tmuck2.4/
tmuck2.4/admin/scripts/
tmuck2.4/docs/
tmuck2.4/minimal-db/
tmuck2.4/minimal-db/data/
tmuck2.4/minimal-db/logs/
tmuck2.4/minimal-db/muf/
tmuck2.4/old/
tmuck2.4/src/
tmuck2.4/src/compile/
tmuck2.4/src/editor/
tmuck2.4/src/game/
tmuck2.4/src/interface/
tmuck2.4/src/scripts/
tmuck2.4/src/utilprogs/
Information available on the following:

PRIMITIVES

Arithmetic:
+ - * / % < > <= >= = and or not random

Stack Manipulation:
depth        dup          over         pick         pop          rot
rotate       swap

Bit, Field, and Property Setting/Getting:
addprop      desc         drop         fail         flag?        getpropdbref
getpropstr   getproptime  getpropval   name         odrop        ofail
osucc        remove_prop  set          setdesc      setdrop      setfail
setname      setodrop     setofail     setosucc     setprop      setsucc
succ

Strings:
explode      instr        rinstr       strcat       strcmp       strcut
stringcmp    stringncmp   strlen       strncmp      subst

Connections and connected players (all optional except awake? and online):
awake?       conboot      concount     condbref     conhost      conidle
connections  contime      online

Miscellaneous:
@            !
addpennies   atoi         call         check_moveto contents     copyobj
dbcmp        dbref        dbtop        execute      exit         exit?
exits        getlink      int          intostr      location     match
moveto       next         notify       notify_except number?     ok?
owner        pennies      player?      prog         program?     pronoun_sub
read         rmatch       room?        self         strftime     systime
thing?       time         var          variable

TOPICS:

@Q           addresses    arguments    comments     conventions  credits
editor       execution    home         instruction-count         linking
locking      macroes      objects      permissions  quickref     recursion
stack        tutorial     user         types        variables
&&
credits
MUF REFERENCE MANUAL:

The MUF reference manual was updated for TinyMUCK 2.1.1 by Jethro with help
from Black_Dougal.  ChupChup updated it for 2.2.  Jiro/Mizue adapted it for
2.3, as well as inserting the quick reference and reformatting it for use with
the `man' command; corrections can be mailed to arromdee@jyusenkyou.cs.jhu.edu.
&
editor
The dictionary of MUF editor commands may be obtained with the command `man
editor-dict'.  The dictionary is several screens long.
&&
editor-dict
DICTIONARY OF MUF EDITOR COMMANDS
---------------------------------

@PROG <name>: enters the editor from Muck, creating a new program if none
exists matching the name.  [Player must have Mucker bit.]
@EDIT <name>: enters the editor from Muck; program with the given name must
already exist.  [Player must have Mucker bit.]

<number> i(insert)
Enter insert mode before line #i.  Any number of lines may be contiguously in-
serted.  The old line #i will become the first line after the inserted lines.
Blank lines are ignored and do not become part of the program.  Entering the
character `.' (period) alone on a line (not preceded or followed by any
spaces) exits insert mode.  The `.' does not become a line.

-1, as a line number, indicates the last line in the program.

<number1> <number2> l(ist)
Display all lines from <number1> to <number2> inclusive.  If only one <number>
is given, only that line will be displayed.

<number1> <number2> d(elete)
Delete all lines from <number1> to <number2> inclusive.  If only one <number>
is given, only that line will be deleted.

c(ompile)
Compile the program you are editing.  This must be done before a program will
run properly.

u(nassemble)
Unassemble program.  This was used to test MUF during its development.  It has
no real use for programmers.

n(umbers)
Toggle display of numbers in program listings.

q(uit)
Quit from the editor. @Q may also be used to do this.

<name1> <name2> s(how)
Show macros in long format: name of macro, name of the person who entered it,
and the body of the macro.  `a z s' will show all macros, for instance.

<name> k(ill)
Delete a macro.  You can only delete your own macros unless you're a wizard.

<name1> <name2> a(bridged)
Abridged macro display.  Shows only the names of macros.

<number> v(iew)
Displays the header of the program which is #<number>.  You must otherwise have
permission to list the program.
&
conventions
The conventions used when describing primitives are:
    d: database reference         #1000
    i (i1, i2...): integer        15
    s: string                     "this is a string"
    v: variable                   varname
    a: function address           'function-name

    c: connection                 [not every Muck 2.3 has connections]

    x, y: any of the above

    --: separates values accepted and returned; ( s -- i ) accepts a
        string and returns an integer.

    There is no such thing as a boolean value; #-1, "", 0, and disconnected
    connections all act like FALSE boolean values with words such as `not',
    `and', and `if'; other values act as TRUE booleans.
&
+ ( i1 i2 -- i )
Addition of integers.  Can also be used to add to variables (as opposed to the
contents of variables).
&
- ( i1 i2 -- i )
Subtraction (i1 - i2) of integers.  Can also be used to subtract from
variables (as opposed to the contents of variables).
&
* ( i1 i2 -- i )
Multiplication, on integers.  Can be used on variables if you really feel like
it.
&
/ ( i1 i2 -- i )
Division (i1 divided by i2, or v divided by i2).  This is integer division
which truncates towards zero.  You can use it on variables if you get the urge.
&
% ( i1 i2 -- i )
Modulus operator (i1 mod i2).  This modulus operator fits the equality
abs(i1 mod i2) == abs(i1) mod abs(i2).  It can be used on variables (why?  Who
knows.)
&
< ( i1 i2 -- i )
Returns 1 if i1<i2, 0 otherwise.
&
> ( i1 i2 -- i )
Returns 1 if i1>i2, 0 otherwise.
&
= ( i1 i2 -- i )
Returns 1 if i1<=i2, 0 otherwise.
&
<= ( i1 i2 -- i )
Returns 1 if i1>=i2, 0 otherwise.
&
>= ( i1 i2 -- i )
Returns 1 if i1 equals i2, 0 otherwise.
&
@ ( v -- x )
Retrieves variable v's value as x.
&
! ( x v -- )
Sets variable v's value to x.
&
addpennies ( d i -- )
d must be a player or thing object.  Adds i pennies to object d.  Without
Wizard permissions, addpennies may only produce a result between zero and
MAX_PENNIES, and when used on other players may be used only to add.
&
addprop ( d s1 s2 i -- )
Sets property associated with s1 in object d.  If s2 is a null string, the
property is set as an integer property using i; otherwise, the property is set
using s while the integer is ignored.  In either case all four parameters are
needed.  This MUF word remains for backwards compatibility and will eventually
go away; use setprop instead.
&
and ( x y -- i )
Performs the boolean `and' operation on x and y, returning 1 if both i1 and i2
are TRUE, and returning 0 otherwise.
&
atoi ( s -- i )
Turns string s into integer i.  If s is not a string, then 0 is pushed onto
the stack.
&
awake? ( d -- i )
Returns the number of times a player is connected.
&
call ( d -- ?? )
Calls another program d.  d must have been compiled already.  d will inherit
the values of ME, LOC, TRIGGER, and all other variables (even if the variables
are given different names within d), and the same stack.  The user must have
permissions on d, or else d must have the LINK_OK flag.
&
check_moveto ( d1 d2 -- s )
Checks if the moveto function can be used to legally move object d1 to location
d2.  It returns a null string if it can, and otherwise a string corresponding
to the error moveto would return.  (In either case it doesn't actually move
anything.)

See moveto.
&
contents ( d -- d' )
Pushes the dbref of the first thing contained by d.  This dbref can then be
referenced by `next' to cycle through all of the contents of d.  d may be a
room or a player.
&
copyobj ( d -- d' )
Creates a new object (returning d' on top of the stack) that is a copy of ob-
ject d except for any actions which may be on it.  You can only `copyobj'
things, and each program is allowed to create only one new thing per run.
&
dbcmp ( d1 d2 -- i )
Performs comparison of database objects d1 and d2.  If they are the same ob-
ject, then i is 1, otherwise i is 0.
&
dbref ( i -- d )
Converts integer i to object reference d.  `44 dbref' is the same as `#44'.
&
dbtop ( -- d )
Returns the dbref of the top object in the database.
&
depth ( -- i )
Returns the stack depth.
&
desc ( d -- s )
Takes object d and returns its description (@desc) string field.
&
drop ( d -- s )
Takes object d and returns its drop (@drop) string field.
&
dup ( x -- x x )
Duplicates the item at the top of the stack.
&
else
See if.
&
execute ( a -- ?? )
Executes the function pointed to by the address a on the stack.  If the
function has different permissions than the current program, it will be run
with its own permissions instead of the current program's permissions.  (2.2
did not do this.)
&
exit ( -- )
Exits from the word currently being executed, returning control to the calling
word, at the statement immediately after the invocation of the call (exiting
the program if applicable).
&
exit? ( d -- i )
Returns 1 if object d is an exit object, 0 if otherwise.  See also player?,
program?, room?, thing?, ok?.
&
exits ( d -- d' )
Returns the first exit in the linked exit list of room/player/object d.
This list can be transversed with `next'.  The player must have permission
on d.
&
explode ( s1 s2 -- ... i )
s2 is the delimiter string, and s1 is the target string, which will be frag-
mented, with i pushed on top of the stack as the number of strings s1 was bro-
ken into.  For instance:
    "Hello world" " " explode
will result in
    "world" "Hello" 2
on the stack.  (Note that if you read these items off in order, they will come
out "Hello" first, then "world".)  s2 may be any length greater than 0.
&
fail ( d -- s )
Takes object d and returns its fail (@fail) string field.
&
flag? ( d s -- i )
Reads the flag of object d, specified by s, and returns its state: 1 = on; 0 =
off; the string s may be abbreviated to down to one letter.  All flags may be
read, including the BUILDER, MUCKER, QUELL, and WIZARD flags (which cannot be
set).  flag? returns 0 for WIZARD if the wizard is also QUELL, and 0 for un-
supported or unrecognized flags.
&
getlink ( d -- d' )
Returns what object d is linked to, or #-1 if d is unlinked.  The interpreta-
tion of getlink is the same as for the @LINK command in Muck; for an
exit/action it returns the room, program, action, or thing linked to.  For a
player, program, or thing, it returns its `home', and for rooms it returns the
drop-to.
&
getpropdbref ( d s -- d )
Retrieves the dbref associated with property s in object d.  If the dbref
doesn't exist, #-1 is returned.
&
getpropstr ( d s -- s )
Retrieves the string associated with property s in object d.  If the property
doesn't exist, "" (null string) is returned.
&
getpropval ( d s -- i )
Retrieves the integer value i associated with property s in object d. If the
property doesn't exist, 0 is returned.
&
if ... [ else ... ] then ( x -- )
Examines boolean value x.  If x is TRUE, the sequence of statements after the
`if' up until the `then' (or until the `else' if it is present) performed.  If
it is FALSE, then these statements are skipped, and if an `else' is present,
the statements between the `else' and the `then' are performed.  Control con-
tinues as usual at the statement after the `then'.  Note that checking the top
of the stack actually pops it, so if you want to re-use it, you should dup
(see `dup') it before the if.  For every `if' in a word, there MUST be a
`then', and vice-versa.  `else' is optional.  See booleans, conventions.
&
instr ( s s1 -- i )
Returns the first occurrence of string s1 in string s, or 0 if s1 is not
found.  See also rinstr.
&
int ( x -- i )
x must be a variable or a dbref.  Converts x into integer i.  (To convert a
string, use `atoi').
&
intostr ( x -- s )
x must be an integer or dbref.  Converts x into string s.
&
location ( d -- d' )
Returns location of object d as object d'; this will work on rooms to find
parent rooms, and on exits/actions to find sources.  It returns #-1 if used on
the global environment, which has no parent.
&
match ( s -- d )
Takes string s and matches it to find an object with that name or containing
the string at the start of a word in its name.  `here' and `me' do work.  If
nothing is found, d = #-1.  If ambiguous, d = #-2. If HOME, d = #-3.  In a
program being run by a wizard, or one which is set W, this will match any
object in the database with #number or *player.
&
moveto ( d1 d2 -- )
Moves object d1 to object d2, or moves it home if d2 is #-3.
MOVETO is affected by the following rules: The source, object, and destination
must be either owned by you or JUMP_OK (the destination may also be HOME).
Also, you may always move something owned by you out of any source, and you
may always move something home if you own the source.

If the thing and destination are rooms, you may also do the moveto if the
destination is LINK_OK or ABODE (room parenting).

See check_moveto.
&
name ( d -- s )
Takes object d and returns its name (@name) string field.
&
next ( d -- d' )
Takes object d and returns the next thing in the linked contents/exits list of
d's location.
&
not ( x -- i )
Performs the boolean `not' operation on x, returning 1 if x is FALSE, and re-
turning 0 otherwise.  See conventions.
&
notify ( d s -- )
d must be a player object, and s a string.  This directly prints the message
to that player, followed by a carriage return.  If the string is null, nothing
is printed; to get a blank line, use a string containing a single space.
&
notify_except ( d1 d2 s -- )
d1 must be a room object, and s a string.  This prints the message to all
players in location d1 except object d2.  If d2 is not a player, or if d2 is
NOTHING (#-1), all players are notified.  If s is null it prints nothing; to
get a blank line, use a string containing a single space.
&
number? ( s -- i )
Returns 1 if string on top of the stack contains a number, otherwise 0.  This
checks the characters in the string, not the type of the data on top of the
stack.
&
odrop ( d -- s )
Takes object d and returns its odrop (@odrop) string field.
&
ofail ( d -- s )
Takes object d and returns its ofail (@ofail) string field.
&
ok? ( x -- i )
Takes x and returns 1 if x is a type dbref, falls within the range of objects
in the database, and is not a garbage object.  See also exit?, player?,
program?, thing?.
&
online ( -- d1 d2 ... i )
Returns the dbrefs of all connected users, in reverse WHO order, along with
the number of users.
&
or ( x y -- i )
Performs the boolean `or' operation on x and y. Returns 1 on the stack if ei-
ther x or y is TRUE, and returns 0 otherwise.
&
osucc ( d -- s )
Takes object d and returns its osuccess (@osucc) string field.
&
over ( x y -- x y x )
Duplicates the second-to-top thing on the stack.  This is the same as `2 pick'.
&
owner ( d -- d' )
d is any database object.  Returns d', the player object that owns d.  If d is
a player, d' will be the same as d.
&
pennies ( d -- i )
Gets the amount of pennies player object d has, or the penny value of thing d.
&
pick ( ni ... n1 i -- ni ... n1 ni )
Takes the i'th thing from the top of the stack and pushes it on the top.
`1 pick' is equivalent to swap, and `2 pick' is equivalent to over.
&
player? ( d -- i )
Returns 1 if object d is a player object, and 0 otherwise.  See also program?,
room?, thing?, exit?, ok?.
&
pop ( x -- )
Pops the top of the stack into oblivion.
&
prog ( -- d )
Returns the dbref of the current program.  (If the program is called by
another, the value is still that of the current program, not that of the
caller.)
&
program? ( d -- i )
Returns 1 if object d is a program, and 0 otherwise.  See also player?, room?,
thing?, exit?, ok?.
&
pronoun_sub ( d s -- s' )
Takes database object d and substitutes string s according to o-message
rules.  For example:
  me @ "%N has lost %p marbles." pronoun_sub
would return:
  "Igor has lost his marbles."
if the player's name was Igor and his sex were male.  d does not have to be a
player for the substitutions to work.
&
put ( ni ... n1 x i -- x ... n1 )
Takes an item and puts it i locations down in the stack, replacing what's
already there.  The referse of `pick'.
&
random ( -- i )
Returns a random integer from 0 to the MAXINT of the system running the MUCK.
In general this number is (2^31)-1 or 2147483647.
&
read ( -- s )
Reads a string s from the user.  If this command is used in a program to which
something is locked, the lock will immediately fail and the fail messages will
be printed, though the program will still run.

If the string is @Q, the program immediately exits.
&
remove_prop ( d s -- )
Removes property s from object d.  If the property begins with an underscore,
`_' or a dot `.', and the effective user does not have permission on that ob-
ject, the call fails.
&
rinstr ( s s1 -- i )
Returns the last occurrence of string s1 in string s, or 0 if s1 is not found.
See also instr.
&
rmatch ( d s -- d' )
Takes string s, checks all objects and actions associated with object d, and
returns object d' which matches that string.  For example, it matches actions
and inventory objects for a player object, actions on a thing object, etc.  If
nothing is found, d' = #-1.  if ambiguous, d' = #-2.  `rmatch' does not check
for the special names "me", "here", or "home".
&
room? ( d -- i )
Returns 1 if object d is a room, otherwise returns 0.  See also player?, pro-
gram?, thing?, exit?, ok?.
&
rot ( x y z -- y z x )
Rotates the top three things on the stack.  This is equivalent to 3 rotate.
&
rotate ( ni ... n1 i -- n(i-1) ... n1 ni )
Rotates the top i things on the stack.  i may be negative.
&
self ( -- a )
Returns the address of the current function.  See ADDRESSES.  This word may be
used in anonymous functions.
&
set ( d s -- )
Sets flag s to object d.  Currently flags things are: ABODE, CHOWN_OK, DARK
[DEBUG], HAVEN, JUMP_OK, LINK_OK, MURKY, STICKY[SETUID].  Boolean operations
(e.g. `!ABODE') work as expected.
&
setdesc ( d s -- )
Sets the desc field on object d.  The program must have permissions on d.
&
setdrop ( d s -- )
Sets the drop field on object d.  The program must have permissions on d.
&
setfail ( d s -- )
Sets the fail field on object d.  The program must have permissions on d.
&
setname ( d s -- )
Sets the name field on object d (unless d is a player, in which case there's
no way to specify the password).  The program must have permissions on d.
&
setodrop ( d s -- )
Sets the odrop field on object d.  The program must have permissions on d.
&
setofail ( d s -- )
Sets the ofail field on object d.  The program must have permissions on d.
&
setosucc ( d s -- )
Sets the osucc field on object d.  The program must have permissions on d.
&
setprop ( d s x -- )
Sets a property with name s on object d.  The property's value x may be an
int, string, or dbref.  See addprop, and the various getprop functions.
&
setsucc ( d s -- )
Sets the succ field on object d.  The program must have permissions on d.
&
strcat ( s1 s2 -- s )
Concatenates two strings s1 and s2 and pushes the result s = s1s2 onto the
stack.
&
strcmp ( s1 s2 -- i )
Compares strings s1 and s2.  Returns 0 if they are equal, otherwise returns as
the difference between the first non-matching character in the strings.  For
example, "a" "z" strcmp returns 25.  This function is case sensitive, unlike
stringcmp.  See also strncmp, stringcmp, stringncmp.
&
strcut ( s i -- s1 s2 )
Cuts string s after its i'th character.  For example,
   "Foobar" 3 strcut
returns
   "Foo" "bar"
If i is zero or greater than the length of s, returns a null string in the
first or second position, respectively.
&
strftime ( i s -- s1 )
Takes a time (returned by `systime') and a string, returning a string format-
ted according to strftime(3).  Special format strings are of the format %[[-
]width[.precision]type.  `width' is a number specifying the field width;
strings are padded with spaces to the right, or to the left if a minus sign is
also added.  The precision is a number indicating the maximum length printed;
the value is truncated on the right if this is exceeded.  The type is a char-
acter or characters, as follows:
    m        month (01-12)
    h, b     month, three letter string (Jan, Feb...)
    B        month, full string (January, February...)
    d        day of month (01-31)
    e        day of month (1-31, space-padded)
    j        Julian day of year (001-366)
    w        day of week (0-6, 0 is Sunday)
    a        day of week, three letter string (Sun, Mon...)
    A        day of week, full string (Sunday, Monday...)
    y        year of the century (00-99)
    Y        year (padded with 0's to 4 places)
    H        hour (00-23)
    I        hour (01-12)
    k        hour (0-23, space-padded)
    l        hour (1-12, space-padded)
    M        minute (00-59)
    S        second (00-61)
    s        seconds, same as the argument
    p        "AM" or "PM"
    z, Z     three letter timezone (of the muck)
    %        percent character
    U        week number (00-53); weeks start on Sunday and must contain
             4 or more days belonging to the year
    W        same except weeks start on Monday

    C        equivalent to %a %b %e %H:%M:%S %Y
    c        equivalent to %m/%d/%y
    x        equivalent to %m/%d/%y %H:%M:%S
    D        date in format mm/dd/yy
    T, X     equivalent to %H:%M:%S
    R        equivalent to %H:%M
    r        equivalent to %I:%M:%S %p

    i        similar to WHO list idle time (ie: '  2d' or '  5m' or ' 23s')

    %t (tab) and %n (newline) are disabled on the Muck.
&
stringcmp ( s1 s2 -- i )
Compares strings s1 and s2. Returns 0 if they are equal, otherwise returns the
difference between the first non-matching character in the strings.  For exam-
ple, "a" "z" stringcmp returns 25.  This function is not case sensitive, un-
like strcmp.
&
strlen ( s -- i )
Returns the length of string s.
&
strncmp ( s1 s2 i -- i' )
Compares the first i characters in strings s1 and s2 (case sensitive).  Return
value is like strcmp.
&
stringncmp ( s1 s2 i -- i' )
Compares the first i characters in strings s1 and s2 (case insensitive).
Return value is like stringcmp.
&
subst ( s1 s2 s3 -- s )
s1 is the string to operate on, s2 is the string to change all occurrences
of s3 into, and s is resultant string.  For example:
    "HEY_YOU_THIS_IS" " " "_" subst
results in
    "HEY YOU THIS IS"
s2 and s3 may be of any length.
&
succ ( d -- s )
Takes object d and returns its success (@succ) string field s.
&
swap ( x y -- y x )
Takes objects x and y on the stack and reverses their order.
&
systime ( -- i )
Returns the number of seconds since the start of January 1, 1970.  See time.
&
then
See if.
&
thing? ( d -- i )
Returns 1 if object d is a thing, otherwise returns 0, See also player?, pro-
gram?, room?, exit?, ok?.
&
time ( -- s m h )
Returns the time of day as integers on the stack, seconds, then minutes,
then hours.  See systime.
&
var <name>
Var is not a `true' primitive in that it must always be used outside words and
does not alter the stack in any way. When the compiler sees a `var' statement,
it allows the use of <name> as a variable in all words sequentially defined
after the var declaration. See VARIABLES.
&
variable ( i -- v )
Converts integer i to variable reference v. Of the pre-defined variables,
`me' corresponds to integer 0, `loc' to 1, and `trigger' to 2. Thus:
     me @
and
     0 variable @
will do the same thing (returning the user's dbref). User-defined variables
are numbered sequentially starting at 3 by the compiler. Note that these vari-
able numbers can be used even if variables have not been formally declared.
See @, !, and VAR.
&
connections ( -- c1 c2 ... i )
Returns a list of connections to the Muck; a player connected multiple times
appears multiple times in the list.  The connections are a separate type, not
integers, and cannot be operated on with arithmetic.  The connections are
guaranteed valid at least to the next `read', after which they might be
outdated.

See types.  Also, some Mucks are not set up with this function available.
&
concount ( -- i )
Returns the number of connections to the Muck.

See types.  Also, some Mucks are not set up with this function available.
&
conidle ( c -- i )
Returns the number of seconds a connection is idle.  

See types.  Also, some Mucks are not set up with this function available.
&
contime ( c -- i )
Returns a time (see types) indicating when the connection connected.  This
time is the number of seconds since the start of January 1, 1970 and is
suitable for use with the `strftime' function.

See types.  Also, some Mucks are not set up with this function available.
&
condbref ( c -- d )
Returns the dbref of the player that is on a given connection.

See types.  Also, some Mucks are not set up with this function available.
&
conhost ( c -- s )
Returns a string indicating the host name of the given connection.  (Wizard-
only.)  The string will be in IP number form if the host can't be or hasn't
yet been resolved.

See types.  Also, some Mucks are not set up with this function available.
&
conboot ( c -- )
Disconnects the specified connection after sending a "You have been booted
from the game." message.  This MUF word is wizard-only; furthermore, the head
wizard (usually #1) can't be booted.

See types.  Also, some Mucks are not set up with this function available.
&
ADDRESSES, QUOTES, '
The address of a function may be specified using the ' operator.  This operator
works on functions, macroes, primitives, and anonymous functions (in previous
Muck versions it only worked on functions); addresses can be passed around,
stored in variables, and passed to other programs.  They're called using the
`execute' word.

Examples of addresses:
    'fun                     (where fun is a function name)
    '.pmatch                 (macro)
    'notify_except           (primitive)
    ': me @ swap notify ;    (anonymous function)
&
ARGUMENTS
A program may be invoked by the player with a command-line argument. This ar-
gument is pushed on the stack before the program is executed.  For example, if
an exit "smell" is linked to a program, typing "smell flower" will invoke the
program with the argument "flower" pushed on the stack. Arguments are always
strings, never integers.

When the user types a command that might use an action, Muck tries to match
all actions near the user.  If the action isn't linked to a program, Muck
matches exact names.  If it is linked to a program, Muck checks all such ac-
tions to find the one that matches as many word(s) as possible.  For example,
if you type "get flower", Muck will first find an action named "get flower"
and then one named "get".  The rest of what you typed is pushed on the stack
as one string.  Thus, if "eat jelly doughnut" is matched with "eat", "jelly
doughnut" will be pushed.  Even if an exact match is found (i.e., an exit named
"eat jelly doughnut") a null string ("") is pushed on the stack.  Thus, the
program always starts with one element on the stack.

TinyMUCK searches for exit matches in this order: room exits, player inventory
exits, room contents exits, player exits, parent room exits.

If the program is in a @# field, the command-line argument is the string after
the number.  For example, if a player looks at something whose description is
"@1000 red", program 1000 will be invoked with the word "red" on the stack.

See EXECUTION, LINKING, LOCKING, and `explode'.
&
COMMENTS
Comments in MUF are surrounded by parentheses. Any characters in a program
between two parentheses (e.g. `(argle)') will be ignored by the compiler, and
do not count as part of the program.
&
EXECUTION
If a program has had an exit linked to it or an object locked to it, then
whenever someone tries to use that object, it may be executed (see LINKING and
LOCKING for more details).

Program execution starts with the last word defined in the program; when the
program calls other programs execution is transferred to the last word of that
other program.

When a program is initially executed by an exit that is linked to it, at least
one word will always be on top of the stack. See ARGUMENTS for more details.
When a program is executed by a locked object, the stack will normally start
empty.  See also STATEMENTS and WORDS.
&
HOME
Dbref #-3 refers to the home of a thing or player; things linked to `home' are
linked there, and doing a `moveto' which moves something there moves it home.
Programs always have a `home' which is the program owner.
&
INSTRUCTION-COUNT
Programs may normally execute 50000 instructions before a `read'.  Programs
with wizard permissions do not have this restriction.
&
LINKING
You may @link exits (but nothing else) to a program. A program will then exe-
cute every time a player goes through that exit. Multiple exits may be linked
to a single program.  See EXECUTION, and various entries in the help for Muck
including @ACTION, @LINK, @OPEN, ACTIONS and LINKING.
&
LOCKING
You may @lock any kind of object to a program.  The program will then execute
every time a player TRIES to go through that exit, pick up that thing or pro-
gram, look at that room, or rob that player.  The lock succeeds if the program
finishes with a 1 on the stack, and fails if it finishes with 0.  See EXECU-
TION and LINKING.
&
MACROS, MACROES
Macroes are defined with the command, within the MUF editor,
    def name body
To list the definition of a macro that was previously defined,
    name show
The command to delete a macro (which must have been created by you) is
    name kill
To use a macro in a program, precede its name with a . symbol (period).
All macroes are global; any MUF programmer can see them and use them.
&
PROPERTIES
All rooms, players and things have properties. These may be set by either
players or programs.  However, players may only set properties to strings,
while programs may set them to either strings or integers.  Thus, things such
as hit points, dollars, strength, etc., can be set.

A property whose name starts with a `_' or `.' can be only set or erased by
programs run by or SETUID to the owner of the object with the property.  If
the name starts with a `.', this restriction also applies to reading it.

Remember, though, that players can always `@set me = :' which erases all their
properties.  Be prepared to always use a default value when trying to read
properties, or set the properties on an object of your own instead of on the
player.

See addprop, getpropdbref, getpropstr, getproptime, getpropval, remove_prop,
and setprop.
&
RECURSION
Recursion refers to a program word calling itself.  This is often used to
replace iterative loops.  See RECURSION.
&
STACK
In MUF, all statements are pushed on the stack when a running program reaches
them during execution, except primitives and user-defined words, which are ex-
ecuted, and variables, whose addresses are pushed on the stack (and may be
operated on by the @ and ! primitives). The maximum number of elements that
can be pushed on the stack is about 512. See EXECUTION, STATEMENTS, VARIABLES
and WORDS.
&
TYPES
Available types are integers, strings, database references, variables, func-
tions, and optionally connections.  Integers, strings, database references,
and variables and functions can be specified in a MUF program; connections
cannot.  Not all MUF words work on all types.  See VARIABLES.
&
USER
The person using the program (as opposed to the programmer).  Non-setuid pro-
grams run according to the permissions of the user rather than the programmer
who owns the program.  The variables ME and LOC refer to the user. See
VARIABLES.
&
VARIABLES
Variables must be defined outside of words using the `var' primitive, and are
global the whole program.  When a variable name is a program statement, its
address is pushed on the stack.  The program can then use the primitive `@' to
retrieve is value, or `!'  to load a value into it.

The variables ME, LOC and TRIGGER are pre-defined in MUF. ME stores the dbref
of the program's user. LOC stores the dbref of his location.  TRIGGER stores
the dbref of the exit/thing which caused the program to be executed.  These
variables may be set; for a non-settable ME and LOC, use `"me" match' and
`"here" match'.  See USER, @, and !.
&
WORDS
A word in MUF begins with a colon (`:') and ends with a semicolon (`;').  The
statement after the colon is the name of the word, and the remaining state-
ments are the actual executed code of the word.  Thus, a word's form is:

        : {word name} {body of word} ;

Obviously, a program may contain many words. Calling a word is accomplished by
using its name. A word may not be called before it has been defined, though a
word can call itself.  See CALL, EXECUTION, RECURSION, and STATEMENTS.
&
OBJECTS
Database objects are specified with #, so object number 10 is specified with
`#10' or `10 dbref'.  There are three special objects:

#-1 is returned by `match' and `rmatch' and a few other MUF words to
indicate no object.

#-2 is returned by `match' and `rmatch' to indicate that the result of the
match is ambiguous.

#-3 is returned by `match' and `getlink' to indicate the special location
`home'.  It may be used in `moveto' to send an object home.
&
LOOPING
There are no looping constructs in standard MUF.  Loops may be simulated
with recursion; however, tail recursion is not specially treated, and the
stack will overflow at 512 levels.
&
@Q
@Q, when typed as input to a `read' (see `read') will immediately quit all
programs and return control to the user.
&
PERMISSIONS
Normally, programs run with the permissions of the person running the program.
If the program is S (SETUID), it instead runs with the permissions of the
program owner.  Sometimes you may need to have parts of your program run with
each set of permissions, in which case you have to have two programs which
call each other, one SETUID and one not.

Programs set W run with wizard permissions if owned by a wizard.  If the
program is not set W, and is run by a wizard or SETUID and owned by a wizard,
the program runs with only the permissions the wizard would have as a normal
player.  (The exception is that if a wizard runs a program, the `match' MUF
word will match any object in the database if given a string of the form
#number or *player.)

To have permission to run a program at all, you must be the program owner,
the program must be LINK_OK, or you must be running the program via something
owned by the program owner (which usually means you're using an action owned
by the program owner).
&
TUTORIAL
Type "man muf-tutorial-1, muf-tutorial-2, and muf-tutorial-3" for the MUF
tutorial.  This is a number of pages long.

It is also hopelessly obsolete.  Not actually wrong, but placed here (with a
few updates) mostly for completeness.  If you have a useful substitute, please
write to the maintainer of 2.3.
&&
muf-tutorial-1
                     Zen in the Art of the Towers of Hanoi
                   (or The Basics of MUF in 10 megs or less.)

                           MUCK 2.1 version: Stinglai
                           MUCK 2.2 update: chupchup
                           MUCK 2.3 update: Jiro/Mizue


This is an introduction to MUF, a dialect/subset of forth used to do really
really neat things with TinyMuck 2.3.  This intro was designed to be read be-
fore any of the other MUF information; it (hopefully) should supply you with a
fair idea of what MUF is all about.  It's written at a non-programming-stud
level, all the better for understanding.


All MUF programs work by performing operations on a stack.

For all you non-programmer types, a stack is just a tool used to store infor-
mation.  Information is manipulated by "pushing" things onto the stack and
"popping" things off.  The last thing you've placed on a stack is always the
next thing you would take off if you tried; it's like piling objects on top of
each other, when the only thing you can remove from the pile is the thing on
top.  For example, if you were to push the number 23, then push the number 42,
and then pop a value off the stack, you would get 42.  If you were to pop
another value off the stack after this, you would get 23.  If you were to try
and pop another value, you would get an error, since the stack would now be
empty.  (This is a "stack underflow.")

The basic procedural unit in MUF is called the word.  A word is simply a se-
quence of instructions.  In program text, a word always starts with a colon,
then the word's name.  A semicolon marks the end of a word.

For example:

: detonate_explosives
        (text of word here)
;

would define a word called detonate_explosives.

Parentheses are used to delineate program comments; everything inside comments
is ignored by the computer.  The detonate_explosives word above, if run as
shown, would do absolutely nothing.

Indentation in MUF is arbitrary and serves to make the program more readable
to people.


In MUF, there are several types of constant values.  Integers and strings are
familiar to those of you who know regular programming languages; MUF also uses
dbrefs.  There are also variables (variable addresses), function addresses,
times, and possibly connections.  Any type of value is stored and retrieved
from the stack as a single unit.  (The string "Hello, Sailor!", for example,
would be stored on the stack in its entirety: "Hello, Sailor!";  it would not
be stored byte-by-byte or word-by-word or in any other such silly way.)  To
push a constant onto the stack, you only need to state its value.  The follow-
ing is a completely legitimate procedure:

: pointless_word
        "Old Man"
        "I'm"
        37
        "What?"
        37
        "Not old!"
;

However, run by itself, it wouldn't do anything visible to the user.  It would,
however, create a stack which looks like this:

("Old Man"  "I'm"  37  "What?"  37  "Not old!")

In the above stack, "Old Man" is the value on the bottom.  "Not old!" is the
value on top of the stack, and would be the next value retrieved.

Formatting of programs is arbitrary with respect to spacing.  For instance,
the above example could be written as

: pointless_word "Old Man" "I'm" 37 "What?" 37 "Not old!" ;

Functions which are available in the standard MUF library take values from the
top of the stack, do things with them, and usually leave something new back on
top of the stack.  We discuss below some examples of them.

The + routine takes the top two integers from the stack, adds them together,
and leaves the result on top of the stack.  In order to easily describe what
functions like this do, a certain stack notation is used:  for +, this would
be (i1 i2 -- z).  What's inside those parenthesis is a sort of "Before and
After" synopsis; the things to the left of the double-dash are the "before",
and those to the right are the "after".  (i1 i2 -- i) says that the function
in question takes two integers away and leaves one.  The letters used here to
tell what kind of data a stack object can be are:  i for integer, d for data-
base object, s for string, v for variable, and x or y to mean something that
can be more than one type.

Here are short descriptions of the procedures listed above so you can get the
hang of how they work:


+ (i1 i2 -- i)
Adds i1 and i2 together.  The word

: add_some_stuff
        2 3 +
;

will return 5.  The word

: add_some_more_stuff
        2 3 4
        5
        + + +
;

will return 14.  When add_some_more_stuff first reaches the "+ + +" line,
the stack will be (2 3 4 5).

The first + changes the stack to look like: (2 3 9).

The next causes: (2 12).

The final + returns: (14).


- (i1 i2 -- i)
Subtracts i2 from i1.

: subtract_arbitrary_things
        10 7 -
;

will return 3 on top of the stack.  The word

: subtract_more_arbitrary_things
        10 7 1 - -
;

will return 4 on top of the stack.  Before subtracting, the stack looks like:
(10 7 1).

The first subtraction changes it to (10 6), and the final subtraction to (4).
Note that this is not the same as

: subtract_more_arbitrary_things
        10 7 - 1 -
;

which would return a value of 2.  (Can you see why?)

The words *, %, and / work similarly to provide multiplication, modulus, and
division operations.


swap (x y -- y x)
Switches the top two things on the stack.  This is useful for when you want
to know the value of x but want to save y for later use.

: swap_stuff_around
        1 5
        2 swap
        3
        "Three, sir!"
        swap
        "Boom!"
;

will, before it gets to the first swap, create a stack of (1 5 2).
After the swap, the stack looks like (1 2 5).  It then accumulates another
3 and a string constant, to look like (1 2 5 3 "Three, sir!")  It swaps
the last two again and adds another string, so the stack looks like:
(1  2  5  "Three, sir!"  3  "Boom!").


pop (x --)
Throws away the value on top of the stack.  As shown in the stack diagram, it
returns nothing but takes something, and so decreases the stack's total size.
Useful when you really really want to get to the next thing on the stack so bad
you don't care what's on top.  The word:

: needless_popping_waste
        "Immanuel Kant"
        "Heideggar"
        pop
        "David Hume"
        "Schoppenhauer"
        "Hegel"
        pop pop
;

would leave the stack looking like ("Immanuel Kant"  "David Hume").


dup (x -- x x)
copies the top stack item.  The word

: dup_example
        "Row"
        dup dup
        "Your"
        "Boat"
;
&&
muf-tutorial-2
would leave the stack as ("Row" "Row" "Row" "Your" "Boat").

random (-- i)
Doesn't even look at the stack, but piles a really really random integer on
top.  The word:

: feel_lucky_punk?
        random
        random
        random
;

would return a stack of three random numbers.


Because of the way the stack works, variables aren't as necessary in MUF as
they are in other languages, but they can be used to simplify stack-handling
operations.  To declare a variable, you simply add the line "var <name>"
at the beginning of your program.  Variables are of no specific type; a
variable which holds an integer can turn around the next second and hold
a string if it's feeling haughty enough.

The following words are important when dealing with variables:

! (x v --)
Set variable v to hold value x.  The program:


var answer

: multiply-and-store
        6 9 *
        answer !
;

will give the variable "answer" the value 42.


@ (v -- x)
This word (pronounced "fetch") retrieves the value of a variable and puts it
on the stack.  You should remember this since a common mistake among beginning
MUF programmers is to forget to put fetch symbols in their programs.
The word

 garply

by itself stands for the variable "garply", while the expression

 garply @

stands for the value of that same variable.  If you're familiar with Lisp, this
is analogous to the difference between garply and (garply).

The program:

var biggles
var fang
: more_silly_manipulation
        10 biggles !
        24 fang !
        biggles @ fang @
        +
;

will return the value 34 on top of the stack.  The program:

var biggles
var fang
: more_silly_manipulation
        10 biggles !
        24 fang !
        biggles fang +
;

is wrong, and will return an "Invalid argument type" error.


The next type of value you need to understand is the database reference.
They're specified with a # in front of a number; '#2032' represents item 2032
in the Muck database.  Because MUF was designed for Muck, there are lots of
special builtin words which work on database references, as well as three
special predefined variables with values that are database references.

These variables are "me", "loc", and "trigger", where "me" holds the player's
database reference, loc holds the player's location's database reference, and
trigger holds the database reference of the object that the program was linked
to, locked to, or in a field of.

me @ will return the player's item reference, while loc @ will return the
room s/he is in.  trigger @ returns the item that triggered the current
program, whether it is a player, exit, room, whatever.  A useful word to
know is:

name (d -- s)
Where d is a db reference and s is a string, name returns the name of item
x.


Now that you know about me @, another Muck function becomes useful.  Its
synopsis is:

notify (d s --)
When d is a player, notify prints string s out to user d.  The program

: warn
        me @
        "There is someone behind the next column waiting to jump you."
        notify
;

would print said message on the user's screen.


Before you can really start writing neat stuff in Muck, there is one more
thing you need to know about: control flow.

Certain MUF functions return values which are "true" or "false".  In MUF,
there are several "false" values, depending on the type.  0 is false for in-
tegers, "" is false for strings, and #-1 is false for db references.  Every-
thing else counts as "true".  For instance, consider the equals operator:

= (i1 i2 -- i)
If integers i1 and i2 are equal, this returns 1 (which is "true"); if the
integers aren't equal, this returns 0 (which is "false").  Therefore the word

: nonequals
        2 3 =
;

always returns 0.

dbcmp (d1 d2 -- i)
works exactly like equals, except that it takes database references.  It still
returns the integers 0 or 1.

strcmp (s1 s2 -- i)
compares strings, but works in reverse: it returns 0 ("false") when the
strings are not equal, and returns "true" when they are.  The reason for this
is so that it can return various values to indicate that one string is alpha-
betically before another.  (All these values are "true").

Another function is useful: negation.

not (x -- i)
If x is true, it returns 0 (which is a "false" value); if x isn't true, it
returns 1 (which is a "true" value).  You can use it on many different types
of values, but it always returns the integer 0 or 1.

Values of true and false are useful with if/else/then statements.  The
if/else/then statement selects between two courses of action depending on
whether a result is true or not.  The way it works is this:  If pulls an item
off the stack.  If the item is not 0, it executes everything between the IF
and the ELSE.  Otherwise it executes everything between the ELSE and the THEN.
In either case, execution continues after the THEN.  The ELSE is optional.

The name of this construction as if/else/then can be somewhat confusing, as it
certainly doesn't work quite like the if/then/else of other languages.

The word:

: word
        2 3 =
        if me @ "Your computer is broken!" notify
        else me @ "Your computer isn't _too_ broken." notify
        then
        me @ "Done executing this word." notify
;

will print "Your computer isn't _too_ broken." to the user, unless something
is really screwy with the math, and it thinks 2 equals 3, in which case it will
print "Your computer is broken!".  In any case, it will then print "Done
executing this word."

: ring
        me @ name
        dup
        "Leon" strcmp not if
            pop
            me @ "The doorbell rings and rings, but Priss ignores you." notify
        else
            print_greeting_message
        then
;

is a more complicated example.  The basic structure of this example is that it
checks your name.  If your name is Leon, it prints the ignore message.  (To
check if your name is Leon, the `strcmp' must be followed by `not', since
`strcmp' returns a false value if the strings are equal, instead of when they
aren't.)  Otherwise, it executes the word `print_greeting_message'.  Presum-
ably, you defined a word with such a name elsewhere, since there isn't any
built-in word with that name.

But what's the reason for the `dup' and `pop'?  Well, suppose
print_greeting_message needs to know the name to do its stuff.  (Of course, it
could do the `me @ name' again, but we'll ignore that since this is just a
sample program; in a real program, it might not be so easy to get the string
again.)  The sequence `"Leon" strcmp not if' does check to see if your name is
Leon; but it also removes the name, whatever it is, from the top of the stack.
If one of the if/else/then clauses needs to use the name, we have to make an
extra copy beforehand.  And once we do this, we find that _both_ clauses start
with this extra copy still on the stack, so we have to pop it away in the
clause that doesn't use it.
&&
muf-tutorial-3
*SAMPLE PROGRAM*

Ok, so you've been reading this whole thing so far, and you really want to
use this stuff to do something interesting.  The following program does
something interesting, and uses the function

strcat (s1 s2 -- s)
Concatenate strings s1 and s2, returning the result.

it also uses

location (d -- d')
Takes db reference d and returns d', the db reference for its location.


: far_vision
        #2032        (2032 is Sylia's object number.               )
        dup           (Make 2 copies; we're about to use 1.         )
        name          (Sylia might change her name in the future, so)
                      (instead of using "Sylia" here we just look up)
                      (her name.                                    )

        " is currently in "
        strcat                (Attach name to sentence so far         )
        swap                  (Flip the sentence back so we can get at)
                              (Sylia's dbref again.                   )

                      (Sylia's dbref is now at top of stack.   )

        location      (Where is Sylia?                         )
        name          (What is the name of the place she is in?)
        "." strcat strcat

        me @ swap notify    (Tell the player where Sylia is.)

        #2055         (Sylia's hardsuit is #2055.        )
        location
        #2032         (Sylia again                       )
        dbcmp         (Has she got her hardsuit with her?)
        if me @ "Watch out-- she's wearing her hardsuit!" notify then
;


    Note that this program uses no variables (except for the universally
    defined ME variable.)


In Muck, this program would be attached to, say, a homing device or a magic
staff.  Now, if Boomer ever wants to find Sylia, he can, and he'll even know
if she's defenseless or she's got her armor.

Without the comments and spaced out like you might see normally, this program
looks like:

: far_vision
        #2032 dup
        name " is currently in " strcat
        swap location name
        "." strcat strcat                   (Now we know where she is.)

        me @ swap notify

        #2055 location
        #2032 dbcmp
        if me @ "Watch out-- she's wearing her hardsuit!" notify
        then
;


Words can also be called by other words; to do this, you treat your other
words just like standard functions when you use them.  When you have more than
one word in the same program, the word which is listed *last* is the one exe-
cuted, and all the ones listed before it are subroutines.  The above program
could be rewritten:

: sylia-identity
        #2032
;

: far_vision
        sylia-identity dup
        name " is currently in " strcat
        swap location name
        "." strcat strcat                   (Now we know where she is.)

        me @ swap notify

        #2055
        location sylia-identity dbcmp (Using sylia-identity and spacing the )
                                      (commands like this makes this bit a  )
                                      (little easier to understand.         )

        if me @ "Watch out-- she's wearing her hardsuit!" notify
        then
;


If you wanted to use standard library functions, you could rewrite the
program again.  For instance, the pmatch library function gives the database
reference to a specific player; the first function could have been written as

: sylia-identity
        "Sylia" .pmatch
;
&
quickref
       The MUF Cheat-Sheet, as seen by Sammael (Arthur, The., etc)
                     (Modified by Jiro/Mizue 7/24/92)
                                  -or-
             Reference manual for MUCK Forth ("MUF")  -terse

ENTERING EDITING MODE
        @prog <program name>    (creates a new program if none match)
        @edit <program name or number>

EDITING COMMANDS
        <number> i                              insert before <number>
        .                                       exit insert mode
        c                                       compile
        <number1> <number2> l                   list
        <number1> <number2> d                   delete
        <letter> <letter>   a                   show macros (abridged)
        <letter> <letter>   s                   show macros (long)
        def <name> <body>                       define macro
        <name> k                                delete macro
        <program#> v                            view program header
        h                                       help on edit mode
        u                                       uncompile
        q                                       quit editor mode

PRIMITIVE TERMINOLOGY

        v       (example: me, varname)          type variable
        d       (example: #0, #-1, #333)        type dbref
        i       (example: 1, 2, 3, -100)        type int (boolean)
        s       (example: "", "string")         type string
        a       (example: 'functionname)        type address (word)
        c       (not in all mucks; untypeable)  type connection
	x, y					any of these

SYNTAX

        ( ... )                           commments
        :                                 begin user-def word
        ;                                 end user-def word
        var <VARNAME>                     variable declaration

        if              ( i -- )
        else            ( -- )
        then            ( -- )
        exit            ( -- )
        execute         ( a -- ??? )
        pop             ( x -- )
        dup             ( x -- x x )
        swap            ( x y -- y x )
        over            ( x y -- x y x )
        rot             ( x y z -- y z x )
        rotate          ( ni ... n1 i -- n(i-1) ... n1 ni )
        pick            ( ni ... n1 i -- n1 ni )
        put             ( ni ... n1 x i -- x ... n1 )
        depth           ( -- i )

        !               ( x v -- )        store value x in var v,
                                          value may be any type data
        @               ( v -- x )        fetch value x from var v
        atoi            ( s -- i )        string --> integer
        intostr         ( i -- s )        integer || dbref --> string
        dbref           ( i -- d )        integer --> dbref
        int             ( x -- i )        VAR || object --> integer
        variable        ( i -- v )        integer --> VAR ref

        prog            ( -- d )          current program
        self            ( -- a )          address of current function
        dbtop           ( -- d )          top of database

        + - * / %       ( i1 i2 -- i )          
        < > = <= >=     ( i1 i2 -- i )
        strcmp, stringcmp
                        ( s1 s2 -- i )    strcmp == case sensitive
        strncmp, stringncmp
                        ( s1 s2 n -- i )  compares only n letters
        number?         ( s -- i )
        dbcmp           ( d1 d2 -- i )
        and  or         ( i1 i2 -- i )
        not             ( i -- i' )

        strlen          ( s -- i )
        strcat          ( s1 s2 -- s )
        instr           ( s1 s2 -- i )    finds string s2 within s1
        strcut          ( s i -- s1 s2 )  cuts string at position i
        explode         ( s1 s2 -- ... i )s2 is the partition, len >0
        subst           ( s1 s2 s3 -- s ) string, replacement, tobesub
        pronoun_sub     ( d s -- s' )     does % subs a la osucc/ofail

        read            ( -- s )
        notify          ( d s -- )        player, message 
        notify_except   ( d1 d2 s -- )    place, player, message 
        pennies         ( d -- i )
        addpennies      ( d i -- )        player, pennies
        random          ( -- i )

        getpropdbref    ( d s -- d )      #-1 if none
        getpropstr      ( d s -- s )      "" if none
        getpropval      ( d s -- i )      zero if none
        addprop         ( d s1 s2 i -- )  ignores i unless s2 is ""  [obsolete]
        setprop         ( d s x -- )      sets string, int, or dbref
        remove_prop     ( d s -- )

        name, desc, succ, fail, drop, osucc, ofail, odrop
                        ( d -- s )        retrieve message

        setname, setdesc, setsucc, setfail, setdrop, setosucc, setofail,
        setodrop        ( d s -- )        set message

        player?, thing?, room?, program?, exit?, ok?
                        ( d -- i )        boolean

        location        ( d -- d' )
        owner           ( d -- d' )
        moveto          ( d1 d2 -- )      moves d1 to d2
        check_moveto    ( d1 d2 -- s )    null, or error string if not movable
        set             ( d s -- )        object, string (flag)
        flag?           ( d s -- i )      object, string, boolean
        call            ( d -- ??? )      call remote program
        match           ( s -- d )        thing, dbref (#-1 = NOTHING,
                                                 #-2 = AMBIGUOUS, #-3 = HOME)
        rmatch          ( d s -- d )      object, thing, dbref           
        copyobj         ( d -- d' )       returns dbref of new object
        contents        ( d -- ... i )    returns stack of dbrefs and i

        systime         ( -- i )          seconds since January 1, 1970
        strftime        ( i s -- s1 )     formats time according to string

        online          ( -- d d ... i )
                                          returns list of and number of users
        awake?          ( d -- i )        returns number of connections
 
        [ the connection primitives are optional ]
        connections     ( -- c c ... i )
                                          returns list of/number of connections
        concount        ( -- i )          returns number of connections
        conidle         ( c -- i )        idle time, in seconds
        contime         ( c -- i )        when connected
        condbref        ( c -- d )        player corresponding to connection
        conhost         ( c -- s )        host name (wiz-only)
        conboot         ( c -- )          boots player (wiz-only)