[DGD] Delay statements in scripting

Noah Gibbs noah_gibbs at yahoo.com
Sun Jan 4 03:27:20 CET 2004


  This is a problem I've been thinking about for
awhile, and stuff I've seen recently has made me more
interested in fixing it.  Since the problem is
specific to some of the implementation choices made by
the DGD server, I'm going to try this list.  Feel free
to call "off topic" if this seems to be.

  Scripts in MUDs tend to be simple little things that
rooms, objects and mobiles do.  They tend to be
essentially a set of actions, in order, with the
occasional conditional or loop.  They are, in other
words, usually pretty simple.  They also tend to be
the sort of thing that somebody would type at a
command line since they tend to primarily specify
actions for a mobile to take, or sensory input for
people to see/hear/etc.

  There's one different very simple and fundamental
action that scripts want to take, and it's harder to
implement:  delays.  When you want a mobile to look at
what it's been given, wait a few seconds and give it
back disdainfully, it's important to wait that few
seconds.  The problem is that DGD is single-threaded,
which means that threads of execution need to finish
*fast* so that the rest of the MUD can get on with
what it's doing.  A three-second delay loop isn't an
option, and would halt the rest of the MUD, spoiling
the effect.  It doesn't work.

  Note to Skotos guys:  I know you've solved this
problem, and from your documentation I'm even pretty
sure how.  However, I'm under NDA so I can't use your
solution.  Since I'm giving my MUDLib code away, you
probably wouldn't want me to.

  One way to do this is to schedule call_outs, or do
something roughly similar.  That's a bit ugly because
you need to split your function into pieces --
"give_script_start", "give_script_after_delay_1",
"give_script_after_delay_2", etc.  However, once you
get over the syntactic ugliness it's not too bad.  It
does what you want it to.

  Another way is to have a very simple script that
queues up actions in your mobiles.  In other words,
you'd just give it the equivalent of a bunch of lines
of typed input.  Unfortunately, to add loops and
conditionals and things to this, you'd need to add
another programming language on top of your parser. 
So you could do this, but you'd be implementing
state-switches and multithreading in a pretty ugly
way.  Not great.

  A variant on that choice is to queue up actions in
advance, but run LPC code to do it.  So you'd have
function like mobile_do_run(), mobile_do_sharpen(),
etc that would queue up that action to be done when
the current action is finished.  So you'd make up a
set script of actions, but you'd get conditionals and
scripting at the very beginning, when you chose what
actions.  Unfortunately, that means that all control
structures must be done in the very beginning, and
must be done (effectively) before any of the delays
happen.  That's not great.  It means that mobiles will
get stupider as the script goes on longer, and if they
need to enter a room and then respond to it, you're
reduced to call_out statements again.

  A third possibility is to run the script again after
each delay, and pass some kind of argument to it to
tell it where it came back.  So you'd make your whole
function a big switch() statement and then jump to
where you were after the delay.  A delay would become
a return statement, along with how long you should
delay, and then you'd get called again with an
argument for how long you've delayed or something. 
That'd be wacky, and your builders would hate you and
want to kill you, but it would work.

  All these solutions are pretty gross.  I know of one
or two variants on the above, which are also pretty
gross.  Anybody know a good way to deal with this? 
What I'd really like would be a way to write LPC code
and have some kind of "delay" statement that worked
transparently.  Failing that, anything that allowed
builders to write simple scripts for simple actions
would be great.

  I assume I'm not the only person who's had this
problem, but most Diku-type MUDs solve it with an
awful internal scripting language based on the format
for player commands (i.e. "if is_player($target1) then
kill $target1").  That's mostly like the "implement a
language for it" solution above, and ignores all the
advantages of having LPC built into the server in the
first place.

  Anybody know a good way to handle this?


=====
------
noah_gibbs at yahoo.com

__________________________________
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree
_________________________________________________________________
List config page:  http://list.imaginary.com/mailman/listinfo/dgd



More information about the DGD mailing list