[MUD-Dev] Room-based vs. coordinate-based

clawrenc at cup.hp.com clawrenc at cup.hp.com
Mon Jun 30 16:29:04 CEST 1997


In <33AEA9CD.41C67EA6 at iname.com>, on 06/23/97 
   at 11:09 AM, Shawn Halpenny <malachai at iname.com> said:

>Alex Oren wrote:
>> 
>> Which brings me back to the topic.
>> 
>> How would I implement the equivalent of room-spoofs in a
>> coordinate-based setting?

>You would spoof a room-object by cloning the existing room and
>modifying the desired methods on that object to implement whatever
>new functionality.  All references to the old room should map to the
>new room until the spoofing is terminated (see aside below).

You are changing the original (my) definition of a spoof.  I don't
mind, but unless we provide a distinction this is going to get
confusing.  In my model of a spoof the room is not cloned.  As
diagrammed many times before:

  Note: All references to "Object#" below are refering to the object
  in the DB whose ObjectID is "Object#".

  ObjectA exists.
  ObjectB spoofs ObjectA.
    ObjectA is cloned (exact copy) to ObjectX.
    The contents the original ObjectA are replaced entire with the
      contents of the the spoof object.

Removal of a spoof does the same thing backwards:

  ObjectC is copied on top of ObjectB.
  ObjectC is deleted.

What you appear to be missing (od adding) here is the concept of the
generic method.  The important aspect of a spoof and its accompnying
generic method is that it allows the original object, now cloned off
to ObjectC above, to continue to be affected by the outside world. 
Thus if a tree is spoofed, then someone carves their name on its
truck, and then the spoof is removed, the tree will still have the
carvings...

Very simply a generic method will match any and every incoming method
call which is not more directly matched by another existant method on
the object.  Where the power comes in is that a spoof object is able
to use this to intercept certain method calls to an object, and to
allow others thru to the orignal object unaffected.  

Internally, the spoof may have a number of methods defined, and the
general method.  The result is that any other object sending a message
to what it thinks is the original ObjectA, instead is sending a
message to the spoof. The spoof can then intercept that message with
one of its own locally defined methods, or it can pass the message on
(possibly edited) to the original object via the general method.

In a way the spoof acts as an intelligent filter between the original
object and the rest of the world.  Considerable intelligence can be
built into a spoof.  The result is that the entire behaviour and
appearance of an object, even its API can be changed, all without
changing the source to the original object at all.

A spoof is just a normal MUD object.  The only specific difference
between a spoof and other objects is that a spoof is used to *replace*
a normal MUD object, relegating the original object to a backup copy. 
This leaves the rest of the system in ignorance -- it has no reason to
think that anything happened.  Thus message calls from other objects,
intended for the spoofed object, now arrive at the spoof, and the
spoof does with them whatever it wants (including passing the message
straight back to the hidden original object).

Diagrammed:

  ObjectA exists.
  ObjectA is spoofed.
    ObjectA is cloned to ObjectB.
    The contents of ObjectA are replaced with the spoof.
  ObjectX now calls ObjectA.get()
    Note that ObjectA is now the spoof.
    ObjectA does not have a method called "get()" defined.
    The general method on the spoof matches get(), and calls
      ObjectB.get()
      ObjectB is of course the original object, just with a
        different objectID now.
      ObjectB.get() is called and does whatever.

Or, to show the spoofing in action:

  ObjectA exists.
  ObjectA is spoofed.
    ObjectA is cloned to ObjectB.
    The contents of ObjectA are replaced with the spoof.
  ObjectX now calls ObjectA.get()
    Note that ObjectA is now the spoof.
    ObjectA __does__ have a method called "get()" defined.
    ObjectA.get() is called instead of any get() method on the
      original ObjectB.
      ObjectB is of course the original object, just with a
        different objectID now.
    ObjectA.get() does whatever.

Example:

  The DemonWroth watches all character objects (players) that have
ever been in the same room as the PrincessBride, until those objects
have been in the same room as the Great God GooGoo.

One solution is to have the DW spoof the containment methods on the PB
so that every time the PB enters a room a spoof is set on the room
(and removed from the room she left).  The spoof overlays the
containment methods on the room so that it in turn installs monitors
on any objects that enter the room, _and_ spoofs the object to overlay
_its_ containment methods to check for the presence of the GGGG when
ever it enters a room (and remove the monitor and the spoof if it
does).

Diagrammed:

  DemonWroth installs spoof on PrincessBride
    Spoof(PrincessBride) adds features to
      PrincessBride.I_am_contained_by
      and PrincessBride.I_am_leaving_container.
      Spoof(PrincessBride).I_am_contained_by spoofs the room the
        PrincessBride is entering.
      Spoof(PrincessBride).I_am_leaving_container removes the same
        spoof from the old location.
        Spoof(room) adds features to the room.contain_objects.
          Spoof(Room).contain_objects installs monitors on any objects
            which enter the room (call it "thing").
            Monitor(thing) reports back to the DemonWroth.
          Spoof(Room).contain_objects spoofs the object (thing) that
            just entered the room, adding features to
            thing.I_am_contained_by.
            Spoof(thing).I_am_contained_by checks every room the thing
              enters to see if the GGG is there, and if so removes
              itself (the spoof), and the monitor that reports back 
              to the DemonWroth

Starting to get the idea?

The whole idea of a spoof is that its transparent.  The original
object continues to be affected by the rest of the world, __AND__ the
rest of the world has no idea that anything has happened.  Its
transparent.

>An aside--given:
>Room R at time t=0.
>An earthquake is scheduled to occur in R at t+5.
>Room R is spoofed at t+2, creating R' which now exists in lieu of R.
>Time t+5 arrives, the earthquake occurs.  Are the effects of the
>  earthquake applied to R, R', or both?  Generalized:  are any
>  actions occuring on R to be duplicated on R' and vice versa?
>  
>Note:  the spoofing of R and the earthquake are independent events
>and are completely unrelated in cause, execution, and effect.

Given the above spoofing method this is not a concern.  The earthquake
event is sent to R' just as if it were the real room, which to the
rest of the world, it is.  The R' spoof then passes on all the calls
to the real room at R.  It then makes all the requisite changes,
passes the return codes back to R' which in turn passes them back to
the event.  

It all happens automatically without any special casing and without
there ever having to be two rooms, or having to track which room an
event gets delivered to.  There is only ever one room, with a possibly
large number of spoofs.  

Note: In a couple real-game type test cases here I've had rooms
overlaid by over 50 spoofs.  I don't think that sort of condition is
going to be even slightly uncommon in practice -- I suspect I'll
commonly see objects with over 100 spoofs attached -- which hs caused
me to log "Optimise spoof support" on the list here.  With your room
copying model that many spoofs gets expensive.

--
J C Lawrence                           Internet: claw at null.net
(Contractor)                           Internet: coder at ibm.net
---------------(*)               Internet: clawrenc at cup.hp.com
...Honorary Member Clan McFUD -- Teamer's Avenging Monolith...




More information about the mud-dev-archive mailing list