Skip to content
kayateia edited this page Jul 14, 2014 · 4 revisions

Overview

Basics -- MUDs, MOOs, Lambda

CliMOO is a MUD Object Oriented (Multi User Dungeon) in the lineage of LambdaMOO. However, it is written from a completely new code base, from scratch. There are several important differences, as well. You might consider that CliMOO is OS/2 to LambdaMOO's Windows 3.x. LambdaMOO is (of course) much more prevalent, more well developed and understood, but in some ways, less advanced. In other ways, simply different.

Unlike legacy MUDs and MOOs, CliMOO is designed from the ground up to have a separate user interface layer. It's still capable of the same basic functions (type text, see results), but it's expected that the user agent will take care of a lot of improvements to the experience. This includes displaying rich text, images, and audio, as well as allowing for better command line editing, and script editing functions. Accordingly, the interface with the server backend itself is quite different than LambdaMOO; it's more of an XMLRPC/HTTPRPC interface. This will become important in discussions of special commands.

Objects

The entire world in CliMOO (or any MOO) is made up of objects. Objects are what they sound like: an item of some kind that can contain other objects, and has attributes describing it, as well as verbs which can be acted upon it. Each object also has a set of permissions that describe who can do what to it.

Many beginning MOO users are surprised at how this works (though not CS people, typically). A room is an object, and players can be contained within it. Objects for players to look at (a painting) or interact with (a sofa with a "sit on" verb) may be in the room as well. Exits from rooms are, themselves, objects which are capable of teleporting a player into another room. The result emulates a conventional MUD's "exits".

Object Names

An object has three names:

  • An object ID. This is in the form "#n", and specifies an absolute reference to an object within the world. Every object is unique, and object numbers are typically not recycled.
  • Path ID. This is a user-friendly name assigned to an object, and is optional. If an object is contained entirely within objects that are strongly named with path IDs, the object may be referred to with a path string. Most system objects are strongly named in this way. E.g. "/templates/room".
  • Descriptive name. This is the value stored in the "name" attribute, and is typically what's shown to users.

When interacting with the game world, users may use any of these to refer to an object.

Scripting

All actions that take place in the CliMOO world are the result of one of two things: a server-side built-in action, or scripting.

Server-side built-in actions are very limited and not very common. They are essentially the atomic building blocks of all other scripting. They include things like the method calls available on world objects within scripting, system functions like checkpointing the database, and so on.

Scripting is typically server-side as well, but it's written in a dynamic scripting language called CliMOO script (or cmscript, or simply mooscript). Cmscript is based on an open source parser/runtime called "Script.NET", which is, itself, an implementation of a scripting language based on C#. So you can think of cmscript as a sort of domain-specific Javascript based on C#.

Since cmscript can be written by any user, it must be locked down pretty heavily. All cmscript runs inside a sandbox that grants (whitelists) permissions rather than denies them. So every action that is performed in a cmscript is checked against a set of allowed actions, and only then allowed to proceed. Each time the script requests to read or write information on an object, it's checked against the object's permissions.

More info about scripting here: Scripter's Guide

CliMOO Commands

Most interaction with CliMOO happens by way of typing commands. There are several major types of commands:

  • Local commands. These are executed on the client itself; the client acts on the user's behalf and speaks to the server's XMLRPC interfaces. These commands are typically prepended by "!". Example: !verb
  • Shortcut commands. These are executed on the server side, but are shortcuts for longer verbs. The quote mark (") expands into "say", which speaks aloud. The colon (:) expands into "emote", which performs an arbitrary action on the user's behalf, to anyone else in listening distance. This makes it quick and easy to do social interactions when in a primarily command mode.
  • Authoring commands. These are also typically prepended by "!". They are an overlapping set with local commands, but some are executed on the server. An example of one of these is !verbs.
  • Scripting commands. These are prepended by ";" and are snippets of cmscript that are executed directly. The implicit subject of these "verbs" is the player. e.g. ;self.desc = "Some new description"
  • World actions. Everything else is considered as a possible world action. World actions interact with other objects in order to cause the world to change.

Local commands are executed by the client, so a given client may have a very different set of commands. For the built in client (the web browser) the following are available:

  • !edit <objId> Allows you to edit a world object. Typically you'll want to specify the object's name or ID, like !edit me.
  • !create Creates a new world object. You can fill in the info in the GUI editor.
  • !upload Lets you upload binary metadata onto an object. This is good for e.g. setting the 'image' attribute.
  • !verb <verbId> <objId> Lets you create or edit a verb on an object. You'll need to specify both the verb and the object. e.g. !verb kiss me lets you edit the verb "kiss" on yourself, which is executed by any user who types "kiss foouser" (assuming that you're foouser).

Server authoring commands are also available:

  • !verbs <objId> Gives a list of all verbs on the object, and a little brief snippet of the verb's code.
  • !attrs <objId> Gives a list of all attributes on the object, and the value if it's displayable.

Attributes

It's not MUD Object Oriented for nothing. Each object can contain an arbitrary set of attributes. Some are standard (e.g. image and desc) but you can attach any attribute you like to an object. Furthermore, these attributes are inherited.

Each object is not only contained within another object, but it has a sort of archetypical parent object. In CS terms, you might think of these as base classes, but they're really not quite the same. They're closed to Javascript prototypes. A class is a prototype of an object, and instances are created from it. CliMOO objects are subclassed directly from each other.

What does this mean in a practical sense? If object B sets object A as its parent, then all of object A's attributes and verbs are available on B by default. These are available as a sort of shadow attribute/verb, in that they aren't truly set on B. But if you attempt to access an attribute on B, and it doesn't exist, A is also checked. In this way, you can say "I'd like to make an object that's just like A, but different". B's local attributes and verbs then define those differences.

These attributes are protected by a set of permissions that specify who can edit them, and whether they can be overridden. For example, a radio object might have a set of attributes that specify what it looks like and what station it is tuned to. A base radio object might have the actual description, and clones of this radio might only be allowed to change what station they're tuned to.

All attributes, unlike LambdaMOO, are accompanied by a MIME type. If it's text, or some type that may easily be converted to/from text (like a C# boolean), you can edit it in the command line. Otherwise, it requires client support for upload/download.

Verbs

Like attributes, verbs are blobs of text attached to an object. They are executable code in the form of cmscript.

There's little remarkable about them all in all, though it will need a whole separate reference to fully describe the language and API. But one thing is worth mentioning: verb forms.

Each verb can define one or more verb forms which describe how the verb can be invoked. Since verbs are used in more or less grammatical English sentences, there must be some determination of what you can do with an object. For example, you might want to put an object into another, or in another. But it wouldn't make much sense to "put foo as bar".

At the top of each verb are signature lines describing the verb forms. They demonstrate to the parser how they may be used, as above. They may also include wildcards in various forms.

Command parsing

When a user types a world command, some complex fuzzy parsing happens to determine what the user intended. The sentence is parsed into the following components:

  • A subject, which is usually the player performing the action.
  • A verb, which is what the player is doing, and of course a matching bit of cmscript describing how to do it.
  • A direct object, in the grammatical sense. On what is the verb being performed?
  • A preposition, e.g. "into", "on top of", etc. Many prepositions are aliased into one simpler concept. (e.g. "on", "on top of", "onto", "upon", "above", "over" are all simplified into "on".)
  • An indirect object, to which the preposition refers.
  • A secondary preposition for a secondary indirect object.
  • A secondary indirect object, to which the secondary preposition refers.

The latter two are an addition for CliMOO over Lambda, and allow for complex formations like "put cat into kennel with key".

Subject is relevant because it may not be the player performing the action. Other objects may also invoke verbs on other objects, including players. E.g. there could be a booth where you press a button, and it kisses you.

The fuzzy logic happens because the verbs are attached to objects; they are not global items. So in the above example, the parser would look for a "put" verb on the "cat" object which contained a signature that allows parsing the line. Failing that, it will search the indirect and secondary indirect objects. All of the object names may also have spaces in them. The earliest match is the one that's used.

Users

A user is an authentication token paired with an in-world object. The in-world object must be parented from the global player template.

Player objects with an attached/logged-in user have a few specific properties that are not present on other objects. For example, text may be written to their console. This area is rather nascent right now.

Periodics (Pulse Verbs)

Objects may register for periodic calls on their verbs. This can be used to e.g. have a logging object periodically flush its contents to some network resource.

This is done using two special attributes: pulsefreq and pulseverb. Set pulseverb to the name of a verb available on the object, and pulsefreq to a number of seconds (currently must be a multiple of 5). After that many seconds, and thereafter in that many seconds, the pulseverb will be called by the system.