\documentstyle[11pt]{article} \title{TinyMUD 2.4 Reference Manual\\(preliminary version)} \author{James Aspnes\\ School of Computer Science\\ Carnegie-Mellon University\\ Pittsburgh, PA 15213} \begin{document} \maketitle \section{Introduction} TinyMUD 2 was written as a successor to the original TinyMUD and its many descendants. Its principal features include a specialized programming language designed to grant enough power to produce interesting effects without granting so much power that a programmer can easily damage or shut down the TinyMUD server, an inheritance hierarchy that allows the easy construction of classes of objects which can be used by non-programmers, and an efficient parser that supports (relatively) complex inputs allowing a command to take multiple objects. One of the main goals of TinyMUD 2 has been to eliminate nearly all game-specific code from the server implementation, and move it instead into the database, coded in the built-in programming language. This document describe the built-in programming language and the behavior of the TinyMUD 2 parser. \section{Language} This section describes the features of the programming language available in TinyMUD 2.4. \subsection{Types} The data types supported by the language are: objects, booleans, strings, numbers, actions, sets, and times. All variables except those referring to objects are prefixed with a single-character type specifier, as follows: \begin{tabular}{ll} \verb=x= & object \\ \verb=?x= & boolean \\ \verb=$x= & string \\ \verb=%x= & number (integer) \\ \verb=&x= & action \\ \verb=@x= & set; an unordered collection of objects \\ \verb=~x= & time \\ \end{tabular} Values of type string and type action can be used interchangeably. Values of all types may be used as booleans; they take on the value \verb=?false= if they are null and \verb=?true= otherwise. This feature is primarily useful for detecting ``empty'' variables. Values of type number are automatically coerced to their decimal expansion when used as a string. Most language primitives restrict the types of their arguments; these restrictions will be described with each primitive. \subsection{Constants} All constants of type number consist of a contiguous sequence of decimal digits, e.g. \verb=1=, \verb=5567=, etc. There are only two boolean values, represented by the constants \verb=?true= and \verb=?false=. String constants have a rather complicated syntax. In their simplest form, string constants look much like string constants in many other languages: a sequence of characters delimited by double-quotes, as in \\ \verb="Every good boy deserves favor."=. The set of characters that may appear in side a string constant is severely restricted--- only printing ASCII characters (including space) and the tab character are allowed. By convention the tab character is used to represent newlines within a ``multi-line'' string, as the newline character is reserved for separating inputs to and outputs from the server process. String constants may also appear in the form of ``giant'' strings. These are delimited by matching pairs of square brackets. Other string constants may be nested within a giant string constant. Some examples of giant string constants: \begin{verbatim} [Every good boy deserves favor.] [The sign says "ELVIS NEEDS BOATS"] [set thing.&code to [tell "You lose!" to you]] \end{verbatim} Double-quotes appearing within a simple string constant may be escaped using a backslash, as in \verb="The sign says \"ELVIS NEEDS BOATS\""=, which will print as \verb=The sign says "ELVIS NEEDS BOATS"=. Backslashes and square brackets (in giant strings) may also be escaped using backslashes. The effect of putting a backslash before other characters is unpredictable. \subsubsection{Null constants} Two special constants exist for referring to ``null'' values, which are the default values held by variables of type object, string, or action. These are \verb=nothing= (for objects) and \verb=$null= (for strings and actions.) Null values are used primarily for shadowing inherited variable bindings. The null values of type number and boolean are \verb=0= and \verb=?false=, respectively. It is dangerous to depend on the existence of null values for types time and set. \subsection{Variables} Every object can possess variables of any of the seven types. A variable name by itself refers to a component of \verb=me=. It is possible to refer to variables on other objects using the dot operator, \\ e.g. \verb=location.owner.pet_dog.%number_of_fleas=. Most variable names may contain only letters, digits, and the underscore character; action names may also contain a single occurence of one of the characters \verb=<= or \verb=>=. Object variables may not start with a digit to prevent confusion with numeric constants. It is recommended that non-action variable names beginning with an underscore be avoided except for ``temporary'' variables that are only used within a single action invocation. Variables occuring in a statement return their value. It is possible to set the value of most variables using the \verb=set= statement, e.g.: \begin{verbatim} set dog.%fleas to 5 set location.$description to "Foo" set ?happy to ?true set broken_container.&take>from to [tell "You lose!" to you] \end{verbatim} Variables of type set cannot appear in a set statement (other mechanisms exists for modifying such variables, as described below.) An object can only set variables on objects it controls. Any object may read any variable on any other object. Variables may also be cleared using the clear statement, e.g.: \begin{verbatim} clear dog.%fleas clear location.$description clear ?happy clear broken_container.&take>from clear @tools \end{verbatim} Clearing a variable has the affect of removing it completely from an object, allowing a default value to be inherited from its ancestors. Variables of any type may be cleared. It is necessary to have control of an object to modify any of its variables. However, any object can read any variable. Certain variables have special meaning to the system and thus have additional restrictions on their use: \begin{description} \item{\verb=me=} Holds the object processing an action. May not be set. \item{\verb=you=} Holds the object which initiated an action, i.e. the object corresponding to the user which typed the currently-executing command. May not be set. \item{\verb=next=} Iteration variable inside loops; holds the current object in the set or contents list being iterated over. May not be set, and has no meaning outside of a loop. \item{\verb=$text=} Any unparsed text from the command line. May not be set. \item{\verb=~time=} The current time. \item{\verb=%id=} The unique ID number of an object. ID numbers also exist for strings (e.g. \verb=$name.%id=) and other types. Use of ID numbers is discouraged. \item{\verb=%count=} The number of objects contained in an object's contents set. \verb=%count= may also be used on set variables to count their contents, \\ e.g. \verb=TOP.@connected_players.%count=. \item{\verb=%random=} Returns a different non-negative random number every time it is used. \item{\verb=location=} The location of an object. This may not be set directly, although it is affected by the \verb=move= statement. \item{\verb=owner=} The owner of an object. May only be set by wizard objects. \item{\verb=parent=} The parent of an object, used to control inheritance. It is not permitted to set the parent of an object to one of its descendants. \item{\verb=$aliases=} A string listing the names with which an object may be named on the command line. The aliases are separated by the pipe character, as in \verb="George | george | G"=. Case is significant. \item{\verb=create=} Returns a new object every time it is used. May only be used by wizard objects and may not be set. \end{description} There are also several boolean variables with special meaning to the system: \begin{description} \item{\verb=?player=} This object is a player. May only be set by wizard objects. \item{\verb=?builder=} Reserved for future expansion. May only be set by wizard objects. \item{\verb=?programmer=} Allows use of \@ syntax from the command line. May only be set by wizard objects. \item{\verb=?wizard=} Objects with the \verb=?wizard= bit set have special privileges, including implicit control over all other objects that do not have their \verb=?admin= bit set. The \verb=?wizard= bit may only be set by objects possessing the \verb=?admin= bit. \item{\verb=?admin=} Gives the object the ability to set \verb=?wizard= bits and execute certain system commands. Cannot be set or reset; under normal conditions, only the TOP object will have this bit set on it. \item{\verb=?connected=} Tells whether a player is connected or not. Automatically maintained by the system; can also be set by admin objects. \item{\verb=?paranoid=} If true, any tell sent to this player will be annotated with the id of its source. \item{\verb=?open=} If true, relaxes some of the restrictions on movement. Can be set by any controlling object. \end{description} There are also a large number of action names that have special meaning to the system. As these action names begin with underscores, they cannot be parsed from the command line: \begin{description} \item{\verb=&_default=} Called on the location of the current player if it is impossible to parse the command line; \verb=$text= is set to the entire input. \item{\verb=&_before=} Called on both the location of the current player and on the current player before an action is handled. \item{\verb=&_after=} Called on both the location of the current player and on the current player after an action is handled. If the player moves during the action, it is still the original location which gets the \verb=&_after= action. \item{\verb=&_invoke=} Called on an object if the command line matches one of its aliases. \item{\verb=&_startup=} Called exactly once on every object when the system is started. \item{\verb=&_connect=} Called on a player when the player connects. \item{\verb=&_disconnect=} Called on a player when the player disconnects. \item{\verb=&_tick=} Called when a delay expires. \end{description} \subsubsection{Inheritance} Variables of all types except set are inherited. If the system cannot find a value for a particular variable on an object, it will try instead to use the value of that variable on the object's parent, and will similarly continue to ascend the chain of ancestors until either a value is found or no more ancestors exist. In the latter case, a null value is returned whose meaning depends on the type of the variable. The semantics of inheritance create a distinction between the absence of a variable on an object (which allows ancestors' values to be inherited) and the presence of a variable whose value is null. The \verb=clear= statement always results in the former state; if the latter state is preferred it is necessary to explicitly set the variable to the appropriate null constant. \subsubsection{Set variables} Variables of type set are unusual. Unlike variables of other types, they are not inherited. They also may not be set; instead, two additional statements are provided for manipulating set variables. The add/to statement adds an object to a set, as in \verb=add dog to kennel.@inmates=. Similarly, the take/from statement removes an object from a set, as in \\ \verb=take dog from kennel.@inmates=. The same restrictions are placed on changing a set variable as are placed on changing a variable of any of the other types; the object requesting the change must have control over the object of which the set variable is a component. \subsection{Expressions} The usual simple arithmetic operations on numbers, \verb=+, -, *, /= are supported, with the normal precedence, as is unary minus and the remainder operator \verb=mod= (e.g. \verb=%random mod 3=.) Times may be subtracted to yield a number which counts the seconds between them; a number may also be added to or subtracted from a time to yield a new time, and a time may be taken mod a number to yield a number. This last facility allows times to be displayed in ways other than the default. For example, a clock might contain the following code as part of its look handler: \begin{verbatim} tell (~time mod 43200) / 3600 ":" ~time mod 60 to you \end{verbatim} This will print out the current hour and minute separated by a colon. A full set of comparison operators is available: \verb/< > <= >= = !=/. Following C conventions \verb/!=/ means ``not equals.'' Values of any type except set may be tested for equality or non-equality; other comparison operators may only be used on numbers or times. Supported logical operators are \verb=!= (not), \verb=and=, and \verb=or=. The \verb=and= and \verb=or= operators are guaranteed to evaluate their left argument first and to evaluate their right argument only if necessary. Thus, for example, in the statement: \begin{verbatim} move me to you.location and move you to me \end{verbatim} the second move statement is executed only if the first returns \verb=?true=, i.e. if it succeeds. \subsubsection{Predicates} There are two built-in predicates. \verb=$x matches y= returns \verb=?true= when \verb=$x= is a valid alias for \verb=y=. \verb=@x contains y= returns \verb=?true= when \verb=y= is an element of \verb=@x=. As elsewhere, an object may be substituted for the set, and is then interpreted to mean the object's contents. \subsection{Statements} All statements may also be used in expressions for their boolean value, which indicates whether the statement succeeded or not. In addition to the set, clear, add/from, and take/to statements already described, the following classes of statements are supported: \begin{description} \item{\verb=tell= {\em string-list} \verb=to= {\em object}} Used to send a message to a player. {\em string-list} may contain any number of expressions of type string, action, time, or number, which are formatted according to their type and concatenated to form the resulting method. No special privileges are required to do a tell. \item{\verb=move= {\em object} \verb=to= {\em destination}} Moves an object to a destination (also an object.) Move statements are tightly restricted: the object being moved must be controlled by \verb=me=, in a location controlled by \verb=me=, or be equal to \verb=you=; the destination must be controlled by \verb=me=, have its \verb=?open= bit set, or be equal to \verb=you=. If these conditions are not met the move does not take place and the statement returns \verb=?false=. \item{\verb=delay= {\em time} or \verb=delay= {\em number}} Adds an entry to the system {\em delay queue.} This has the effect of causing the system to deliver a \verb=_tick= method to \verb=me= when either the time has been reached (first form) or the specified number of seconds have elapsed (second form.) An object may have any number of pending delays, but only wizard objects may execute a delay statement inside a \verb=_tick= handler. The delay queue is not saved in checkpoint files and is not preserved across system reboots. \item{\verb=destroy= {\em object}} Destroys an object, clearing all of its variables (including system variables) and removing it from its location. References to destroyed objects are {\em not} removed; however, once an object has been destroyed it can not be modified or moved. \end{description} \subsection{Control structures} The language supports two main control structures, if/then statements and bounded loops over the contents of a set. The if/then statment has the following general form: \begin{center} \em \verb=if= expr \verb=then= statements [\verb=elseif= expr \verb=then= statements]$\ast$ [\verb=else= statements] \verb=endif= \end{center} where the asterisk indicates that any number of elseif clauses may appear, the else clause is optional, and each block of statements can contain any number of individual statements. Here's an example of an if/then statement that one might actually find in a program: \begin{verbatim} if ?locked then tell "The door appears to be locked." to you elseif move you to other_side then tell "You go through the door." to you else tell "The door is stuck." to you endif \end{verbatim} Note that the \verb=endif= is not optional! The other control structure is the loop, which is written as follows: \begin{center} \em \verb=in= set [\verb=matching= string] \verb=do= statements \verb=end= \end{center} Without the optional \verb=matching= clause, executes the statements once for each object in the set with \verb=next= set to the current object. With the \verb=matching= clause, executes the statements only for objects matching the specified string. While this second form is equivalent to a loop surrounding an if/then statement, it is likely to be much more efficient in practice. Loops may not be nested. The \verb=break= statement, consisting only of that keyword, may be used to exit a loop immediately. \subsection{Exit Statement} The statement \verb=exit= immediately terminates the execution of an action. \subsection{Security} The security system is centered around the notion of {\em control}. Under most circumstances, one object controls another if both are owned by the same player. However, certain objects have special permissions which affect control as follows: \begin{enumerate} \item An object with its \verb=?wizard= bit set to \verb=?true= controls any non-admin object. \item No non-wizard object may control a wizard object, even if they have the same owner. \item No other object ever controls an admin object. \end{enumerate} Control is necessary to modify an object's variables, and is used to determine when a \verb=move= expression may be successfully carried out. Control is not necessary to read an object's variables. In all cases control is tested for the object \verb=me=, which provides the currently-executing code. \section{Command Parsing} Actions come in several varieties. Single-word actions like \verb=&get= or \verb=&look= take at most one object and are handled by either that object, the player, or the surrounding room. Two-word actions like \verb=&get>from= or \verb=&describe<as= require two objects; the object ``pointed to'' by the \verb=<= or \verb=>= handles the action and the other is passed through unparsed in the variable \verb=$text=. There are also two special actions used by the parser, \verb=_invoke= and \verb=_default=. When presented with a line of input the command parser considers many possible ways of interpreting it as an action, taking the first successful parse in the following list: \begin{description} \item[\bf \@ code] If the line begins with an at-sign, the remainder of the line is treated as code in the programming language, compiled, and run with \verb=me= set to the current player. The player must have the \verb=?programmer= bit set to use this feature. \item[\bf verb] If verb is a single-word action on the room (first choice) or the current player, invoke it with \verb=$text= set to the null string. Example: {\em look}. \item[\bf object] If the entire command line matches an alias for an object in the current room or the player's inventory, and that object has an \verb=&_invoke= method, call that method with \verb=$text= set to null. Example: {\em north}. \item[\bf verb object] If object matches an object in the current room or the player's inventory, and \verb=&verb= is an action on that object, invoke it with \verb=$text= set to null. Example: {\em get book}. \item[\bf verb1 object1 verb2 object2] If \verb=&verb1<verb2= is an action on some object matching object1, invoke it with \verb=$text= set to object2 as an unparsed string (the action may, of course, choose to do its own match on object2.) Similarly, if \verb=&verb1>verb2= is an action on some object matching object2, invoke that action with \verb=$text= set to object1. Examples: {\em whisper Hi there to fred} could invoke a \verb=&whisper>to= action on fred if it has one, and {\em open door with key} could invoke an \verb=&open<with= action on some object matching ``door''. \item[\bf verb text] Call \verb=&verb= on room or player with all other words passed through unparsed in \verb=$text=. \\ Example: {\em say Good Morning!} \item[\bf text] Call \verb=&_default= on room or player if possible. This behavior is a last resort for the parser, and is used primarily to implement error messages. \end{description} If none of the above parses are possible, the system will print an uninformative message and wait for another line of input. During the execution of an action the variable \verb=me= is set to the object which ``receives'' it, i.e. the object on which the action is found. \verb=you= is always the current player, and \verb=$text= is set as described above. One must be careful when writing an action handler to consider all circumstances under which it might be invoked. For example, suppose that an object A (with an alias named ``A'') has a handler for \verb=&look=. Then it is possible that this handler might be called in any of the following situations: \begin{itemize} \item If some player contained in A types ``look''. \item If A is a player who types ``look.'' \item If some player who either holds A or is in the same location as A types ``look A''. \item If some player contained in A types ``look B'' and B does not match anything in A or in the player. \item If A is a player who types ``look B'' and B doesn't match anything. \end{itemize} In most cases where the differences between these cases are critical (as in the last two cases above) it is possible to distinguish them by examining \verb=$text= and the relative positions of \verb=me= and \verb=you=. \end{document}