From: alcaman@opal.cs.tu-berlin.de (Alexander Weidt)
Subject: Re: 3.01.02 Problem
Keywords: move_object(), init(), add_action()
Organization: Techn. University of Berlin, Germany
Date: Thu, 16 Apr 1992 19:46:08 GMT

tschille@descartes.waterloo.edu (Mordin) writes:

>We are running version 3.01.02 of the parser and I've run into a bit of
>a prob. Seems that I can readily add verbs via add_action(), but they
>tend to stick around until a player logs out.
>
>Is this a problem with the parser or is there a different reason for it?

Hi..
  I would definitely say that this is a problem with the parser... :-/
However, I have never experienced this problem on a (relatively) vanilla
LPmud driver regardless of the version.

  The routine move_object() in simulate.c seems carefully programmed, and
even after studying it all day, couldn't find any bugs in it.  It would be
very helpful if you could perhaps give additional details concerning your
specific driver configuration, and details of any modifications done to it.

  Given this chance, I shall take the opportunity to explain the move_object
mechanism and how it is implemented in the driver, in the hope that it
will be of interest to LPC novices.

  When the stackmachine comes across a F_MOVE_OBJECT instruction, after
having obtained object pointers for the destination, it calls the move_object
routine in simulate.c.  The main function of this routine is to transfer an
object to a different environment, hereby making sure that the sentences,
making up the command definitions are updated correctly. (Sentences are
structures that contain the player's commands, which associate a command
string, with an object and function.)  There are also differences in the
execution of a F_MOVE_OBJECT instruction depending on if the driver has been
compiled with COMPAT_MODE defined or not, I shall explain what happens in the
non-compat mode.

The first part involves performing some checks to see if it legal to move
the object in the first place; if the object to be moved 'item' is the
current_object, if the object has been "approved" and if the object is
shadowing another object.  The next step is to update the light level in
the object's new environment.

If the item has an environment (not true if it has been freshly loaded or
cloned), we need to remove its sentences that have been defined by its
environment, or objects in its environment, not forgetting those that exist
in objects in its environment defined by the item itself.  We start by
checking to see if the object has had commands enabled (that is able to
perform commands, and thereby having a list of command sentences).  If this
is so, then we remove all sentences defined by item in its environment.
Depending of whether item's environment has commands enabled, the sentences
defined in the environment, by item need to be removed too.  The next step
is to scan through the objects in item's environment, removing sentences
defined by these objects from their and our sentence lists.

The next part actually "moves" the item into its new environment by adjusting
the object's and destination's next_inventory and environment pointers

The last part of the move requires the local function "init()" to be called
in various objects.  (The init function is mainly used to set up commands).
This is rather tricky, and I have found that novices tend to get cofnused as
to when exactly init gets called in their object, and with which object as
"this_player()".  Naturally the order in which init gets called in the
objects is important as command overlaying is a valuable feature.

Demos draws a deep breath.

Init is called in objects according to the following scheme:
If an object 'item', with commands enabled is moved to a destination 'dest'
then all objects in dest's inventory will have init called.  In addition,
regardless of whether an object has commands enabled, its own init function
will be called once for each living object in its new environment, including
the environment itself, should it be living.
Phew.. ;)

Furthermore, during these calls, the value of the command_giver is set to the
living object for which it is called.  (The value of command_giver is
obtained by a call to efun::this_player().)

Read "object with commands enabled" for "living object" in the above.

Things in the COMPAT_MODE run similarly.  The main differences being that
it is legal for an object to move another object and that the local function
"exit()" is called in the object's environment. 

In the code, Lars notes that it would be cleaner for the object being moved
to make the init calls itself, has anyone modified their driver and made any
observations as to the performance loss?  With the help of the apply_low
function cache the performance degradation might still be bearable.

Happy hacking, Demos.
--
Do not meddle in the affairs of game driver, for it is subtle and quick to
anger.
Newsgroups: rec.games.mud.lp