From: goetz@acsu.buffalo.edu (Phil Goetz)
Newsgroups: rec.arts.int-fiction
Subject: World simulation (was Re: object-oriented adventure games)
Date: 6 Nov 92 03:55:46 GMT
Organization: State University of New York at Buffalo/Comp Sci

TWO OBSERVATIONS ON WORLD SIMULATION

A. Ontology:  Objects vs. Objects + Locations + People + ...

In Jurgen Appelo's recent post (appelo@dutiag.twi.tudelft.nl), he said:
>6. I believe many game makers make the mistake of dividing the world in
>characters, objects and area's. This could make several situations
>almost impossible, like carrying dwarfs (a character could only carry
>objects), putting them in a box (an object could only hold other
>objects) or entering a new world that's inside a suitcase (area's hold
>objects, not vice versa). Everything should be possible. After all,
>that's what many adventure games are all about.

Similarly, in a letter from Erik Francis (max@west.darkside.com):
>GOOGOL is heavily object-oriented.  In fact, there is no distinction 
>between an "item," "creature," or "room" -- they're all generalized 
>objects, called _symbols_.  The one and only property that symbols have 
>is that they can point to one other symbol.  This can be interpreted (and 
>is in the standard implementation) as the first symbol being _inside_ the 
>second one.  For instance, if I pick up a pen, then the pen-symbol is 
>pointing to my symbol.

I think that object-oriented code is the way to go for adventures, and I agree
wholeheartedly with making every location, object, player, non-player, etc.,
the same type of object.  I would even claim that the game manager should
respond to non-player actions the same way as to player actions, except for
printing to the screen.  (Jurgen also mentioned this.) This forbids you from
having the nonplayers do impossible things for the sake of the plot, but you
can generally stick in any such "impossible action" side-effects elsewhere.

I'd like to point additional reasons why you don't want to
distinguish between objects and locations, etc.  In my adventure, objects
can have the property of being transparent and/or openable.  Glass bottles,
for instance, are both.  If the player is outside a transparent or open object
looking in, he can see inside.  If the object is open, he can reach inside.
This takes place regardless of whether the object is used in the game as an
object (glass bottle) or a location (locked car with windows which you can
eventually drive away).  Vehicles in general are MUCH easier when objects can
be locations.

You don't want to write the reach-accessibility or sight-accessibility routines
twice, once for objects and once for locations.  For one thing, they are
necessarily recursive (A is reachable if A is in B and B is reachable).

Deciding whether the player's location is light or dark is a bit tricky.
If the player is inside object A, the object is treated as his location,
and when the game prints the display of what he can see, it checks to see if
there is light in location A.  If not, it first checks for a light source
(i.e. a lamp) in A, then checks to see if A inherits light from the object B
that it is in.  This occurs if A is open or transparent, and B is light, i.e.

	light(A) if
		lit(A)	(e.g. a field)
	    or	there exists C in A such that lit(C)	(e.g. a lamp)
	    or	{[open(A) or transparent(A)] and in(A,B) and light(B)}

(Yes, it's recursive.)  Because this routine works on objects and not just
locations, it provides you with much greater versatility.  For instance, your
player can drink the potion labelled "drink me" and run around in objects that
have not been defined as locations (e.g. glass bottles) with logical effects,
these new "locations" being permitted simply by virtue of the fact that the
now smaller player can fit into them.  Furthermore, if you have undeveloped
film in a camera, you can have a demon attached to the film which asks at each
turn, "Am I in a lit container?", without writing separate light-inheritance
routines for objects.

B. Command Handlers (Verbs)

The Alan language has a nice feature:  each verb can be defined globally,
in a location, or for an object.  When the verb is used, the conditions
required (& side-effects) are checked first for the global definition,
then for the location, then the specific object.

I'm just throwing that out as something neat, because I really want to talk
about consistency maintainers.  (I'd like to come up with a snappy name,
but...)  Most adventures take the approach of writing a bunch of different
verbs, and letting each verb do as it pleases.

Much better, in my opinion, is to have a small set of primitive relations,
and a small set of ways of modifying them.  In my adventure, all data was
represented in a semantic network, where nodes represent objects and links,
relations.  So the link (ball in box) means the ball is in the box;
(ball on table) means the ball is on the table.  (An interesting problem -
because of the bidirectional nature of my network links, my program could
not distinguish between "The key is under the rug" and "The rug is on the
key", with the result that if you typed PUT KEY UNDER RUG it would say
"There isn't room!", meaning there isn't room for the rug on the key.
I don't know of a good solution.)

The key point is that, any time something changes the network, it has to
send a request to make a specific change to the network (add a link,
remove a link, "change" a link (i.e. (ball in X) => (ball in box)).
A very small set of complicated routines would check that this change
was allowable, and implement all side-effects.  For instance, if the camera
is on the notebook and the flashbulb is part of the camera, and you carry
the notebook into the next room, the movement verb sends a request to
accomplish (player in roomB).  The consistency-maintainer must first
check that there is room in the next room for yourself, the notebook, the
camera, and the flashbulb; if there is, all these items must be relocated
into the next room without affecting their relationships to each.  Maintaining
consistency just for "in" and "on" turns out to be tricky, and I think the
reason most adventures don't allow more relations than "in" is because they
don't use this method, but must have each verb maintain consistency
independently, and the complexity of doing this for more than just "in" is
prohibitive.

Phil
goetz@cs.buffalo.edu