adonthell-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Adonthell-devel] Schedules


From: Kai Sterker
Subject: [Adonthell-devel] Schedules
Date: Tue, 30 Apr 2002 11:45:06 +0200

Well, this gonna be a long mail, I know it. You should still read it
though ;).

Now that the dialogue rewrite is complete, the windows port comes along
nicely, it's time for me to move on to new things. I have some ideas
about a much improved character schedule system (and character schedules
in general) I'd like to share with you.

As you can see from Waste's Edge, a single schedule for each character
allows it to walk around, but everything it does is very predictible and
quite limited. Another problem is that the schedules are not modular at
all. Often, schedules contain completely different things (Erek's has
code to walk between parlour and common room, to go to and return from
both Bjarn and Jelom) and this makes it extremely difficult to write
modular schedules.

The ideal solution would be schedules that only concentrate on one
thing. This thing might be more complex than any schedule we've written
so far, but at the same time generic enough that practically every NPC
can be given this schedule.

This means of course that a lot of information the schedule needs must
come from outside. Basically there are three ways to pass additional
information to a schedule: 
1  via parameters at construction time 
2  through quest flags or character attributes
3  calculated at runtime

With the current system, the first isn't much different from the second,
as the schedule is created by C++ code in the character class. So any
parameters given could well be read in at runtime as well.


Another thing that currently prevents us from using highly specialised,
yet generic schedules is that such schedules need to be switched very
often. But a generic schedule can't contain rules to find a new
schedule, as these are special for every character.

So the idea is to have a schedule manager. This has basically 4
attributes: Two booleans, 'active' and 'running' that determine whether
the schedule is on hold or not, and whether there is a schedule at all.
Apart from those there is the actual schedule and a 'manager
schedule'.

And like that it works:
The manager schedule is special for each character. It basically
describes what he does during the day or on special events. It might get
pretty big and CPU consuming, but as it only runs occasionally that
shouldn't matter. Task of the manager schedule is to set a new character
schedule whenever the character has none. (So all a generic schedule
needs to do at the end is setting 'active' to false. The next iteration,
the schedule manager spots this and can run the manager schedule to set
the actual schedule, depending on such things as time of the day,
location or quest flags.

Of course that's not the only way to switch schedules. This may also be
triggered from events or dialogues or even from certain character
schedules themselves.

As an addition, the schedule manager might contain a counter that can be
set, and when it reaches zero it'll run the manager schedule without any
further action from outside.

And, as you might imagine, the manager schedule itself can be changed as
well :)


The cool thing about each character's individual manager schedule is
that it is a very conveniant way to pass parameters to the actual
character schedules. These parameters need not be stored anywhere on C++
side (whith all the overhead of loading or saving or creating them in
the first place). They are simply part of the manager schedule and can
be easily edited.

I imagine the the actual schedules are highly parametrised (otherwise,
how can they be so generic?), so the manager schedule will be a great
ease for passing them all the parameters they need.


The ultimate goal is to
* give each character a very individual life. That means, their day is
  divided into a number of actions (-> different schedule for each
  action), with special actions for special days (market day, certain 
  game events), etc. 

  So unlike Waste's Edge, which still looks rather sterile, the game 
  world should be alive and full of people going about their daily 
  live even without interaction of the player.

* let characters react to goings-on in their neighbourhood. If a fight
  breaks out for example, some might attack others might escape and call
  for help. That in turn might attract other NPC's or scare them away, 
  so that suddenly a crowd gathers, or guards appear or whatever.

  As a lot of factors decide how a certain event propagates, the 
  outcome might be different each time, and that really gives the
  impression of 'intelligent' behaviour and a living world.


So much for the schedule manager. Now a few more words on modularity:

Even our highly specialized, generic schedules are not generic enough.
There are tasks that are part of many different schedules, like locating
and picking up a certain item. Activities like those can be put into
helper modules that are used by the schedules then. CPU intensive code
could even by implemented on C++ side for efficiency.


And finally, here is a little example that came to my mind:

Imagine a smith at work. For his next task he needs to pick up a hammer,
so the script would call the locate_and_pickup ("HAMMER", <map>,
<submap>, ...) subroutine. Now imagine the hammer is either outside the
scope of this routine or not there at all. So it returns false. 

The next step would be to switch to a search ("HAMMER", <location> ...)
script, that implements some kind of search strategy. This script would
internally make use of the locate_and_pickup function, and at some point
it would abort with either true or false.

Let it return false, which means the hammer is gone. Now we could launch
a shop_for ("HAMMER", ...) script instead. Thius requires some
additional work of course. To work for the smith in Waste's Edge as well
as for that in Cirdanth, there needs to be a way to figure out where to
buy certain things. We can probably make some sort of 'database' for
this purpose that can be queried by the script.

Anyway, let assume the smith figured out where to go. He arrives at the
shop, buys a new hammer and with that the shop_for script terminates.
Now the manager schedule runs and detects that our smith isn't at his
work although it is still day, so it will set a schedule that'll bring
him back to the smithy. This will terminate once he arrives and the
manager will set the normal work schedule. And this time, our smith has
his hammer :).


As you probably noticed, all those scripts where highly generic. You
could as well call shop_for ("ALE" ...) or locate_and_pickup ("PLATE
MAIL"). Latter would of course call search ("PLATE MAIL").


We could probably create a small economy that way: peasants could bring
fruits and stuff to the market, or grain to the miller. The Dwarves
mining ore, refinning and smithing stuff, and finally bringing it to
town. And so on and on and on ...

Writing those interacting schedules probably takes a while, but a lot of
them will contain mainly the same things: pick that up here and deliver
it there. With a way to let NPC's determine where they should go for
what, this won't be too difficult.


So, if there are no objections (or better ideas), I'll concentrate on
that part from now on.

Kai

P.S. I also think I've found a way to make the current schedule much
more efficient, but I'll write a seperate mail for that :).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]