Objects
=======
The world of COOL is made entirely of objects. The COOL server is the
"engine" that simply manipulates the objects. The server enforces
almost no rules about the behaviour of objects or how they can
interact.
For the sake of example, we'll use a simple world that has just a few
base objects: the Player, Rooms, Things (e.g., things that you can
pick up), and Exits.
Exits are used to connect rooms. Exits are one-way, so you typically
have two Exits connecting two rooms; one Exit for one direction and
another for the other direction.
The Room and Exit objects are "locationless;" although they are
objects, since everything is an object in COOL, as far as location
goes, they don't have a location and more or less float in limbo.
Variables
=========
Objects have variables or properties. I'll try to stick with the term
variable but I may use the term property; they both mean the same
thing. Examples of object variables are the description of the
object, its name, and so forth.
Methods
=======
Objects can also have code bound to them. This code is called COOL
and it looks similar to C. It has the usual flow control statements
(if, else, for, and while). The code on an object is typically split
into several subroutines, called methods, for doing a variety of
different things. A method can call another method on the object;
thus methods can be used as subroutines in the usual programming
sense. The more interesting use of methods is to bind them to a verb;
verbs are how the player interacts with objects. For example, a watch
object might have a "wind" verb, which is bound to the "wind_cmd"
method, so when the player does "wind watch" the wind method might
print the message, "You wind the watch and it starts ticking." But
actually, a verb isn't bound to a method, what really happens is you
specify that if the player types some command, this object should
invoke a particular method in response to that. For example, the
player object could have an "inventory" command; here's how you'd set
it up:
verb "inv*entory" = inventory_cmd;
The asterisk means that the characters after it are optional; the
player can shorten the command to just "inv". So when the player
types "inv", the COOL code in the method inventory_cmd is run.
In what follows, when I say things like "the inventory verb is
called;" what I mean is that the method bound to the inventory command
is called.
How verbs are called
====================
Next, let's go over how the verbs' methods are called. The COOL
server parses and splits up the command that the player types, so that
it has a list of words, which the player typed. So if the player
types "hit nail" the parser makes a list, of 2 words. It then checks
various objects to see if any of them has a verb/method binding for
"hit;" I'm not sure of the exact order of checking, but I think it
first checks the verbs on the player, then the verbs on any objects
the player is carrying, then verbs on the room the player is in, and
then finally verbs on objects in the room. If there is an object that
has a "hit" verb, its method gets called, with the list of words that
the user typed as its arguments, and the method checks to see if it's
for itself; i.e., is the 2nd word that object? For example, there
could also be a punching bag in the room that has a "hit" verb. If
the method determines that it's the right object then it does whatever
it should do, and when it finishes it returns the value 0 to the
server to signal that it was the right object. If the punching bag's
"hit" verb method had been called first, it would return 1 to signify
that it wasn't the right object and the server will continue calling
the hit verb methods on other objects.
The obvious upshot of this is that it's the objects that define the
vocabulary.
Inheritance
===========
Another interesting aspect of COOL is that it's truly an object
oriented system. COOL has what's called inheritance; an object
inherits variables and methods from its parent objects. It also has
multiple inheritance; an object can have more than one parent.
In our simple example, the objects were Player, Rooms, Exits, and
Things. In reality we'd most likely have some generic Base object
which these other objects were decendents of. And it probably
wouldn't even be that simple; the Player and Thing objects will always
have a location, so they'd probably be decendents of a generic Located
object, and the Located object's parent would be the Base object. The
Room and Player object can also contain things (the Player contains
whatever it's carrying) so they might also be children of a generic
Container object.
So how does this inheritance work? The generic Room object would
probably have a name variable that contains the name of the room, and
a description variable that contains the description of the room, and
a contents variable that's a list of objects in the room. It would
probably also have a "look" verb bound to a method which when invoked
prints the name of the room, the room's description, and the contents
of the room. When you're building your world in COOL, to make a new
room, you'd clone the generic Room. You wouldn't need to define a
look verb for your room; if the player issues a simple "look" command
in your room, the COOL server would use the look verb on the generic
Room. But your room would have it's own name, description, and
contents variables, and the generic Room's look verb would use those
variables, not the ones of the generic Room. If you wanted to, you
could make one room behave differently; you could add a look verb to
it and program it to do something different. The COOL server would
see that that room has its own look verb and use it instead of the
generic Room's look verb.
Some example ideas
==================
Here are some simple examples of things that are easy to do with COOL.
There are string manipulation primitives in the COOL language, so you
could have an object variable that specifies the gender of an object;
e.g., an NPC. You might have several of these NPCs, some male, some
female. They'll probably share a lot of common code (via inheritance
from their parent), and some of this code would emit messages when the
NPC does something; for example if it scratches its head, you'd see
the message "Xyz scratches her head." But for the male NPC you wan't
it to print "Abc scratches his head." So you could replace the
his/her with some special sequence that should be replaced with the
appropriate possessive pronoun: "Lmn scratches %p head."
Of course it would be trivial to have an a variable on exits that
specifies if the exit is open or closed. An exit can have a
description, just like anything else can. When you open or close the
exit, it could change the description; when it's closed, when you look
at the exit it might print something like "A sturdy oak door." and
when it's open you'd see something like "A sturdy oak door, wide
open." Since the exit "knows" the room it leads to, it can access
that room's variables and you could have the exit's description
automatically include something about the room that it leads too; for
example, things that are in the other room.
Thing objects could have a weight and volume. You could set up a
variable on the player specifying that it can carry only so much
weight. A container object could have a variable for its internal
size, which would limit how many or how big of an object it could
contain.
An object knows its location; i.e., what object contains it. This
means that the Container object can act as a "conduit" for things in
it. For example, you could have a cage object with, say, a bird in
it, and whenever the bird sings, you hear it. You can also use this
to make vehicles. A vehicle is simply an object that allows the
player to enter it, and it typically has some way to allow the player
to look out; the vehicle passes the description of the room it's in to
the player inside. Information can move in both directions.
You can get the source code for COOL by doing an anonymous ftp to
ferkel.ucsb.edu, cd to the directory /pub/mud/CoolMUD, set binary
mode, and get the file coolmud2.1.2.tar.Z. There is also some
documentaton for it there, but it's not up-to-date and needs more
work.