[MUD-Dev] TECH DGN: Re: a few mud server design questions (long)
jandrieu at caltech.edu
Thu Jul 26 11:49:54 New Zealand Standard Time 2001
Robert Zubek writes:
> Joe Andrieu writes:
>> As long as objects are persistent and there is a periodic time
>> event, it is fairly straightforward to instantiate an object to
>> handle longer term events.
> hmm, that's a very good point. i didn't even realize it at the
> moment, but the event handler i was modelling didn't support
> periodic time events at all, which was probably at the source of
> my difficulty.
> do i understand correctly that what you describe is a kind of a
> multitasking approach? one in which the control loop looks like
> for each time tick
> for each living entity
> call the entity's 'time tick' handler
> and the tick handler takes care of all the relevant events that
> got queued up in the meantime.
Actually, I'm not sure "tick" should be the only top-level signal
propagating down the cascade. On the other hand, events which are
processed outside the tick propagation are essentailly occuring
outside the time field of the implicit simulation.
There are two areas you probably want to think about when
considering what is contained in the simulation and what is executed
independent of its time-loop.
First, there are some cases where ticks are a really bad way to do
things. Notably when the actually processing requirements for an
event are either much longer or much shorter than the expected tick
duration. For example, you would not want to initiate a (blocking)
disk formatting process during a tick. As Sean Kelley points out in
his reply, you probably want to make sure the actions in any given
tick get done in a relatively short period. In fact, by catching
when tick events exceed this bound, you can also make the world safe
for accidental infinite loops. Similarly events which need an
immediate response, e.g., refreshing the screen or managing the
network interface, must be managed so quickly as to render the tick
immaterial. I through about that after sending my first note.
Which leads to the following question:
Are you separating your system into a "Driver" and "Mudlib"? This
is the classic LPMud architecture where the driver manages all the
memory management, networking, message passing, etc., and provides a
scripting language and "sandbox" simulation space to execute the
code comprising the MudLib. It seems to me that what you are aiming
for is to implement 100% in LISP. Is that right? Does that mean you
also have to write the networking code in LISP? If so, then you
probably want to make sure you don't get the network handling caught
up in your simulation event handler. With a clean break we can now
assume that we are processing events only "within the simulation"
and anything else is handled by code that's "closer to the metal".
Second, I'm assuming you are just going to use CLOS to manage the
object-oriented side of this puzzle. Of course, you could code your
own object implementation and method calling system, but that
doesn't quite sound like your goal in this application. With this
assumption, we can assume that any cascade of method calls triggered
by a Tick happen effectively in unit time, e.g., simultaneously.
Given that, you can also look into whether or not you want to enable
rollback should inconsistent events occur during the tick. A
non-trivial task, but one that has its merits (although I don't know
if anyone has done it at the granularity of a tick.)
> compared to this, my original design had the entities be more like
> static collections of stats and function pointers, manipulated by
> a general event dispatcher, eg.:
> for each event in the queue
> process event (using all involved entities)
> in this latter model, there is no concept of an independent time -
> events are one-shots, and if nothing is happening an object won't
> even notice the passing of time.
Correct. There would be no concept of time. Which can be disturbing
if the user is expecting time to occur. Does nothing happen (in the
simulation) when nothing happens (to drive the simulation
externally)? If nobody is in your forest, can one of your trees
In addition to assuring a steady march of temporal progress, a tick
mechanism allows objects to be encoded with a common time scale.
Most systems I know, the "tick" is essentially a heartbeat, and
designers can use that to code time-related events along a common
axis. For example, the poison spell. Or movement. Or picking a
lock. The universe needs to manage each appropriately and Ticks
give the designers/coders a straightforward way to define the
duration of something.
> but it could mean that in this model, without a separate clock
> that would poll the objects, objects wouldn't be able to act
> autonomously. (curiously, this didn't cause me any problems with
> npcs, because i figured i'd put those in separate asynchronous
> threads anyway, since they will need to run at a higher frequency
> that the main control loop. :)
Correct! Hence the subclass "Living Objects". All objects can
respond to events, exist in some location, have properties, etc..
Only living objects can act autonomously (by responding to a tick
signal). Also, I would second Sean Kelly's advice about threads.
> hm, i'm going to have to rethink my approach to event handling. i
> wouldn't want each creature's time tick handler to be doing too
> much event processing, but perhaps something like the following
> would be a good combination of event dispatching and asynchronous
> time support:
> for each time slice
> for each of the first n events in the queue (where n is small)
> process event
> for each entity
> call the entity's 'time tick' handler
Hmmm... I'm not sure what this buys you. The most obvious thing it
does is destroy the common basis for timeflow in the simulation. If
coders can't depend on the tick as a unit time, they need to find
another measure. Realtime? The system clock? Count the number of
state transitions? Think of tick as a common currency for the
simulation. Designers can use the Tick for things designed to
consume one time unit.
> in which case the objects' tick handler could be very simple, and
> in most cases simply null.
I concur with Sean Kelly on this one. Only objects which need to be
autonomous should be "living". Which means they probably don't have
a NULL tick handler. Limiting the number of living objects is
preferable to having living objects with NULL tick handlers.
I also like Sean's calendar object. A fine way to manage the master
Tick queue. Although I would again stress that the relevant unit
time is one tick, rather than tie it to any realtime timeslice such
as a day.
I'll suggest an event propagation mechanism in a separate email.
jandrieu at caltech.edu
+1 (626) 395-8045
MUD-Dev mailing list
MUD-Dev at kanga.nu
More information about the MUD-Dev