fbmuck-6.05/auto/
fbmuck-6.05/contrib/jresolver/
fbmuck-6.05/contrib/jresolver/org/
fbmuck-6.05/contrib/jresolver/org/fuzzball/
fbmuck-6.05/docs/devel/
fbmuck-6.05/game/
fbmuck-6.05/game/logs/
fbmuck-6.05/game/muf/
fbmuck-6.05/scripts/
fbmuck-6.05/src_docs/
                  MUF Reference Manual for FBMuck 6.00
                   by Revar Desmera <revar@belfry.com>




----------------------------------------------------------------------------
                          Details and Definitions
----------------------------------------------------------------------------




Mucker Levels:
  
  There are now four levels of MUCKERs in fb4.0.  Level zero is a
non-mucker. They cannot use the editor, and MUF programs owned by them
cannot be run.
  
  Level one MUCKER's are apprentices.  Their powers are restricted as they
cannot get information about any object that is not in the same room they
are.  ie:  OWNER, NAME, LOCATION, etc all fail if the object isn't in the
same room as the player.  Level one MUCKER programs always run as if they
are set SETUID.  NOTIFY, NOTIFY_EXCEPT, and NOTIFY_EXCLUDE will refuse to
send messages to rooms the user is not in.  Level one programs cannot use
ADDPENNIES.  Level one programs don't list DARK objects or rooms in the
contents of a room, unless they are controlled by the program owner.
Additionally, level one programs have an absolute instruction limit that
is the same size as the PREEMPT instruction limit.  This is usually
around 20,000 instructions.
  
  Level two MUCKERs are also called Journeymen.  Their permissions are
equivalent to the permissions for a normal MUCKER under older versions
of the server.  Level two programs can run as many as four times the
number of instructions that a preempt program could.  This is usually
around 80,000 instructions.
  
  Level three MUCKERs are referred to as Masters.  They can use the con-
nection info primitives (ie: CONDBREF, ONLINE, etc.), read the EXITS list
of any room, use NEXTPROP on objects, can use NEWROOM, NEWOBJECT, NEWEXIT,
and COPYOBJ without limitations, can use QUEUE and KILL, and can override
the permissions restrictions of MOVETO.  You only give a player MUCKER
level 3 if they are very trusted.  There is no absolute instruction count
limit for level three or above, except for programs running in PREEMPT mode.
  
  A player who is wizbitted is effectively Mucker Level 4.  MUCKER level
four is required for the RECYCLE primitive, the CONHOST primitive, the
FORCE primitive, and the SETOWN primitive.  ML4 also allows overriding
of permissions of the SET* primitives, and property permissions.  Props
not listed by NEXTPROP with ML3 are listed with ML4.  Programs running
ML4 do not even have instruction limits on PREEMPT mode programs.
  
  The MUCKER level permissions that a program runs at is the lesser of
it's own MUCKER level and the MUCKER level of it's owner.  If it is
owned by a player who is MUCKER level 2, and it is MUCKER level 3,
then it runs at Mucker level 2.  The one exception to this is programs
owned by a Wizard player.  They run at Mucker level 2 if the program
itself is not wizbit, and at Mucker level 4 if the program IS set wizbit.
  
  Mucker level is referred to in flags lists by M# where the # is the
Mucker level.  Level zero objects don't show a flag for it.  Example:
    Revar(#37PM3)
  In verbose flags lists, Mucker levels greater than zero are shown
by MUCKER# where # is the mucker level.
  
  To set a level on a player or program, use the level number as the
flag name.  MUCKER is the same as 2, and !MUCKER is the same as 0.
Example:
    @set Revar=2
  A player may set the MUCKER level on a program they own to any level
lower than or equal to their own level, and a wizard may set a program
or player to any MUCKER level.  When a program is created, it is
automatically set to the same MUCKER level as the creating player.
When a program is loaded from an old db, if it is Mucker Level 0,
it is upgraded to Mucker Level 2.


Multitasking:

  There are 3 modes that a program can be in when running:  foreground,
background, and preempt.  A program running in the foreground lets other
users and programs have timeslices (ie multitasking), but blocks input
from the program user.  Background mode allows the user to also go on and
do other things and issue other commands, but will not allow the program
to do READs.  Preempt mode means that the program runs to completion
without multitasking, taking full control of the interpreter and not
letting other users or progs have timeslices, but imposes an instruction
count limit unless the program is a wizard program.

  Programs run by @locks, @descs, @succs, @fails, and @drops default to the
preempt mode when they run.  Programs run by actions linked to them
default to running in foreground mode.  QUEUEd program events, such as
those set up by _listen, _connect, _disconnect, etc, and those QUEUEd by
other programs default to running in background mode. (NOTE: these
programs cannot be changed out of background mode)


Libraries:

How to use a library:
    1) Use "@register lib" to list what libraries exist.
    2) Use "@view $lib/<libraryname>" to list the docs on that library.
    3) When you've found the library and the function you want, then all
        you have to do in your program is, at the beginning of it,
        $include $lib/<libraryname>
        then just use the function name to invoke it later in your program
        and it will run as if it were a function in your program.

How to make a library:
    1) Create a program with several useful generic subroutines.
    2) DOCUMENT those subroutines in a commented out header in the prog.
    3) @set <program>=_docs:<command to list those DOCS you made>
    4) Set the version number of the code in the library with $version 1.000
        This lets you keep track of the code revision installed, separately
        from the version of the library calling API.
    5) Set the library API version number with $lib-version 1.000
        This is the version of the calling interface for this library.
        Remember to up this version when you change this library's calls.
        Remember that 1.19 is less than 1.2, so use numbers like 1.002.
    6) For each function you want to be externally callable, do the following:
        a) Declare it PUBLIC
        b) Create the caller macro with either:
            $libdef FUNCNAME     or
            $pubdef EXPORTEDNAME "$lib/THISLIB" match "FUNCNAME" call
    7) Make sure the program is set LINK_OK and VIEWABLE.
    8) Globally register the program with the @register command with a
        prefix of "lib/".  ie: @reg lib-strings.muf=lib/strings
    9) You're done!

Currently standard libraries:
    $lib/strings      Functions for manipulating strings.
    $lib/props        Routines for searching for properties, or setting them.
    $lib/lmgr         Standard list manager routines.
    $lib/stackrng     Routines to handle variable sized ranges on the stack.
    $lib/edit         String range editing and manipulation routines.
    $lib/editor       Standard user text editor.
    $lib/mesg         Standard message manager routines.
    $lib/mesgbox      Routines for handling lists of messages.
    $lib/match        Object or string matching routines.
    $lib/reflist      Dbref-list management routines.
    $lib/index        Hashed linked list manager with partial key matching.
    $lib/gui          Routines to make MCP's GUI package easier to use.
    $lib/optionsgui   Given datums, auto-generates a GUI to edit them.


Flags that have importance to MUF:

  If a program is set DARK (DEBUG), then when it is run, it will print out
a stack trace for each instruction executed, to the player running the
program.  This is useful for debugging programs.

If a program is set ZOMBIE, then when the owner runs it, they will enter an
interactive debugger, useful for following a program as it runs and
changing it to see what different situations do.

On dbload, if a program is set ABODE (AUTOSTART), *AND* it is owned by
a wizard, then it will be placed in the timequeue with a delay of 0 and
a string parm of "Startup".  Autostart programs run with the location
NOTHING (#-1) rather than the location of the owner of the program.

If a program has the HAVEN flag set on it (HARDUID) then it runs with
the uid and permissions of the owner of the trigger of the program.
If the program is a timequeue event with trigger of #-1, then it
will run with the permissions and uid of the program owner as in SETUID.

If a program is set both SETUID and HARDUID, and it is owned by a wizard,
then it inherits the uid and mucker level of the program that called it.
If it was not called by a program, then it runs SETUID.  This is useful
for writing libraries.

Programs set BUILDER (BOUND) run in preempt mode, regardless of the mode
of the program.  ie: a foreground program, while running in a program set
BOUND, will run pre-empt, with the multitasking effectively shut off.

A program that is set WIZARD ignores almost all permissions checking.

The Mucker Level of the program also has a great deal of influence on what
a program can and cannot do.  See MUCKER LEVELS for more information.


Compilation:

  Programs are compiled when they are run or called, or when explicitly
compiled in the editor.  They are compiled with the uid of the owner of
the program.  After being unused for a number of minutes, programs will
be removed from memory until needed again.


Listeners:

  When a message is notify_except'ed or notify_exclude'ed to a room, and
LISTENERS and LISTENERS_ENV are defined, then it will run ALL the programs
referred to in all the _listen properties down the environment tree,  And
in all of the objects in the room with LISTENERS_OBJ defined.  Also, the
muf NOTIFY primitive was changed to run the _listen program on an object
or player if a message is sent to them that way.


Connect and Disconnect Propqueues:

  A room or player may have a "_connect" property set that contains the
dbref of a program to run when a player connects.  The program must be
either link_ok or must be owned by the player connecting.  When the
program is run, the string on the stack will be "Connect", the "loc @"
will be the location of the connecting player, the "me @" will be the
connecting player, and the "trigger @" (and "trig") will be the object
that had the _connect property on it.  All programs referred to by
_connect properties on the player, and on rooms down the environment tree
from the player, will be run.  When a player disconnects, programs referred
to by _disconnect properties will be run in a similar manner.
(connect and disconnect _actions_ are also triggered.)


Arrive and Depart Propqueues:

  Programs referred to by props in _depart/_arrive propdirs will all be
run when a player leaves or enters a room, respectively. An example would
be _arrive/announce:1234  That would queue up program #1234 when a player
enters a room.  The name ("announce") is not important, and can be anything
you want, but they are run in alphabetic order.





----------------------------------------------------------------------------
                       Macros and Compiler Directives
----------------------------------------------------------------------------




__FUZZBALL__

  A pre$defined macro that contains the value 1 on a FuzzBall Muck server.
This is useful for server-type specific $ifdefs, when code needs to be
different on, say, FuzzBall Mucks and ProtoMucks.  For example:
    $ifdef __fuzzball__
        me @ "This is a FuzzBall Muck server.!" notify
    $endif


__MUCKNAME

  A pre$defined macro that contains the name of the server's muckname @tune
parameter value.  This is useful for muck specific $ifdefs.  For example:
    $ifdef __muckname=FurryMUCK
        me @ "Helloooooo Furry!" notify
    $endif


__VERSION

  A pre$defined macro that contains the current server version.  Contains
the same string that the VERSION primitive returns.  This is mainly useful
in $ifdef/$ifndef comparisons.  The value of this will always start with
'Muck2.2fb' for historical reasons, followed by the current fbmuck server
version.  Ie: Muck2.2fb6.00 for the 6.00 fbmuck server.


MAX_VARIABLE_COUNT

  A pre$defined macro that expands to the maximum number of variables of
each type allowed in a program.  For function-scoped variables, this is the
max number of scoped vars that each function may have.


$AUTHOR <rest_of_line>

  Sets the _author string property on the program to <rest_of_line>.
The preferred format is an email address with name comment. ie:
    $author Revar Desmera <revar@belfry.com>
To denote multiple authors, separate them with commas.  ie:
    $author Revar Desmera <revar@belfry.com>, Foxen <foxen@belfry.com>
If you don't want to include your email address, just omit it.  ie:
    $author Revar, Foxen


$VERSION <float>

  Sets the _version string property on the program to <float>.  Version
numbers should be like 1.009 and 1.010, so that they can be compared using
floating point comparisons.  (Remember, 1.9 is greater than 1.10.)


$LIB-VERSION <float>

  Sets the _lib-version string property on the program to <float>.  Version
numbers should be like 1.009 and 1.010, so that they can be compared using
floating point comparisons.  (Remember, 1.9 is greater than 1.10.)


$NOTE <rest_of_line>

  Sets the _note string property on the program to <rest_of_line>.


$DEFINE <defname> <definition> $enddef

  Basically the same as C's #define <defname> <definition>


$DEF <defname> <definition>

  This is the same as $define, except that the definition stops at the end
of the program line, without using an ending $enddef.


$UNDEF <defname>

  About the same as C's #undef <defname>


$INCLUDE $<libname>
$INCLUDE <dbref>

  Sets a bunch of $defines from the properties in the /_defs/ propdir of the
given program.  For example, if object #345 had the following properties:
    /_defs/desc: "_/de" getpropstr
    /_defs/setpropstr: dup if 0 addprop else pop remove_prop then
    /_defs/setpropval: dup if "" swap addprop else pop remove_prop then
    /_defs/setprop: dup int? if setpropval else setpropstr then
then if a program contained '$include #345' in it, then all subsequent
references to 'desc', 'setpropstr', 'setpropval', and 'setprop' would
be expanded to the string values of their respective programs.  For example,
'desc' would be replaced throughout the program with '"_/de" getpropstr'
NOTE:  You cannot have a slash in a definition name.  ie: The property
    _defs/a/b:foo
will NOT make a definition named a/b.


$PUBDEF :
$PUBDEF <defname>
$PUBDEF <defname> <rest_of_line>
$PUBDEF \<defname> <rest_of_line>

  By using this directive, the _defs/ directory on a MUF program can
be set at compile time.

$pubdef :                          Clears the _defs/ propdir on the program.
$pubdef <defname>                  Clears the _defs/<defname> prop on the prog.
$pubdef <defname> <rest_of_line>   Sets _defs/<defname> prop to <rest_of_line>.
$pubdef \<defname> <rest_of_line>  Sets _def/<defname> if not already set.

For example:
    $pubdef tell me @ swap notify
would put a property named '_defs/tell' on the program object, with the
value 'me @ swap notify'.  Def names cannot have ':' nor '/' in them.


$LIBDEF <function>
$LIBDEF \<function>

  Sets up an _defs/ prop on the program to call the specified function.
For example:
    $libdef myfunc
would put a prop named '_defs/myfunc' on the program object, with the
value '<this_programs_dbref> "myfunc" call'


$CLEARDEFS [ALL]

  Ignores program _defs/ when compiling the program. Wizards programs can
use '$cleardefs ALL' to also ignore #0 _defs/ when compiling. This does
not affect macros, and internal _defs/ are always loaded no matter what.


$IFDEF <condition> <compile if true> $endif
$IFDEF <condition> <compile if true> $else <compile if false> $endif

  This determines whether or not to compile optional sections of code,
depending on the existence of or value of certain $defined names.
The four accepted forms of the <condition> argument are:
    DEFNAME        Is true if DEFNAME was $defined earlier, whatever the value.
    DEFNAME=VALUE  Is true if DEFNAME exists and its value equals VALUE.
    DEFNAME>VALUE  Is true if DEFNAME exists and is greater than VALUE.
    DEFNAME<VALUE  Is true if DEFNAME exists and is less than VALUE.

  The semantics of greater than and less than is the same as that used by
the strcmp string comparison command.  There must be no spaces between the
DEFNAME, comparator, and VALUE.  They must be run together as one word.

  There is no >= or <= comparator available, so to make such a comparison
you need to use $ifndef with the opposite comparator.  Ie, to check if
FOO is greater than or equal to 3, use:
    $ifndef FOO<3
        BAR
    $enddef

Compiler directives are nestable also.  For examples:
    $ifdef __version>Muck2.2fb3.5
        $def envprop .envprop
    $endif
    $define ploc
        $ifdef proplocs
            .proploc
        $else
            owner
        $endif
    $enddef


$IFNDEF <condition> <compile if false> $endif
$IFNDEF <condition> <compile if false> $else <compile if true> $endif

  This determines whether or not to compile optional sections of code,
depending on the non-existence of or value of $defined names.  $ifndef is
short for 'If NOT Defined' or 'If Not', so it compiles the first code
branch (before the optional $else), only if the <condition> is false.
The four accepted forms of the <condition> argument are:
    DEFNAME        Is true if DEFNAME was $defined earlier, whatever the value.
    DEFNAME=VALUE  Is true if DEFNAME exists and its value equals VALUE.
    DEFNAME>VALUE  Is true if DEFNAME exists and is greater than VALUE.
    DEFNAME<VALUE  Is true if DEFNAME exists and is less than VALUE.

The semantics of greater than and less than is the same as that used by the
strcmp string comparison command.  There must be no spaces between the
DEFNAME, comparator, and VALUE.  They must be run together as one word.


$IFVER this <float> <truebranch> $endif
$IFVER this <float> <truebranch> $else <falsebranch> $endif
$IFVER $<libname> <float> <truebranch> $endif
$IFVER $<libname> <float> <truebranch> $else <falsebranch> $endif
$IFVER <dbref> <float> <truebranch> $endif
$IFVER <dbref> <float> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the $version of the given program, which is stored in its
'_version' property.  In the form '$ifver this' then this checks this
compiling program's $version.  Otherwise, this checks the $version of
the program referenced by $regname or #dbref.
  The <truebranch> will be compiled if the given program's $version
is greater than or equal to the given <float>, using a floating point
number comparison.  Otherwise, the <falsebranch>, if given, will be
compiled.


$IFNVER this <float> <truebranch> $endif
$IFNVER this <float> <truebranch> $else <falsebranch> $endif
$IFNVER $<libname> <float> <truebranch> $endif
$IFNVER $<libname> <float> <truebranch> $else <falsebranch> $endif
$IFNVER <dbref> <float> <truebranch> $endif
$IFNVER <dbref> <float> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the $version of the given program, which is stored in its
'_version' property.  In the form '$ifnver this' then this checks this
compiling program's $version.  Otherwise, this checks the $version of
the program referenced by $regname or #dbref.
  The <truebranch> will be compiled if the given program's $version
is less than the given <float>, using a floating point number comparison.
Otherwise, the <falsebranch>, if given, will be compiled.


$IFLIBVER this <float> <truebranch> $endif
$IFLIBVER this <float> <truebranch> $else <falsebranch> $endif
$IFLIBVER $<libname> <float> <truebranch> $endif
$IFLIBVER $<libname> <float> <truebranch> $else <falsebranch> $endif
$IFLIBVER <dbref> <float> <truebranch> $endif
$IFLIBVER <dbref> <float> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the $lib-version of the given program, which is stored in its
'_lib-version' property.  In the form '$iflibver this' then this checks this
compiling program's $lib-version.  Otherwise, this checks the $lib-version
of the program referenced by $regname or #dbref.
  The <truebranch> will be compiled if the given program's $lib-version
is greater than or equal to the given <float>, using a floating point
number comparison.  Otherwise, the <falsebranch>, if given, will be
compiled.


$IFNLIBVER this <float> <truebranch> $endif
$IFNLIBVER this <float> <truebranch> $else <falsebranch> $endif
$IFNLIBVER $<libname> <float> <truebranch> $endif
$IFNLIBVER $<libname> <float> <truebranch> $else <falsebranch> $endif
$IFNLIBVER <dbref> <float> <truebranch> $endif
$IFNLIBVER <dbref> <float> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the $lib-version of the given program, which is stored in its
'_lib-version' property.  In the form '$ifnlibver this' then this checks this
compiling program's $lib-version.  Otherwise, this checks the $lib-version
of the program referenced by $regname or #dbref.
  The <truebranch> will be compiled if the given program's $lib-version
is less than the given <float>, using a floating point number comparison.
Otherwise, the <falsebranch>, if given, will be compiled.


$IFLIB $<libname> <truebranch> $endif
$IFLIB $<libname> <truebranch> $else <falsebranch> $endif
$IFLIB <dbref> <truebranch> $endif
$IFLIB <dbref> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the existence of a given program.
  The <truebranch> will be compiled if the given object exists and is a
program.  Otherwise, the <falsebranch>, if given, will be compiled.


$IFNLIB $<libname> <truebranch> $endif
$IFNLIB $<libname> <truebranch> $else <falsebranch> $endif
$IFNLIB <dbref> <truebranch> $endif
$IFNLIB <dbref> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the existence of a given program.
  The <truebranch> will be compiled if the given object does not exist, or
if it is not a program.  Otherwise, the <falsebranch>, if given, will be
compiled.


$IFCANCALL this <publicname> <truebranch> $endif
$IFCANCALL this <publicname> <truebranch> $else <falsebranch> $endif
$IFCANCALL $<libname> <publicname> <truebranch> $endif
$IFCANCALL $<libname> <publicname> <truebranch> $else <falsebranch> $endif
$IFCANCALL <dbref> <publicname> <truebranch> $endif
$IFCANCALL <dbref> <publicname> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the ability for the compiling program to call a given public
function on a given program.
  If the given program is given as 'this', then this will check if the
given callable function was declared earlier in this compiling program.
  The <truebranch> will be compiled if the given program exists, is a
program, and has a given callable function (declared with PUBLIC or WIZCALL)
that this compiling program has permission to call.  Otherwise, the
<falsebranch>, if given, will be compiled.


$IFNCANCALL this <publicname> <truebranch> $endif
$IFNCANCALL this <publicname> <truebranch> $else <falsebranch> $endif
$IFNCANCALL $<libname> <publicname> <truebranch> $endif
$IFNCANCALL $<libname> <publicname> <truebranch> $else <falsebranch> $endif
$IFNCANCALL <dbref> <publicname> <truebranch> $endif
$IFNCANCALL <dbref> <publicname> <truebranch> $else <falsebranch> $endif

  This determines whether or not to compile optional sections of code,
depending on the ability for the compiling program to call a given public
function on a given program.
  If the given program is given as 'this', then this will check if the
given callable function was declared earlier in this compiling program.
  The <truebranch> will be compiled if the given program does not exist,
is not a program, or does not have a given callable function (declared with
PUBLIC or WIZCALL) that this compiling program has permission to call.
Otherwise, the <falsebranch>, if given, will be compiled.


$ECHO <string>
  Echos the given string to the screen of the person compiling the program.
Runs at compile-time.


$ABORT <message>
  Aborts compiling and prints out the error message.


$PRAGMA <pragmatype> [<args>]
  Sets a compiler option in a backwards compatible manner.  If the pragmatype
isn't recognized, the compiler will just ignore this line and continue its
compile attempt.  The $pragma directive must be all on one line, and the
entire rest of the line after the pragmatype is assumed to be arguments for
that pragmatype.  The currently supported pragmatypes are:

COMMENT_STRICT
  This specifies that comments are in the old style that is terminated by the
first end-paren ')' in the comment.

COMMENT_RECURSE
  This specifies that comments are in the new recursive style where any parens
'(' in a comment must be matched by end-parens ')'.

COMMENT_LOOSE
  This is the default comment style, where the compiler tries to compile
comments as if in comment_recurse mode, but will fall back to comment_strict
mode if a comment fails to have balancing parens.


Escaping Literal Tokens:

  You can escape a token in MUF so that it will be interpreted literally.
ie:  \.pmatch will try to compile '.pmatch' without expanding it as a
macro.  This lets you make special things with $defines such as:
    $define addprop over over or if \addprop else pop pop remove_prop $enddef
so that all the 'addprop's in the program will be expanded to the
definition, but the 'addprop' in the definition will not try to expand
recursively.  It will call the actual addprop.





----------------------------------------------------------------------------
                        Stack Manipulation Operators
----------------------------------------------------------------------------




POP ( x -- )

  Pops the top of the stack into oblivion.


POPN ( ?n..?1 i -- )

  Pops the top i stack items.


DUP ( x -- x x )

  Duplicates the item at the top of the stack.


DUPN ( ?n..?1 i -- ?n..?1 ?n..?1 )

  Duplicates the top i stack items.


LDUP ( {?} -- {?} {?} )

  Duplicates a stackrange on top of the stack.


SWAP ( x y -- y x )

  Takes objects x and y on the stack and reverses their order.


OVER ( x y -- x y x )

  Duplicates the second-to-top thing on the stack.  This is the same as 2 pick.


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.  Using a negative rotational
value rotates backwards.
Examples:
    "a"  "b"  "c"  "d"  4  rotate
would leave
    "b"  "c"  "d"  "a"
on the stack.
    "a"  "b"  "c"  "d"  -4  rotate
would leave
    "d"  "a"  "b"  "c"
on the stack.


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 dup, and 2 pick is equivalent to over.


PUT ( nx...n1 ni i -- nx...ni...n1 )

  Replaces the i'th item from the top of the stack with the value of ni.
The command sequence '1 put' is equivalent to 'swap pop'.
Example:
    "a"  "b"  "c"  "d"  "e"  3  put
would return on the stack:
    "a"  "e"  "c"  "d"


REVERSE ( ?n..?1 i -- ?1..?n )

  Reverses the order of the top i items on the stack.
Example:
    "a"  "b"  "c"  "d"  "e"  4  reverse
would return on the stack:
    "a"  "e"  "d"  "c"  "b"


LREVERSE ( ?n..?1 i -- ?1..?n i )

  Reverses the order of the top i stack items, leaving i.
Example:
    "a"  "b"  "c"  "d"  "e"  4  lreverse
would return on the stack:
    "a"  "e"  "d"  "c"  "b"  4


DEPTH ( -- i )

  Returns the number of items currently on the stack.


{  ( -- marker)

  Pushes a marker onto the stack, to be used with } or }list or }dict.


}  ( marker ?n ... ?1 -- ?n ... ?1 i )

  Finds the topmost marker in the stack, and counts how many stack items
are between it and the top of the stack.  The marker is removed from the
stack, and the count is pushed onto the stack.





----------------------------------------------------------------------------
                       Variables and Handling Thereof
----------------------------------------------------------------------------




ME @

  There is a global variable named ME that contains the dbref of the
player who invoked the program.  The value of this variable is not
guaranteed to be secure, as another program could change the value of
ME then call your program.  If you must be certain that the value of
the ME variable is correct, use the commands:
    "me" match me !
The ME global variable is the same variable as '0 variable'


LOC @

  There is a global variable named LOC that contains the dbref of the
location of the player who invoked the program.  The value of this
variable is not guaranteed to be secure, as another program could change
the value of LOC then call your program.  If you must be certain that
the value of the LOC variable is correct, use the commands:
    "me" match location loc !
The LOC global variable is the same variable as '1 variable'


TRIGGER @

  There is a global variable named TRIGGER that contains the dbref of the
trigger object that invoked the process.  The value of this variable is
not guaranteed to be secure, as another program could change the value of
TRIGGER then call your program.  If you must be certain that the value of
the TRIGGER variable is correct, use the commands:
    trig trigger !
The TRIGGER global variable is the same variable as '2 variable'
The value of TRIGGER will be #-1 for AUTOSTART programs,


COMMAND @

  There is a COMMAND variable, similar to ME, LOC, and TRIGGER, except that
it contains a string.  The string contains the command the user typed
that triggered the the program, without the command line arguments.  ie:
if there was an exit named "abracadabra;foo bar;frozzboz" that was linked
to the program, and the user typed in "foo bar baz", then the program
would run with "baz" on the stack, and "foo bar" in the global COMMAND
variable.  The TRIGGER global variable is the same variable as '2 variable'


VAR <name>

  When used inside a function, a function-scoped variable is created.
This variable is local to each invocation of a given function; recursive
calls each get their own scoped variable dataspace.  This variable type
is analogous to C's function-scoped variables.  The use of function-scoped
variables is highly recomended to make functions more readable.

  When used outside of a function, the compiler allows the use of <name>
as a global variable in all functions defined after the var declaration.
This variable dataspace is shared between ALL muf programs called in
this process.  This means that if program A declares a global variable,
then calls program B, and program B also declares a global variable,
then changes its value, then the global variable declared in program A
will also have been changed.  For this reason, this usage of VAR is
deprecated and shoud NOT be used.  Use LVAR instead.  This usage is only
kept around for backwards compatability with some old icky programs that
used this feature to pass data between some programs.


VAR! <name>

  This must be used within a function.  It declares a function-scoped
variable named <name> that then has its value set to the topmost stack
item.  For example, the following program prints out "Hello World!":
    : myfunction
        "Hello World!" var! foo
        me @ foo @ notify
    ;


LVAR <varname>

  This declares a variable as a program-local variable.  If another program
calls this program, the values of the program-local variables will not be
changed in the calling program, even if the called program changes them.
This variable will be available to all functions defined later in the
program, after the lvar declaration.  This variable's data is persistent
within this process.  Ie: if program A calls program B, and program B sets
the value of this program-local variable, then returns to A, which then
calls B again, the value of this variable will still have the value it was
set to in the first call.  The value is NOT persistent between different
processes.  This variable type is analogous to C's global variables.


@ ( v -- x )

  Retrieves variable v's value x.


! ( x v -- )

  Sets variable v's value to x.


VARIABLE ( i -- v )

  Converts integer i to global variable reference v. Of the pre-defined
variables, `me' corresponds to integer 0, `loc' to 1, `trigger' to 2,
and 'command' to 3.
Thus:
    me @
and
    0 variable @
will do the same thing (returning the user's dbref). User-defined variables
are numbered sequentially starting at 4 by the compiler. Note that these
variable numbers can be used even if variables have not been formally
declared.  This command has been deprecated, and is not recommended to use.
It's original purpose was to allow MUF to do small arrays.  Since MUF now
has an intrinsic array stack item type, this should no longer be used.


LOCALVAR (i -- l)

  Takes an integer and returns the respective program-local variable.
Similar to the 'variable' primitive.  Use of this command is deprecated
and is not recommended.  Use the array stack item type instead.





----------------------------------------------------------------------------
                             Logical Operators
----------------------------------------------------------------------------




<  ( n1 n2 -- i )

  Compares two numbers and returns 1 if n1 is less than n2, and 0 otherwise.


>  ( n1 n2 -- i )

  Compares two numbers and returns 1 if n1 is greater than n2, and 0 otherwise.


=  ( n1 n2 -- i )

  Compares two numbers and returns 1 if n1 is equal to n2, and 0 otherwise.


<= ( n1 n2 -- i )

  Compares two numbers and returns 1 if n1 is less than or equal to n2,
and 0 otherwise.


>= ( n1 n2 -- i )

  Compares two numbers and returns 1 if n1 is greater than or equal to n2,
and 0 otherwise.


NOT ( x -- i )

  Returns true (1) if the top stack item is considered false.  Returns
false (0) otherwise.  The stack item can be of any type.  For the various
types, here are their false values:
    Integer      0
    Float        0.0
    DBRef        #-1
    String       ""


AND ( x1 x2 -- i )

  Returns true (1) if both of the top two stack items are considered true.
Returns false (0) otherwise.  The stack items can be of any type.  For the
various types, here are their false values:
    Integer      0
    Float        0.0
    DBRef        #-1
    String       ""


OR ( x1 x2 -- i )

  Returns true (1) if either of the top two stack items are considered true.
Returns false (0) otherwise.  The stack items can be of any type.  For the
various types, here are their false values:
    Integer      0
    Float        0.0
    DBRef        #-1
    String       ""


XOR ( x1 x2 -- i )

  Returns true (1) if either of the top two stack items are considered true,
but NOT both of them.  Returns false (0) otherwise.  The stack items can be
of any type.  For the various types, here are their false values:
    Integer      0
    Float        0.0
    DBRef        #-1
    String       ""


STRING? ( x -- i )

  Returns true if x is a string.


INT? ( x -- i )

  Returns true if x is a int.


FLOAT? ( ? -- i )

  Returns true if the item on the stack is a floating point value.


DBREF? ( x -- i )

  Returns true if x is a dbref.


ARRAY? ( ? -- i )

  Tests if stack item is an array.  Returns i as 1 if so, 0 if
otherwise.


DICTIONARY? ( ? -- i )

  Tests if stack item is an array of dictionary type.  Returns i as 1
if so, 0 if otherwise.


ADDRESS? (? -- i)

  Returns true if the top stack item is a function address.


LOCK? (? -- i)

  Returns true if the top stack item is a lock.





----------------------------------------------------------------------------
                        Execution Control Structures
----------------------------------------------------------------------------




IF (x -- ) ... THEN
IF (x -- ) ... ELSE ... THEN

  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 continues 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.


IF (x -- ) ... ELSE ... THEN

  Begins an ELSE block in an IF-ELSE-THEN code block.  If the value
tested by the IF is false, then this code block will be executed.


IF (x -- ) ... THEN
IF (x -- ) ... ELSE ... THEN

  Denotes the end of an IF-THEN or IF-ELSE-THEN code block.


'FUNCNAME ( -- a )

  Pushed the address of the start of the previously defined function
FUNCNAME onto the stack.  This can be useful for use with EXECUTE and
arrays to make a list of functions you can call by index, or for making
function callbacks.


EXECUTE ( a -- ?? )

  Executes the function pointed to by the address a on the stack.
This function does NOT need to be in the same program as the function
that did the EXECUTE.


JMP (a -- )

  The JMP primitive takes an address like those supplied by 'funcname and
moves execution to that point.  It's one early way that was used to do
tail-recursion loops without as much overhead, and without failing due to
system stack overflows.  It's mostly obsolete now, except that it's one
of the three or four internal primitives used to implement IF-ELSE-THEN and
BEGIN-WHILE-REPEAT loops and such.  You shouldn't use JMP explicitly in
in modern MUF code, as it is deprecated.  NOTE: Using JMP to jump into a
different function can have problems, and is not recommended.

Example of JMP as a tail-recursion optimization:
    : countforever ( i -- )
        1 +
        dup intostr .tell
        'countforever jmp
    ;

A better ways to do the same thing with looping primitives would be:
    : countforever ( i -- )
        begin
            1 +
            dup intostr .tell
        repeat
    ;


CALL ( d -- ?? )
CALL ( d s -- ?? )

  Calls another program d.  Program d will inherit the values of ME, LOC,
TRIGGER, and all other global variables.  If used in the second form,
this will call the named PUBLIC function s in the given program d.
The called program will NOT share the same localvars as the caller,
unless the caller is calling itself.


INTERP ( d1 d2 s -- ? )

  Takes a program dbref to run d1, the trigger to use d2, and the top stack
item string and calls the program with the given string on the stack.
Returns when interpretation halts, which could be the result of an exit, an
error, or a primitive that suspends execution such as sleep or read.
Return value is the top item off the stack if successful exit, or a null
string for anything else.


EXIT ( -- )

  Exits from the function currently being executed, returning control to
the calling function, at the statement immediately after the location of
the call (exiting the program if applicable).


BEGIN ( -- )

  Marks the beginning of BEGIN-UNTIL or BEGIN-REPEAT loops.


FOR (i1 i2 i3 -- i)

  Marks the beginning of a iterative FOR loop, and initializes it with i1
as the start index, i2 as the end index, and i3 as the step.  If i2 is less
then i1, or if i3 is negative and i2 is greater then i1, the entire loop is
skipped without executing.  If i3 is 0 the loop will run infinitely until
some other condition causes an exit.


FOREACH (a -- @ ? )

  Marks the beginning of an iterative FOREACH loop, stepping through every
index/value pair in the array.


WHILE (i -- )

  If the value on top of the stack is false, then this causes execution
to jump to the instruction after the UNTIL or REPEAT for the current
loop.  If the value is true, however, execution falls through to the
instruction after the WHILE.


BREAK ( -- )

  Breaks out of the innermost loop.  Jumps execution to the instruction
after the UNTIL or REPEAT for the current loop.


CONTINUE ( -- )

  Jumps execution to the beginning of the current loop.


REPEAT ( -- )

  This marks the end of the current loop.  Execution jumps to the instruction
after the matching BEGIN, FOREACH or FOR in a loop.


UNTIL (i -- )

  This marks the end of the current loop.  If the value on top of the
stack is false, then execution jumps back to the instruction after
the matching BEGIN or FOR statement.  If the value is true, it exits
the loop, and continues execution at the next instruction following
the UNTIL.
  Loops, TRY-CATCH-ENDCATCH's, and IF-ELSE-THEN's can all be nested in
each other as much as you want.


Loops:

  The BEGIN, FOR, or FOREACH statement marks the beginning of a loop.
Either the UNTIL or the REPEAT statement marks the end of the loop.
REPEAT will do an unconditional jump back to the BEGIN or FOR statement.
UNTIL checks to see if the value on the stack is false.  If it is, it
jumps back to the BEGIN or FOR statement, otherwise, it falls through
on execution to the statement after the UNTIL.
  Within a loop, even within IF-ELSE-THEN structures within the loop
structure, you can place WHILE, CONTINUE, or BREAK statements.  There
is no limit as to how many, or in what combinations these instructions
are used.
  A WHILE statement checks to see if the top value on the stack is false.
If it is, then execution breaks out of the innermost loop and resumes
after the matching REPEAT or UNTIL statement.
  The CONTINUE statement causes the loop to jump back to the beginning
of its next iteration, after the BEGIN, FOR, or FOREACH.
  The BREAK statement forces execution to break out of the innermost loop,
resuming after the matching REPEAT or UNTIL.
  Note: You can nest loops complexly, but WHILE, BREAK, and CONTINUE
statements only refer to the innermost loop structure.


Loop Examples 1:

How to count from 1 to 10 using a BEGIN-REPEAT loop:
    0 begin
        dup 10 < while
        1 +
        me @ over intostr notify
    repeat

How to count from 1 to 10 using a BEGIN-UNTIL loop:
    0 begin
        1 +
        me @ over intostr notify
        dup 10 =
    until

How to count from 1 to 10 using a FOR-REPEAT loop:
    1 10 1 for
        intostr me @ swap notify
    repeat


Loop Examples 2:

Example of a FOR loop:
    1 10 1 for
        me @ swap intostr notify
    repeat

Example of nested FOR loops:
    1 5 1 for
        "" swap 1 -1 for
            intostr strcat
        repeat
        me @ swap notify
    repeat

Example of a complex (if pointless) FOR loop:
    10 -10 -2 for
        me @ over intostr notify
        dup -5 > while
        dup 0 = if pop continue then
        dup -3 = if pop break then
        not
    until

Example of a FOREACH loop:
    {
        "index1" "value1"
        "index2" "value2"
        "index3" "value3"
    }dict
    foreach
        " = " swap strcat strcat me @ swap notify
    repeat


Loop Examples 3:

Example of a complex loop structure:
    101 begin                       (BEGIN the outer loop)
        dup while 1 -                 (This WHILE, ...)
        dup not if break then         (this BREAK, and..)
        dup 2 % not if continue then  (this CONTINUE refer to the outer loop)
        dup 10 % not if
        15 begin                      (BEGIN inner loop)
            dup while 1 -               (This WHILE, and.. )
            dup 5 % not if break then   (... this BREAK, refer to inner loop)
        repeat                        (This REPEAT statement ends inner loop.)
        then
        dup 7 % not if continue then  (This CONTINUE, and...)
        dup 3 % not if
            dup 9 % while             (...this WHILE refer to the outer loop)
        then
        dup intostr
        me @ swap notify
    dup 1 = until pop               (This UNTIL ends the outer loop)


PUBLIC <functionname>

  Declares a previously defined function to be public for execution by other
programs.  This is a compile-time directive, not a run-time primitive.  To
call a public function, put the dbref of the program on the stack, then put
a string, containing the function name, on the stack, then use CALL.
For example:
    #888 "functionname" CALL


WIZCALL <functionname>

  Declares a previously defined function to be callable from other programs,
as long as the calling program has wizbit permissions.  This is a compile-
time directive, not a run-time primitive.  To call a public function, put
the dbref of the program on the stack, then put a string, containing the
function name, on the stack, then use CALL.  For example:
    #888 "functionname" CALL


CANCALL?  (d s -- i)

  Returns true if the given program has a public or wizcall function that the
current program has permissions to call.  Returns false, otherwise.





----------------------------------------------------------------------------
                               I/O Operators
----------------------------------------------------------------------------




NOTIFY ( d s -- )

  d must be a player object. s must be a string. Tells player d message
s.  If s is null it will print nothing.  This primitive will trigger
the _listen'er property on the object the message is sent to, unless
the program that would be run is the same as one one currently running.


NOTIFY_EXCEPT ( d1 d2 s -- )

  d1 must be a room object, s must be a string.  Tells everyone at
location d1 except object d2 message s.  If object d2 is not a player
or NOTHING (#-1) all players are notified.  If s is null it prints
nothing.  NOTE: notify_except is now only an inserver $define.  It is
translated to '1 swap notify_exclude'.  Please see the man sections on
NOTIFY_EXCLUDE and DIRECTIVES for more information.


NOTIFY_EXCLUDE (d dn ... d1 n s -- )

  Displays the message s to all the players (or _listening objects),
excluding the n given players, in the given room.  For example:
  #0 #1 #23 #7 3 "Hi!" notify_exclude
would send "Hi!" to everyone in room #0 except for players (or objects)
#1, #7, and #23.  _listener's will not be triggered by a notify_exclude
if the program they would run is the same as the current program running.


READ_WANTS_BLANKS ( -- )

  Tells the interpreter that this process wants to be able to receive blank
lines from the READ primitive.  If this is not executed, the process will
silently ignore blank ("") lines in READ.  This only needs to be done once
per process, and isn't reversable.


READ ( -- s )

  Reads a string s from the user. This command should not be used in a
program that is locked (as opposed to linked) to an object, as the
lock will always fail and print the fail messages at read time.  It
cannot be used in a program associated with a room object.


TREAD ( i -- s i )

  Acts like a timed READ call.  If the user does not provide input within
the given number of seconds, the READ call will time-out and return a
false boolean, otherwise it returns a true boolean and the string value
entered.  This is implemented as an in-server macro as follows:
    "__tread" timer_start { "TIMER.__tread" "READ" }list event_waitfor
    swap pop "READ" strcmp if "" 0 else read 1 "__tread" timer_stop then


USERLOG ( str:mesg -- )

  Logs an arbitrary message to the user log file.  (#defined in config.h
as USER_LOG, defaults to the "logs/user" file.)  The log entry will be
formatted like:
Winged(#4023) [newaction.muf(#666)] 06/11/02 03:09:31: <string>
The program must be running at a mucker level at least equal to the @tune
value 'userlog_mlev' (defaults to 3) to write this log entry.





----------------------------------------------------------------------------
                           Mathematical Operators
----------------------------------------------------------------------------




INT ( x -- i )

  Converts variable, float, or dbref x to integer i.


+ ( n1 n2 -- i )

  This adds two numbers, n1 + n2.  If both numbers are integers, an integer
will be returned.  If one of them is a floating point number, then a float
will be returned.  You can also use this on a dbref or a variable number,
so long as the second argument is an integer.  In those cases, this will
return a dbref or variable number, respectively.


- ( n1 n2 -- i )

  This subtracts two numbers, n1 - n2.  If both numbers are integers, an
integer will be returned.  If one of them is a floating point number,
then a float will be returned.  You can also use this on a dbref or a
variable number, so long as the second argument is an integer.  In those
cases, this will return a dbref or variable number, respectively.


* ( n1 n2 -- n )

  This multiplies two numbers, n1 * n2.  If both numbers are integers, an
integer will be returned.  If one of them is a floating point number,
then a float will be returned.  You can also use this on a dbref or a
variable number, so long as the second argument is an integer.  In those
cases, this will return a dbref or variable number, respectively.


/ ( n1 n2 -- n )

  This divides two numbers, n1 / n2.  If both numbers are integers, an
integer will be returned.  If one of them is a floating point number,
then a float will be returned.  You can also use this on a dbref or a
variable number, so long as the second argument is an integer.  In those
cases, this will return a dbref or variable number, respectively.


% ( n1 n2 -- i )

  This returns the integer modulo (remainder) of the division of two
numbers, n1 % n2.  Floats cannot use the % modulo function.  For them,
use either the FMOD or MODF primitives.


++ ( v -- )
++ ( n -- n' )

  If given an integer, float, or dbref, adds 1 to it, and returns the result.
If given a variable containing an integer, float, or dbref, adds 1 to the
value stored in the variable, and returns nothing.


-- ( v -- )
-- ( n -- n' )

  If given an integer, float, or dbref, this subtracts 1 from it, and
returns the result.  If given a variable containing an integer, float,
or dbref, this subtracts 1 from the value stored in the variable, and
returns nothing.


ABS ( i -- i )

  Given an integer, returns its absolute value.


SIGN ( i -- i )

  Given an integer, returns 1 if positive, -1 if negative, and 0 if 0.


GETSEED ( -- s )

  Returns the the current SRAND seed string.


SETSEED ( s -- )

  Sets the seed for SRAND.  Only the first thirty-two characters are
significant.  If SRAND is called before SETSEED is called, then SRAND
is seeded with a semi-random value.


SRAND ( -- i )

  Generates a seeded random number.


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 2,147,483,647 (2.1 billion).  This is
based on the standard C random() function, so it's not very secure.


BITOR (i i -- i)

  Does a mathematical bitwise or.


BITXOR (i i -- i)

  Does a mathematical bitwise exclusive or.


BITAND (i i -- i)

  Does a mathematical bitwise and.


BITSHIFT (i i -- i)

  Shifts the first integer by the second integer's number of bit positions.
Same as the C << operator.  If the second integer is negative, its like >>.





----------------------------------------------------------------------------
                          Floating Point Operators
----------------------------------------------------------------------------




FLOAT ( i -- f )

  Converts integer to floating point type.


PI ( -- f )

  Returns the value of Pi.


INF ( -- f )

  Returns the value of an Infinite result.  Most functions will not
accept this value as a legal input.


EPSILON ( -- flt:epsilon )

  Returns the smallest number such that 1.0 + Epsilon is distinct from 1.0
in the internal representation for floating point numbers.  This is the
precision error.  This is useful when comparing that two numbers are equal
to within the precision of the system.  ie:
    float1 @ float2 @ - fabs epsilon < if "Equivalent" then

  When you are working with numbers that have exponent parts that may not be
near e+00, you should do a relative comparison instead:
    float1 @ float2 @ - float1 @ / fabs epsilon < if "Equivalent" then


FTOSTR ( f -- s )

  Converts a floating point number into a string.  Trailing zeros are not
removed from the end of the number, when no mantissa is shown.  FTOSTR can
return either the xxx.yyy form or the x.yyyEzz form of a float, depending
on which would give the shortest string length.


FTOSTRC ( f -- s )

  Converts a floating point number into a string.  Trailing zeros are removed
from the initial decimal, if no mantissa is shown.  FTOSTRC can return either
the xxx.yyy form or the x.yyyEzz form of a float, depending on which would
give the shortest string length.


STRTOF ( s - f )

  Converts a string into a floating point type.
STRTOF recognizes most standard forms of floating point representation,
including the xxx.yyy and x.yyyEzz forms.


FABS ( f -- f )

  Returns the absolute value of the float f.


CEIL ( f - f )

  Returns the next highest integer, as a floating point type.


FLOOR ( f -- f )

  Returns the next lowest integer number, as a floating point type.


ROUND ( f i -- f )

  Rounds the floating point number to the precision requested, given as the
number of places to the right of the decimal point.  ie: '1.111 1 round'
would leave '1.1' on the stack, while '1.111 0 round' would leave '1.0'.
Negative i values denote places to the left of the decimal place.  ie:
'1234.56 -2 round' would return '1200.0' on the stack.


FMOD ( f1 f2 -- f )

  Returns the floating point remainder of f1 divided by f2.  (f1/f2)


MODF ( f -- fi ff )

  The modf primitive breaks f into an integral part and a fractional part,
each of which has the same sign as f.  Both returned values are floats.
fi is the integral part, while ff is the fractional part.


SQRT ( f -- f )

  Returns a float's square root.  Expects a value greater than or equal
to zero.


COS ( f -- f )

  Returns the cosine of a float.  Only operates in the range of -Pi/4 to Pi/4.


ACOS ( f -- f )

  Returns the inverse cosine of a float.  Only operates within the range
from 0 to Pi.


SIN ( f -- f )

  Returns the sine of a float.  Only operates within the range of -Pi/4
to Pi/4.


ASIN ( f -- f )

  Returns the inverse sine of a float.  Only operates within the range
from -Pi/2 to Pi/2.


TAN ( f -- f )

  Returns the tangent of a float.  Only operates within the range of
-Pi/4 to Pi/4.


ATAN ( f -- f )

  Returns the inverse tangent of a float.  Only operates within the range
from -Pi/2 to Pi/2.


ATAN2 ( fy fx -- f )

  Returns the inverse tangent of (fy / fx), taking into account the signs
of both values, and avoiding problems with DIVBY0.  This is useful to
get an angle from X-Y coordinates.


LOG ( f -- f )

  Returns the natural log of float f.  Requires a value greater than zero.
Very small values will return INF.


EXP ( f -- f )

  Returns the value of e raised to the power of the passed float.


LOG10 ( f -- f )

  Returns the log base 10 of float f.  Requires a value greater than zero.
Very small values will return INF.


POW ( f1 f2 -- f )

  Returns f1 to the power of f2.  If f1 is zero, f2 must be greater than
zero.  If f1 is less than zero, f2 must be an integer value.


DIFF3 ( fx1 fy1 fz1 fx2 fy2 fz2 -- fx' fy' fz' )

  Returns three floats, being the differences of fx1 - fx2, fy1 - fy2, and
fz1 - fz2, respectively.


DIST3D ( fx fy fz -- f )

  Returns the distance of the XYZ coordinate (fx,fy,fz) from the origin.
To do a 2D distance calculation, simply use a Z value (fz) of 0.


XYZ_TO_POLAR ( fx fy fz -- fr ft fp )

  Converts the XYZ coordinate (fx, fy, fz) to the spherical polar coordinate
(fr, ft, fp).  fr is the radius, ft is theta (the plane angle), and fp is phi
(the elevation angle)  To do 2D X-Y to radius and angle conversion, simply use
a Z coordinate (fz) of 0, and discard phi (fp).


POLAR_TO_XYZ ( fr ft fp -- fx fy fz )

  Converts the spherical polar coordinate (fr, ft, fp) to the XYZ coordinate
(fx, fy, fz).  fr is the radius, ft is theta (the plane angle), and fp is phi
(the elevation angle)  To do 2D radius and angle to X-Y conversion, simply use
a phi angle (fp) of 0, and discard Z (fz).


FRAND ( -- f )

  Returns a random floating point number between 0 and 1.


GAUSSIAN ( fs fm -- f )

  Given the standard deviation, and the mean, return a floating point random
number with the given normalization.  Note that this may be any value between
-INF and INF.


CLEAR ( -- )

  Clears all error flags for floating point math operations.


CLEAR_ERROR ( s|i -- i )

  Clears a specific error flag for floating point math operations.


ERROR? ( -- i )

  Returns true if any of the floating point error flags have been set.  In
most cases, an error condition in a math operation will return a zero value
(except in the case of integer math, which will wrap around on an overflow
or underflow condition).  It is possible to poll for error conditions after
every math operation, or when a '0' result is found.
The following is a list of the current Error Flags:
    DIV_ZERO  - (0) Division by zero attempted.
    NAN       - (1) Result was not a number.
    IMAGINARY - (2) Result would be imaginary. 
    FBOUNDS   - (3) Floating-point inputs were out of range.
    IBOUNDS   - (4) Calculation resulted in an integer overflow or underflow.


ERROR_BIT ( s -- i )

  Returns the bit identifier for a given floating point error flag string name.


ERROR_NAME ( i -- s )

  Returns the string name for the error flag, given a floating point error
identifier.


ERROR_NUM ( -- i )

  Returns the total number of floating point error flag types.


ERROR_STR ( s|i -- s )

  Returns a user-readable error string, given a floating point error identifier.


IS_SET? ( s|i - i )

  Checks if a specific floating point error flag is set.


SET_ERROR ( s|i -- i )

  Sets the specified error flag for floating point operations.





----------------------------------------------------------------------------
                       String Manipulation Operators
----------------------------------------------------------------------------




ATOI ( s -- i )

  Turns string s into integer i.  If s is not a string, then 0 is pushed
onto the stack.


CTOI ( s -- i )

  Converts the first character in s into its ASCII equivilent.


STRLEN ( s -- i )

  Returns the length of string s.


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 i as 0 if they are equal,
otherwise returns i as the difference between the first non-matching
character in the strings.  For example, "a" "z" strcmp returns 25.
The reason it returns a 0 for a match, and the difference on a non-match,
is to allow for nice things like string sorting functions.
This primitive is case sensitive, unlike stringcmp.


STRNCMP ( s1 s2 i -- i' )

  Compares the first i characters in strings s1 and s2.
Return value is like strcmp.


STRINGCMP ( s1 s2 -- i )

  Compares strings s1 and s2. Returns i as 0 if they are equal,
otherwise returns i as the difference between the first non-matching
character in the strings.  For example, "a" "z" stringcmp returns 25.
This function is not case sensitive, unlike strcmp.


STRINGPFX (s s2 -- i)

  Returns 1 if string s2 is a prefix of string s.  If s2 is NOT a prefix
of s, then it returns 0.  Case insensitive.


INSTR ( s s1 -- i )

  Returns the first occurrence of string s1 in string s, or 0 if s1 is
not found.


RINSTR ( s s1 -- i )

  Returns the last occurrence of string s1 in string s, or 0 if s1 is
not found.  '"abcbcba" "bc" rinstr' returns 4.


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.


MIDSTR ( s i1 i2 -- s )

  Returns the substring of i2 characters, starting with character i1.
i1 and i2 must both be positive.  The first character of the string
is considered position 1.  ie:
    "testing" 2 3 midstr
will return the value "est".


SPLIT ( s1 s2 -- s1' s2' )

  Splits string s1 at the first found instance of s2.  If there are no
matches of s2 in s1, will return s1 and a null string.


RSPLIT ( s1 s2 -- s1' s2' )

  Splits a string, as SPLIT, but splits on the last occurence of s2.


EXPLODE ( s1 s2 -- ... i )

  s2 is the delimiter string, and s1 is the target string, which will be
fragmented, with i pushed on top of the stack as the number of strings
s1 was broken 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".)  For TinyMUCK 2.2, s2 may
be any length.  But "" (null string) is not an acceptable string for
parameter s2.


EXPLODE_ARRAY ( s1 s2 -- a )

  s2 is the delimiter string, and s1 is the target string.  s1 will be split
up at each place where s2 is found in s1, and all the parts will be returned
in a list array.  For instance:
    "alpha, beta, gamma"  ", "  explode_array
will result in a list array that is identical to:
    { "alpha" "beta" "gamma" }list
s2 cannot be a null string, but it can be of any non-zero length.  When s2
is more than one character long, the delimiter is considered to be the
entire s2 string.  The delimiters are removed from the results.


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.


FMTSTRING ( ?n..?1 s -- s )

  Allows for string formatting with format substitutions, as per C's printf.
FMTSTRING can be used to format complicated and long strings, as well as
multi-lined (with embedded new-lines) strings.  These strings can consist
entirely of user-specified text, formatted variable entries (as values taken
from the stack) or a combination of both.

  The first format substitution in the format string will use the topmost
stack value.  The next format substitution will use the next item down
the stack, and so on.

  The start of a format substitution in the string is noted by a '%'.  If a
literal '%' is needed in the string, a '%%' may be used.  The format of a
substitution is as follows: '%[-,|][+, ][0][number][.number]type'
Where 'number' is an integer value, and 'type' is one of the following
identifiers:
    i - integer argument
    s - string argument
    d - dbref number, in the form of #123
    D - dbref name reference; given a dbref, will print the associated
        name for that object - terminates on bad reference
    l - pretty-lock, given a lock, will print the description
    f - float in xxx.yyy form
    e - float in x.yyEzz form
    g - shorter of forms e or f
    ~ - default representation of any stack type
    ? - unknown type argument, will print a string stating what the
        variable type is

  A '-' at the start of a format substitution indicates the field will be left
justified.  A '|' at the start indicated the field will be centered.  A '+'
forces the + sign to appear for positive numbers.  A space forces a blank
in front of positive numbers.  (This is the default.)  A leading 0 will
force the field to be padded on the left with 0's instead of spaces.  If you
use a '*' in place of either the width or precision format fields, then
that integer number will be obtained from the stack.  You may specify a
negative fieldwidth to obtain left justification of that field.  You may
not specify a negative precision.


ARRAY_FMTSTRINGS ( list:dicts str:format -- list:results )

  Lets you apply a format string, a la FMTSTRING, to each of a list of
dictionaries of input data, returning a list of strings, one for each
input dictionary.

  Unlike FMTSTRING, the format string needs to have key markers to
specify which key of each input dictionary to use to get the data for
each format field.  You specify the key markers in each format
subsititution by adding a '[KEY]' before the substitution type letter.
For example, the code:

    {
        {
            "username" "Johnny"
            "count" 4
            "object" #18
            4  pi
        }dict
        {
            "username" "Ghaladahsk_Fadja"
            "count" 123
            "object" #97
        }dict
    }list
    "%-16.15[username]s %3[count]i %5[object]d %4.2[4]g"
    array_formatstrings
    { me @ }list array_notify

... would show the following output to the user:

    Johnny             4   #18 3.14
    Ghaladahsk_Fadj  123   #97 0.00

  Note that if a key does not exist in an input dictionary, then that
format field will be assumed to either be 0, #-1, or a null string,
as apropriate for the format type.

  Numeric keys can be referred to as well as string keys.  This also
means that you may use a list of list arrays as input, instead of a
list of dictionaries.

  See FMTSTRING for a full description of normal substitution format codes.
Note that unlike FMTSTRING, the format strings cannot use calculated
field widths or precisions via '*'.

  Hint: If you want to use this format method on a single dictionary, you
can do something like:

    pid getpidinfo   (to give us a dictionary of data.)
    1 array_make     (to make a list with that as its single entry)
    "%-40[player]D %6[pid]i %[called_prog]D" 
    array_fmtstrings
    0 []             (to get the formatted result string.)


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.
  
The substitutions are:
    %a/%A for absolute possessive (his/hers/its, His/Hers/Its)
    %s/%S for subjective pronouns (he/she/it, He/She/It)
    %o/%O for objective pronouns (him/her/it, Him/Her/It)
    %p/%P for possessive pronouns (his/her/its, His/Her/Its)
    %r/%R for reflexive pronouns (himself/herself/itself,
                                  Himself/Herself/Itself)
    %n/%N for the player's name.
  
  if it comes across a %X substitution, where X is any character not listed
in the above substitutions table, it will search down the environment tree
from d to try to find the appropriate %X property for use in substitution.


TEXTATTR ( s1 s2 -- s )

  Takes a plain text string s1 and adds the neccesary codes to make the
output s display with the given attributes s2, when shown with an
appropriate client.  The attributes are passed to TEXTATTR in s2 as a
series of comma separated attribute names.

These are the attributes currently recognized:
    reset    bold   dim       uline    flash   reverse
    black    red    yellow    green    cyan    blue    magenta    white
    bg_black bg_red bg_yellow bg_green bg_cyan bg_blue bg_magenta bg_white


STOD ( s -- d )

  Attempts to extract a dbref from s, recognizing both plain numerical
strings, and those prepended with a '#' sign.


ANSI_STRIP ( s -- s' )

  Takes a string and removes ansi escapes from with in the string, returning
the de-ansified string.


ANSI_STRLEN ( s -- i )

  Returns the length of string s ignoring ansi escape within the string.


ANSI_STRCUT ( s i -- s1 s2 )

  Like STRCUT, but ignores ansi escapes when finding the location to divide
the string at.


ANSI_MIDSTR ( s i i -- s' )

  Does exactly what MIDSTR does, except it ignores ansi escapes when
determining what section of the string to extract.


NUMBER? ( s -- i )

  Returns 1 if string on top of the stack contains a number. Otherwise
returns 0.


INTOSTR ( x -- s )

  x must be an integer or a dbref. Converts x into string s.


ITOC ( i -- s )

  Converts an integer i to its ASCII equivilent character, or a null
if i is not a valid display character.


STRENCRYPT ( s1 s2 -- s3 )

  Takes the plaintext string s1, and encrypts it, using the key s2,
returning the encrypted string s3.  Note: s3 will be 2 characters longer
than s1.  Also Note: The longer your key string is, the more secure
the data will be, up to the length of the data itself.  The encryption
technique used here is pretty simple, so I highly doubt it breaks
any laws to take it outside the USA.  By the same token, it probably
shouldn't be trusted with any really important data.  I'm not an expert
at cryptography, so this ain't DES.


STRDECRYPT ( s1 s2 -- s3 )

  Takes the encrypted string s1, and decrypts it, using the key s2, returning
the plaintext string s3.


TOUPPER (s -- s)

  Takes a string and returns it with all the letters in uppercase.


TOLOWER (s -- s)

  Takes a string and returns it with all the letters in lowercase.


STRIPLEAD (s -- s)

  Strips leading spaces from the given string.


STRIPTAIL (s -- s)

  Strips trailing spaces from the given string.


STRIP (s -- s)

  This is a built in $define.  It is interpreted as "striplead striptail"
It strips the spaces from both ends of a string.


SMATCH ( s s2 -- i )

  Takes a string s, and a string pattern, s2, to check against.  Returns true
if the string fits the pattern.  This is case insensitive.  In the pattern
string, the following special characters will do as follows:
  
  *  A '?' matches any single character.
  
  *  A '*' matches any number of any characters.
  
  *  '{word1|word2|etc}' will match a single word, if it is one of those
        given, separated by | characters, between the {}s.  A word ends with
        a space or at the end of the string.  The given example would match
        either the words "word1", "word2", or "etc".
        {} word patterns will only match complete words: "{foo}*" and "{foo}p"
        do not match "foop" and "*{foo}" and "p{foo}" do not match "pfoo".
        {} word patterns can be easily meaningless; they will match nothing
        if they:
          (a) contains spaces,
          (b) do not follow a wildcard, space or beginning of string,
          (c) are not followed by a wildcard, space or end of string.
  
  *  If the first char of a {} word set is a '^', then it will match a single
        word if it is NOT one of those contained within the {}s.  Example:
        '{^Foxen|Fiera}' will match any single word EXCEPT for Foxen or Fiera.
  
  *  '[aeiou]' will match a single character as long as it is one of those
        contained between the []s.  In this case, it matches any vowel.
  
  *  If the first char of a [] char set is a '^', then it will match a single
        character if it is NOT one of those contained within the []s.  Example:
        '[^aeiou]' will match any single character EXCEPT for a vowel.
  
  *  If a [] char set contains two characters separated by a '-', then it will
        match any single character that is between those two given characters.
        Example:  '[a-z0-9_]' would match any single character between 'a' and
        'z', inclusive, any character between '0' and '9', inclusive, or a '_'.
  
  *  The '\' character will disable the special meaning of the character that
        follows it, matching it literally.
  
Example patterns:
    "d*g" matches "dg", "dog", "doog", "dorfg", etc.
    "d?g" matches "dog", "dig" and "dug" but not "dg" or "drug".
    "M[rs]." matches "Mr." and "Ms."
    "M[a-z]" matches "Ma", "Mb", etc.
    "[^a-z]" matches anything but an alphabetical character.
    "{Moira|Chupchup}*" matches "Moira snores" and "Chupchup arghs."
    "{Moira|Chupchup}*" does NOT match "Moira' snores".
    "{Foxen|Lynx|Fier[ao]} *t[iy]ckle*\?"  Will match any string starting
      with 'Foxen', 'Lynx', 'Fiera', or 'Fiero', that contains either 'tickle'
      or 'tyckle' and ends with a '?'.


INSTRING ( s s1 -- i )

  Returns the first occurrence of string s1 in string s, or 0 if s1 is
not found. Non-case sensitive.  This is an inserver define equivalent to
$def INSTRING tolower swap tolower swap instr


RINSTRING ( s s1 -- i )

  Returns the last occurrence of string s1 in string s, or -1 if s1 is
not found. Non-case sensitive.  This is an inserver define equivalent to
$def RINSTRING tolower swap tolower swap rinstr


NAME-OK? (s -- i)

  Returns true if the given string would be okay as a general object's name.


PNAME-OK? (s -- i)

  Returns true if the given string would be okay as a player name.


REGEXP ( str:text str:pattern int:flags -- list:SubMatchVals list:SubMatchIdx )

  Tests text to see if it matches the given PCRE style regular expression
pattern.  If the test fails, two empty lists are returned.  If the test
succeeded, the first list returned contains, as element 0, the substring
that matched the entire pattern, followed by the captured substrings that
matched the various parenthesized subexpressions of the pattern.  The second
contains, as element 0, a sublist containing the starting position and length
of the substring that matched the entire pattern, followed by similar sublists
for each captured parenthesized subexpression.  These indices are apropriate
for use with the MIDSTR primitive, and consider the first character of the
string to be position 1.

The "flag" argument may be 0, or a combination of the following:

    $def REG_ICASE    1   (Case insensitive match)
    $def REG_EXTENDED 4   (Allows PCRE comments, etc.  See PCRE docs.)


REGSUB ( str:text str:pattern str:substr int:flags -- str:result )

  Performs a regular expression substitution using pattern against text,
replacing the match with substr.  substr may contain \digit to specify
a submatch.  Uses PCRE style regular expression syntax.

The "Flag" argument may be a combination, or none of the following:

    $def REG_ICASE    1   (Case insensitive match)
    $def REG_ALL      2   (Substitute all matches, rather than just the first)
    $def REG_EXTENDED 4   (Allows PCRE comments, etc.  See PCRE docs.)

Ie: to replace all words in a string with 'yadda', ignoring case, you would
use the following code:

    "[a-z]+" "yadda" REG_ICASE REG_ALL + REGSUB


TOKENSPLIT (strString strDelim strEscape -- strPre strPost strChar)

  Searches strString for the first character that matches any character in
strDelim, so long as it is not escaped by the character given in strEscape.  
Returns the unescaped string before the found character, the raw string after
that character, and the character that was found.  For example:
    "ab//cd/'efg'hi//jk'lm"   "'"   "/"   TOKENSPLIT
returns the values:
    "ab/cd'efg"   "hi//jk'lm"   "'"





----------------------------------------------------------------------------
                        Lock Manipulation Operators
----------------------------------------------------------------------------




LOCKED? (d d -- i)

  Takes, in order, the dbref of the player to test the lock against, and
the dbref of object the lock is on.  It tests the lock, running programs
as necessary, and returns a integer of 0 if it is not locked against
them, or 1 if it is.


PARSELOCK (s -- l)

  Parses a lock string into a lock.  If the parsing failed, then the lock
returned will be a TRUE_BOOLEXP, which is logically false to an 'if' test.


UNPARSELOCK (l -- s)

  Unparses a lock into a string fit for program editing.


PRETTYLOCK (l -- s)

  Unparses a lock into a string fit for players to see.


TESTLOCK (d l -- i)

  Tests the player dbref against the given lock.  If the test was successful,
then this returns a 1.  If the test failed, then this returns a 0.


SETLOCKSTR (d s -- i)

  Tries to set the lock on the given object to the lock expression given in
the string.  If it was a success, then it will return a 1, otherwise, if
the lock expression was bad, it returns a 0.  To unlock an object, set its
lock to a null string.


GETLOCKSTR ( d -- s )

  Returns the lock expression for the given object in the form of a string.
Returns "*UNLOCKED*" if the object doesn't have a lock set.





----------------------------------------------------------------------------
                        Array Manipulation Operators
----------------------------------------------------------------------------




ARRAY_MAKE ( {?} -- a )

  Creates a list type array from a stackrange.


}LIST  ( marker ?n ... ?1 -- array )

  Takes all stack items from the top of the stack to the topmost stack
marker and creates a list array from them.  This is actually an inserver
macro, defined to '} array_make'.


ARRAY_MAKE_DICT ( {@ ?} -- a )

  Creates a dictionary type array from a stackrange of index/value
pairs.


}DICT  ( marker @n ?n ... @1 ?1 -- dictionary )

  Takes pairs of stack items from the top of the stack to the topmost stack
marker and creates a dictionary array from them.  Each @ item is used as an
index value for the corresponding ? value.  This is actually an inserver
macro, defined to '} 2 / array_make_dict'.  Be careful to make sure that
there are an even number of stack items between the { and the }dict.


ARRAY_NOTIFY ( a1 a2 -- )

  Notifies all strings in array a1 to all dbrefs in array a2.  Arrays
must be homogenous of their respective types.


}TELL  ( marker strn ... str1 -- )

  Takes all stack items from the top of the stack to the topmost stack
marker and notifies them to the 'me @' user.  This will throw an error
if you try to send a non-string.  Each separate string will be send as a
separate line to the user.  This is actually an inserver macro, defined to
'} array_make me @ 1 array_make array_notify'.


ARRAY_JOIN ([s] s -- s)

  Takes a list array and a delimiter string, and returns a single string
that is the concatenation of all the items in the list array, with the
delimiter string in between.  For example:
    { "one" 2 "three" 3.14159 }list "... " array_join
will result in a single string: "one... 2... three... 3.14159"


ARRAY_INTERPRET ([s] -- s)

  Takes a list array and and returns a single string that is the concatenation
of all the items in the list array, with dbrefs translated to the name of
their respective objects.  For example:
    { #1 " " 2 " three " 3.14159 }list array_join
will result in a single string like: "Wizard 2 three 3.14159"


}JOIN  ( marker ?n ... ?1 -- string )

  Takes all stack items from the top of the stack to the topmost stack
marker and concatenates them into a string based on the default reresentat-
ion of each stack item type.  Dbrefs will be shown as #REF numbers.  This
actually is an inserver macro, defined to '} array_make "" array_join'.


}CAT  ( marker ?n ... ?1 -- string )

  Takes all stack items from the top of the stack to the topmost stack
marker and concatenates them into a string based on the default reresentat-
ion of each stack item type.  Dbrefs will be translated to the name of the
object that they reference.  This primitive is actually an inserver macro,
defined to '} array_make array_interpret'.


ARRAY_COUNT ( a -- i )

  Returns the count of number of items in the array.


ARRAY_GETITEM ( a @ -- ? )

  Returns item with index @ from an array.


ARRAY_SETITEM ( ? a @ -- a')

  Overwrites a given array item at index @ with new value ?.


ARRAY_INSERTITEM ( ? a @ -- a' )

  Inserts a given value into an array.


ARRAY_APPENDITEM ( ? a -- a')

  Appends the given item to the given list array.


ARRAY_DELITEM ( a @ -- a' )

  Removes an item with index @ from an array.


ARRAY_GETRANGE ( a @ @ -- a' )

  Returns as an array the range between two indexes (inclusive)
from an array.


ARRAY_SETRANGE ( a1 @ a2 -- a' )

  Sets items in list a1 to vals from list a2, starting at the given
index.  Returns the resulting array.


ARRAY_INSERTRANGE ( a1 @ a2 -- a' )

  Inserts items from array a2 into a1, starting at the given index.
Returns the resulting array.


ARRAY_DELRANGE ( a @ @ -- a' )

  Deletes a range of items between two indexes (inclusive) from
an array.


ARRAY_NESTED_GET ( a1 a2 -- ? )

  Takes a nested array a1, and a list of array indexes a2, and recursively
fetches nested sub-array values.  Returns 0 if the item doesn't exist.
Example:
    arr1 @ { "foo" 2 "bar" }list array_nested_get
is roughly equivalent to
    arr1 @ "foo" [] dup if
        2 [] dup if
            "bar" []
        then
    then


ARRAY_NESTED_SET ( ? a a2 -- a' )

  Sets the nested array entry in a, specified by the list of array indexes
in a2, to the given value, creating new sub-arrays if needed.
Example:
    { }dict
    "qux" swap { "foo" "bar" "baz" }list array_nested_set
    4 swap { "foo" 2 "clam" }list array_nested_set
would return the same array as
    {
        "foo" {
            "bar" {
                "baz" "qux"
            }dict
            2 {
                "clam" 4
            }dict
        }dict
    }dict


ARRAY_NESTED_DEL ( a a2 -- a' )

  Deletes the nested array entry in a, specified by the list of array
indexes in a2.  Example:
    {
        "foo" {
            "bar" {
                "baz" "qux"
            }dict
            2 {
                "clam" 4
            }dict
        }dict
    }dict
    { "foo" 2 }list array_nested_del
would return the same array as
    {
        "foo" {
            "bar" {
                "baz" "qux"
            }dict
        }dict
    }dict


ARRAY_EXTRACT (array arrIndexes -- array')

  Takes an array, and returns a dictionary containing every element of the
original array who's key was in the list indexes given.


ARRAY_REVERSE (a -- a')

  Takes a list array and reverses the order of its elements.


ARRAY_COMPARE ( a1 a2 -- i )

  Compares two arrays using the same ordering assumptions as ARRAY_SORT in
case sensitive ascending order mode.  If the two arrays are identical,
this returns 0.  If the first array is considered greater than the second,
this returns a positive value.  If the second array is considered greater,
this returns a negative value.  I'm not sure if the greater/lesser-than
comparison results are really useful, though.


ARRAY_EXPLODE ( a -- {@ ?} )

  Explodes an array into a stackrange of its index/value pairs.  Example:
    "index0" "value0" "index1" "value1" 2


ARRAY_KEYS ( a -- {@} )

  Returns the keys of an array in a stackrange.  Example:
    "index0" "index1" 2 


ARRAY_VALS ( a -- {?} )

  Returns the values of an array in a stackrange.  Example:
    "value0" "value1" 2


ARRAY_FIRST ( a -- @ i )

  Returns the first index in array, and a boolean which is false
if there are no items are in the array.


ARRAY_PREV ( a @ -- @ i )

  Returns the previous index in the array, and a boolean which
is false if there are no items left.


ARRAY_NEXT ( a @ -- @ i )

  Returns the next index in the array, and a boolean which
is false if there are no items left.


ARRAY_LAST ( a -- @ i )

  Returns the last index in array, and a boolean which is false
if there are no items are in the array.


ARRAY_CUT ( a1 @ -- a2 a3 )

  Given an array, and an index into the array, cuts the array into two
arrays at that position.  The first array output will contain all array
items before the given index.  The second array will contain the given
position and all items after it.  When used on a list array, both output
arrays will be list arrays.  When used on dictionaries, both arrays will
be dictionaries.


ARRAY_SORT (arrData intSortType -- arrSorted)

  This sorts all the items in the list array given, based on the given
sort type.  This can sort strings, integers, floats, dbrefs, or mixes
of types.  Integers are sorted in with floats, but strings sort after
all numbers.  Dbrefs sort after the other number types, but before
string types.  Other stack item types will sort separately, but in
an undefined consistent order.

  The SortType argument is an integer, and its default value of 0 means
that the sorting should be case sensitive and in ascending order.  You
can change either of those by using one or more of the following inserver
$defines BITORed or added together:
  $def SORTTYPE_CASEINSENS 1   (Sort is to be case insensitive.)
  $def SORTTYPE_DESCENDING 2   (Sort is to be in reversed order.)
  $def SORTTYPE_SHUFFLE    4   (Randomize list completely.)

  The above sort types can be added or bitor'ed together to get the
following inserver $defines as listed below.
  $def SORTTYPE_CASE_ASCEND    0 (Case sensitive and ascending order.)
  $def SORTTYPE_NOCASE_ASCEND  SORTTYPE_CASEINSENS
  $def SORTTYPE_CASE_DESCEND   SORTTYPE_DESCENDING
  $def SORTTYPE_NOCASE_DESCEND SORTTYPE_CASEINSENS SORTTYPE_DESCENDING +


ARRAY_SORT_INDEXED (arrData intSortType idxIndex -- arrSorted)

  This takes a list array of arrays, and will sort them, based on the
value of an indexed value in each subarray, based on the given sort
type.  For example:
    {
        { "name" "One"     "num" 1 }dict
        { "name" "Two"     "num" 2 }dict
        { "name" "Three"   "num" 3 }dict
    }list
    SORTTYPE_DESCENDING "num" ARRAY_SORT_INDEXED
...would return an array of dictionaries, sorted in descending order by the
value of their "num" entries.  ie, the same as:
    {
        { "name" "Three"   "num" 3 }dict
        { "name" "Two"     "num" 2 }dict
        { "name" "One"     "num" 1 }dict
    }list
  This can be used with an array of list arrays, just like with an array of
dictionaries.  For list arrays, you just use an integer for the index.
NOTE: arrays that don't have an item matching the given index, will be
sorted as lesser than arrays that do.

See ARRAY_SORT for more information on sort ordering.


ARRAY_UNION ( a1 a2 -- a )

  Returns a list array containing the union of values of both the given
arrays.  ie: If a value is found in either of the given arrays, then it
will be returned in the result list.  Duplicate values will appear only
once in the returned list.  Keys are discarded.  Ordering is not preserved.


ARRAY_NUNION ( {a} -- a )

  Returns a list array containing the union of values of all the given
arrays in the stackrange.  ie: if a value is found in any of the given
arrays, then it will be returned in the resultant list.  Duplicate values
will appear only once in the returned list.  Keys are discarded.  Ordering
is not preserved.


ARRAY_DIFF ( a1 a2 -- a )

  Return an array containing the difference of the two given arrays.
ie: This returns all values of a2 that weren't found in a1.  Duplicate
values will appear only once in the returned list.  Keys will be discarded.
Ordering is not preserved.


ARRAY_NDIFF ( {a} -- a )

  Return an array containing the difference of all the given arrays
in the stackrange.  ie: This returns all values from the topmost array
that weren't found in any of the remaining arrays.  Multiple arrays are
consecutively processed against the results of the previous difference,
from the top of the stack down.  Duplicate values will appear only once
in the returned list.  Keys will be discarded.  Ordering is not preserved.


array_intersect ( a1 a2 -- a )

  Returns an array containing the intersection of the two arrays.
ie: Only values contained in BOTH the given arrays will be returned.
Duplicate values will appear only once in the returned list.  Keys will
be discarded.  Ordering is not preserved.  This is actually an inserver
macro to '2 array_nintersect'


array_nintersect ( {a} -- a )

  Returns an array containing the intersection of all the given arrays
in the stackrange.  ie: Only values contained in ALL the given arrays
will be returned.  Multiple arrays are consecutively processed against
the results of the previous intersection, from the top of the stack down.
Duplicate values will appear only once in the returned list.  Keys will
be discarded.  Ordering is not preserved.


ARRAY_FINDVAL (a1 ? -- a2)

  Returns a list array containing the keys of every element in the array
a1 whose values match the given value.  For example:

    { #5 #10 #15 #10 #20 }list #10 array_findval

will return a list containing 1 and 3, being the keys (indexes) of the
matching items.


ARRAY_EXCLUDEVAL (a1 ? -- a2)

  Returns a list array containing the keys of every element in the array
a1 whose values did NOT match the given value.  For example:
    { #5 #10 #15 #10 #20 }list #10 array_excludeval
will return a list containing 0, 2 and 4, being the keys (indexes) of the
items that didn't match.  If you want the values, use ARRAY_DIFF or
ARRAY_EXTRACT.  Ie:
    { #5 #10 #15 #10 #20 }list { #10 }list array_diff
or
    { #5 #10 #15 #10 #20 }list dup #10 array_excludeval array_extract
which will both return a list containing #5, #15, and #20.  The main
difference between these two methods is that ARRAY_DIFF will remove any
duplicate values in the remaining items, and the ordering of the resulting
items will have been sorted.  Using ARRAY_EXTRACT, ordering and duplicate
values are preserved.


ARRAY_MATCHKEY (arrStrings strPattern - arrStrings)

  Given an array and an smatch wildcard pattern string, returns a dictionary
containing all the key-value pairs where the key was a string that matched
the given smatch pattern.


ARRAY_MATCHVAL (arrStrings strPattern - arrStrings)

  Given an array and an smatch pattern string, returns a dictionary containing
all the key-value pairs where the value was a string that matched the given
smatch wildcard pattern.





----------------------------------------------------------------------------
                      Property Manipulation Operators
----------------------------------------------------------------------------




GETPROP (d s -- ?)

  Gets the value of a given property, and puts it on the stack.
This can return a lock, a string, a dbref, or an integer, depending
on the type of the property.  Permissions are the same as those for
GETPROPSTR.  This primitive returns 0 if no such property exists, of
if it is a valueless propdir.


GETPROPSTR ( d s -- s )

  s must be a string. Retrieves string associated with property s in
object d.  If the property is cleared, "" (null string) is returned.


GETPROPVAL ( d s -- i )

  s must be a string. Retrieves the integer value i associated with
property s in object d. If the property is cleared, 0 is returned.


GETPROPFVAL ( d s -- f )

  Returns the float value stored in the property


ENVPROP ( d s -- d ? )

  Takes a starting object dbref and a property name and searches down the
environment tree from that object for a property with the given name.  If
the property isn't found, it returns #-1 and a null string.  If the
property is found, it will return the dbref of the object it was found on,
and the value it contained.


ENVPROPSTR (d s -- d s )

  Takes a starting object dbref and a property name and searches down the
environment tree from that object for a property with the given name.  If
the property isn't found, it returns #-1 and a null string.  If the
property is found, it will return the dbref of the object it was found on,
and the string value it contained.


ADDPROP ( d s1 s2 i -- )

  Sets property associated with s1 in object d.  Note that if s2 is
null "", then i will be used.  Otherwise, s2 is always used.  All four
parameters must be on the stack; none may be omitted.  If the effective
user of the program does not control the object in question and the
property begins with an underscore `_', the property cannot be changed.
The same goes for properties beginning with a dot `.' which cannot be
read without permission. 


SETPROP (d s ? -- )

  Stores a lock, dbref, integer, or string into the named property on the
given object.  Permissions are the same as for ADDPROP.


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 object, the call fails.


PROPDIR? (d s -- i)

  Takes a dbref and a property name, and returns a boolean integer that
tells if that property is a propdir that contains other props.
(Requires Mucker Level 2)


NEXTPROP (d s -- s)

  This takes a dbref and a string that is the full propdir pathname of a
property and returns the full pathname of the next property in the given
object's given propdir, or returns a null string if that was the last
property in the propdir.  To *start* the search, give it a propdir name
ending in a '/', or a blank string.  For example, '#10 "/" NEXTPROP'
returns the name of the first property in the root propdir of object #10,
and '#28 "/letters/" NEXTPROP' would return the name of the first
property in the 'letters/' propdir on object #28.  A blank string is the
same as "/".  If you try to do a Nextprop on a non-existant property, you
will have a null string returned to you. Nextprop will skip properties if
they would not be readable by the program with the given permissions and
effective user id. (Requires Mucker Level 3)


ARRAY_GET_REFLIST ( d s -- a )

  Reads in list of space delimited dbrefs from a string property, and
returns them as a list array of dbrefs.  See ARRAY_PUT_REFLIST for
property syntax.


ARRAY_PUT_REFLIST ( d s a -- )

  Takes a list array of dbrefs, and stores them in a property as a space
delimited string of dbrefs.  ie:  "#1234 #6646 #1026 #7104"


REFLIST_FIND ( d1 s1 d2 -- i )

  Finds dbref d2 in the reflist in property s1 on object d1.  If d2 is
not in the list, then 0 is returned.  Otherwise the position of the
dbref in the list is returned, with the first dbref being in position 1,
the second dbref in 2, etc.


REFLIST_ADD ( d1 s1 d2 -- )

  Adds dbref d2 to the reflist in property s1 on object d1.  If d2 is already
in the list, it is moved to the end of the reflist.


REFLIST_DEL ( d1 s1 d2 -- )

  Removes dbref d2 from the reflist in property s1 on object d1.  If d2 is
not in the list, nothing happens.


UNBLESSPROP (dbrefObject strPropname -- )

  Unblesses the given property for MPI.  Requires Wizbit perms.


BLESSPROP (dbrefObject strPropname -- )

  Blesses the given property for MPI.  Requires Wizbit perms.


BLESSED? (d s -- i)

  Takes a dbref and a property name, and returns a boolean integer that
tells if that property has been blessed.
(Requires Mucker Level 2)


ARRAY_FILTER_PROP ([d] s1 s2 -- [d'])

  Takes a homogenous list array of dbrefs, and returns a list array with only
those dbrefs who have a property specified by s1, set to a value that smatch
matches s2.


ARRAY_FILTER_FLAGS ( list:dbrefs str:flags -- list:matchingdbrefs )

  Takes a homogenous list array of dbrefs and a flags test string, and
returns a list array with only those dbrefs whose flags matched the flag
test string.  A flags test string is a list of flag letters or object type
letters to require, and a list of flags to specifically reject preceeded
by exclamation marks (!).  ie: "TD!C!V" would match Things set Dark, which
did not have their Chown_ok or Vehicle flags set.  See 'help @find' for
more info on flag test strings.


ARRAY_GET_PROPDIRS( d s -- a )

  Returns a list array containing the names of all the sub-propdirs
contained within the given propdir.  Any propdirs the program wouldn't
be able to read, are left out.  (ML3 required.)


ARRAY_GET_PROPVALS ( d s -- a )

  Reads in properties from a propdir, and returns them in a dictionary,
keyed by propname.  Sub- propdirs in the given propdir that do not
have any value of their own, are left out of the returned dictionary.
Properties that the program doesn't have perms to read are also
left out.  Reads up to 511 props maximum. (ML3 required.)


ARRAY_PUT_PROPVALS ( d s a -- )

  Takes the values in the given dictionary, and stores them in the given
propdir on the given object.  Each dictionary entry will be saved into a
property with the key as the name, and the value as the property value.
Be aware that dictionary entries with keys starting with one of @ ~ _
or . may require special permissions to save.


ARRAY_GET_PROPLIST ( d s -- a )

  Reads in properties from a classic style proplist, and returns them
in a dictionary, keyed by propname.  Proplists can be in any of the
common proplist styles: ie: "propname#/1", "propname/1", or "propname1".
If the program doesn't have permission to read the list, it returns an
empty dictionary.  Reads up to 511 props maximum.


ARRAY_PUT_PROPLIST ( d s a -- )

  Takes the values in the given list array, and stores them in the given
propdir on the given object as a sequential proplist.  This will use the
system standard proplist format specified by @tune settings.


PARSEPROP (d s s i -- s)

  Returns the string output of the MPI Parser, given an object, a
property name to parse, an input string for the {&how} variable, and an
integer that should either be 1, for when you want {delay} messages to be
sent to the player only, or 0, when you want the rest of the players in
the room to get the omessages. NOTE: for security reasons, you cannot use
PARSEPROP with a mucker level of less than 3.


PARSEPROPEX ( ref:Obj str:Prop dict:Vars int:Private -- dict:Vars str:Result )

  MPI parses "Prop" on "Obj".  The dictionary "var" will be used to setup mpi
variables, the key as the variable name, the value as the content of the
variable.  The content of the variables after the parse will be returned in
the resulting dictionary.  If "Private" is set to 1 the result of any {delay}
will be sent to the player only, otherwise if it is set to 0 the result will
be sent to the rest of the players in the room.  This prim is most useful for
passing values between MPI and MUF, rather than having to resort to formatting
the data into the {&how} variable, or the return value.
This primitives requires at least mucker level 3.





----------------------------------------------------------------------------
                         Database Related Operators
----------------------------------------------------------------------------




DBREF ( i -- d )

  Converts integer i to object reference d.


PROG ( -- d)

  Returns the dbref of the currently running program.


TRIG ( -- d)

  Returns the dbref of the original trigger.


CALLER ( -- d)

  Returns the dbref of the program that called this one, or the dbref of the
trigger, if this wasn't called by a program.


DBTOP ( -- d)

  Returns the dbref of the first object beyond the top object of the database.
'dbtop ok?' would return a false value.


DBCMP ( d1 d2 -- i )

  Performs comparison of database objects d1 and d2. If they are the
same object, then i is 1, otherwise i is 0.
Use of this primitive is deprecated, as dbrefs may be compared with
the standard comparison functions (< <= > >= =).


UNPARSEOBJ (d -- s)

  Returns the name-and-flag string for an object.  It always has the dbref and
flag string after the name, even if the player doesn't control the object.
For example: "One(#1PW)"


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.


SETOWN (d d -- )

  Sets the ownership of the first object to the player given in the second
dbref. (wizbit only)


LOCATION ( d -- d' )

  Returns location of object d as object d'.


MOVETO ( d1 d2 -- )

Moves object d1 to object d2.
  MOVETO is affected by the following rules:
    a) If the object being moved is !JUMP_OK and is it being moved by someone
      other than the object's owner, then the moveto fails.
    b) If the object being moved is a person and either the source or
      destination rooms (if not owned by the person being moved) are
      !JUMP_OK, the moveto fails.
    c) If the object being moved is not a player, is owned by the owner of
      either the source or destination rooms, and either room where the
      ownership matches is !JUMP_OK, the moveto fails.
  The moveto succeeds under any other circumstances.  MOVETO rules follow the
permissions of the current effective userid.  MOVETO will run programs in
the @desc and @succ/@fail of a room when moving a player.


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.


CONTENTS_ARRAY ( d -- a )

  Returns a list array that contains the dbref of every object contained
within the given object.  If a #-1 is returned as the last list item,
then there were too many objects to return all of them.


EXITS ( d -- d' )

  Returns the first exit in the linked exit list of room/player/object d.
This list can be transversed with `next'.


EXITS_ARRAY ( d -- a )

  Returns a list array that contains the dbref of every exit attached to the
given object.  If a #-1 is returned as the last list item, then there were
too many exits to return all of them.


NEXT ( d -- d' )

  Takes object d and returns the next thing in the linked contents/exits
list of d's location.


NEXTOWNED ( d -- d' )

  When called with a player dbref, returns the dbref of the first object they
own.  Subsequent calls to those object dbrefs returns the next object owned
by that same player.  When no more objects are left owned by that player,
#-1 is returned.  The order of the objects is not guarenteed, but when used
correctly, each object owned by that player will be returned exactly once.
The player object itself will NOT be returned.


FINDNEXT ( d1 d2 s1 s2 -- d' )

  Searches for the next object in the database _after_ d1 that is owned by
d2, whose name matches the wildcard pattern s1, and whose flags match
those specified by s2.

  You can start a search with d1 set to #-1.  If d2 is #-1 then ownership
checks will not be performed.  However, only programs with a mucker level
of 3 or better will be allowed to perform non-owner-specific searches, or
searches with an owner different from the effective UID of the program.
If s1 is an empty string, name checks will not be performed.  If s2 is a
null string, then flags will not be checked.

  The s1 name pattern differs from that used by @find, @owned, etc. in
that those commands implicitly treat any patterns as if it has a *
before and after it.  This primitive does NOT.  So for this primitive,
"*.muf" would match only objects whose name ends in ".muf".

  The s2 string is a flagslist that is in the same format as that used by
the @find, @owned, etc. commands.  ie:  "F3!D" will match all muf program
objects in the database that are mucker level 3, and not set debug.

  If there are no more objects in the database that might match all the
search criteria, then #-1 is returned.  Otherwise, the next matching
object is returned.

This primitive is used like this:
    #-1 begin
        me @ "*.muf" "F" FINDNEXT
        dup while
        dup unparseobj .tell
    repeat


NEXTENTRANCE ( d1 d2 -- d3 )

  Searches the database for the next object after d2 that is linked to d1.
You can begin a search by passing #-1 as d2.  The search currently scans
upwards through the database, but this ordering is not guaranteed.  If an
object is found that links to d1, then the dbref of that object is returned.
If no more such objects are found in the db, then #-1 is returned.


CONTROLS ( d1 d2 -- i )

  Takes a player dbref d1 and an object dbref d2, and returns true if the
player has control over the given object.


MATCH ( s -- d )

  Takes string s, first checks all objects in the user's inventory, then
checks all objects in the current room, as well as all exits that the
player may use, and returns object d which contains string s.  If
nothing is found, d = #-1. If ambiguous, d = #-2. If HOME, d = #-3.


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,
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. If HOME, d' = #-3.


PMATCH (s -- d)

  Takes a name and returns the dbref of the player.  If the name does not
match that of a player, #-1 is returned.


PART_PMATCH (s -- d)

  Takes a player name, or the first part of the name, and matches it
against the names of the players who are currently online.  If the
given string is a prefix of the name of a player who is online, then
their dbref is returned.  If two players could be matched by the
given string, it returns a #-2.  If None of the players online match,
then it returns a #-1.


PENNIES ( d -- i )

  Gets the amount of pennies player object d has, or the penny value
of thing d.


ADDPENNIES ( d i -- )

  d must be a player or thing object.  Adds i pennies to object d.
Without Wizard permissions, addpennies may only give players pennies,
limited to between zero and MAX_PENNIES.


MOVEPENNIES (d1 d2 i -- )

  Moves i pennies from player/thing d1 to player/thing d2.  This is the
first step towards making ADDPENNIES require at least ML3 (or wizbit),
for enabling economies.


CHECKPASSWORD ( d s -- i )

  Checks if password string s is valid for player dbref d.  returns 1 on
success, otherwise returns 0.
Wizbit only.


NEWPASSWORD ( d s -- )

  Changed the password of the given player d to s.


SET ( d s -- )

  Sets flag s to object d.  Currently settable things are: abode, chown,
dark, haven, jump, link, sticky.  Boolean operations (e.g. `!abode')
work as expected.


FLAG? ( d s -- i )

  Reads the flag of object d, specified by s, and returns its state: 1 =
on; 0 = off.  The ! token may be used before the name of a flag to negate
the check and check for the absense of the flag.  Different flags may be
supported in different installations.  flag? returns 0 for unsupported or
unrecognized flags.
  You can check the "interactive" flag to see if a player is currently in
a program's READ, or if they are in the MUF editor.
The "Truewizard" flag will check for a W flag with or without the QUELL set.
The "Mucker" flag returns the most significant bit of the mucker level and
the "Nucker" flag returns the least significant bit. (Use MLEVEL instead.)


MLEVEL (d -- i)

  returns the mucker (or priority) level of the given object.


OK? ( x -- i )

  Takes x and returns 1 if x is a type dbref, as well as 0 or above,
below the top of the database, and is not an object of type garbage.


PLAYER? ( d -- i )

  Returns 1 if object d is a player object, otherwise returns 0.
If the dbref is that of an invalid object, it will return 0.


ROOM? ( d -- i )

  Returns 1 if object d is a room, otherwise returns 0.  If the dbref is that
of an invalid object, it will return 0.  A dbref of #-3 (HOME) returns 1.


THING? ( d -- i )

  Returns i as 1 if object d is a thing, otherwise returns i as 0.


EXIT? ( d -- i )

  Returns 1 if object d is an exit object, 0 if otherwise.


PROGRAM? ( d -- i )

  Returns 1 if object d is a program, otherwise returns 0.
If the dbref is that of an invalid object, it will return 0.


SYSPARM ( s -- s )

  Takes a tuneable system parameter and returns its value as a string.  For
an integer it returns it as a string, a time is returned as a string
containing the number of seconds, a dbref is returned in standard dbref
format, and boolean is returned as 'yes' or 'no'
Checking an invalid parameter or a parameter requiring higher permissions
than the program has will return an empty string.

Parameters available:
  (str)  dumpwarn_mesg        - Message to warn of a coming DB dump
  (str)  deltawarn_mesg       - Message to warn of a coming delta dump
  (str)  dumpdeltas_mesg      - Message telling of a delta dump
  (str)  dumping_mesg         - Message telling of a DB dump
  (str)  dumpdone_mesg        - Message notifying a dump is done
  (str)  penny                - A single currency
  (str)  pennies              - Plural currency
  (str)  cpenny               - Capitolized currency
  (str)  cpennies             - Capitolized plural currency
  (str)  muckname             - The name of the MUCK
  (str)  rwho_passwd          - Password for RWHO servers (Wizbit only)
  (str)  rwho_server          - RWHO server to connect to (Wizbit only)
  (str)  huh_mesg             - Message for invalid commands
  (str)  leave_mesg           - Message given when QUIT is used
  (str)  idle_boot_mesg       - Message given to an idle booted user
  (str)  register_mesg        - Message for a failed 'create' at login
  (str)  playermax_warnmesg   - Message warning off too many connects
  (str)  playermax_bootmesg   - Error given when a player cannot connect
  (time) rwho_interval        - Interval between RWHO updates
  (time) dump_interval        - Interval between dumps
  (time) dump_warntime        - Warning prior to a dump
  (time) monolithic_interval  - Max time between full DB dumps
  (time) clean_interval       - Interval between unused object purges
  (time) aging_time           - When an object is considered old and unused
  (time) maxidle              - Maximum idle time allowed
  (int)  max_object_endowment - Max value of an object
  (int)  object_cost          - Cost to create an object
  (int)  exit_cost            - Cost to create an exit
  (int)  link_cost            - Cost to link an exit
  (int)  room_cost            - Cost to dig a room
  (int)  lookup_cost          - Cost to lookup a player name
  (int)  max_pennies          - Max number of pennies a player can own
  (int)  penny_rate           - Rate for finding pennies
  (int)  start_pennies        - Starting wealth for new players
  (int)  kill_base_cost       - Number of pennies for a 100 percent chance
  (int)  kill_min_cost        - Minimum cost for doing a kill
  (int)  kill_bonus           - Bonus for a successful kill
  (int)  command_burst_size   - Maximum number of commands per burst
  (int)  commands_per_time    - Commands per time slice after burst
  (int)  command_time_msec    - Time slice length in milliseconds
  (int)  max_delta_objs       - Max percent of changed objects for a delta
  (int)  max_loaded_objs      - Max percent of the DB in memory at once
  (int)  max_process_limit    - Total processes allowed
  (int)  max_plyr_processes   - Processes allowed for each player
  (int)  max_instr_count      - Max preempt mode instructions
  (int)  instr_slice          - Max uninterrupted instructions per time slice
  (int)  mpi_max_commands     - Max number of uninterruptable MPI commands
  (int)  pause_min            - Pause between input and output servicing
  (int)  free_frames_pool     - Number of program frames pre-allocated
  (int)  listen_mlev          - Minimum MUCKER level for _listen programs
  (int)  playermax_limit      - Manimum allowed connections
  (ref)  player_start         - The home for players without a home
  (bool) use_hostnames        - Do reverse domain name lookup
  (bool) log_commands         - The server logs commands (Wizbit only)
  (bool) log_failed_commands  - The server logs failed commands (Wizbit only)
  (bool) log_programs         - The server logs programs (Wizbit only)
  (bool) dbdump_warning       - Warn about coming DB dumps
  (bool) deltadump_warning    - Warn about coming delta dumps
  (bool) periodic_program_purge - Purge unused programs from memory
  (bool) support_rwho         - Use RWHO server
  (bool) secure_who           - WHO works only in command mode
  (bool) who_doing            - Server support for @doing
  (bool) realms_control       - Support for realm wizzes
  (bool) allow_listeners      - Allow listeners
  (bool) allow_listeners_obj  - Objects can be listeners
  (bool) allow_listeners_env  - Listeners can be up the environment
  (bool) allow_zombies        - Zombie objects allowed
  (bool) wiz_vehicles         - Only wizzes can make vehicles
  (bool) force_mlev1_name_notify - M1 programs forced to show name on notify
  (bool) restrict_kill        - Can only kill KILL_OK players
  (bool) registration         - Only wizzes can create players
  (bool) teleport_to_player   - Allow use of exits linked to players
  (bool) secure_teleport      - Check teleport permissions for personal exits
  (bool) exit_darking         - Players can set exits dark
  (bool) thing_darking        - Players can set objects dark
  (bool) dark_sleepers        - Sleepers are effectively dark
  (bool) who_hides_dark       - Dark players are hidden (Wizbit only)
  (bool) compatible_priorities - Backwards compatibility for exit priorities
  (bool) do_mpi_parsing       - Parse MPI strings in messages
  (bool) look_propqueues      - Look triggers _lookq propqueue
  (bool) lock_envcheck        - Locks will check the environment
  (bool) diskbase_propvals    - Allow diskbasing of property values
  (bool) idleboot             - Enable or disable idlebooting
  (bool) playermax            - Enable or disable connection limit


SYSPARM_ARRAY ( str:pattern -- list:sysparminfo )

  Given an smatch wildcard string pattern, returns a list of dictionaries,
one per each matched @tune parameter (sysparm), containing the information
about each sysparm.  This will only return items for which your program has
permission to read the data.

Each dictionary contains the following data, keyed with these strings:
    "name"     The name of the @tune setting.
    "group"    The logical group that this parameter belongs to.
    "type"     One of "string", "integer", "timespam", "dbref", or "boolean".
    "mlev"     The mucker level required to read the value of this sysparm.
    "value"    The value of the sysparm.  May be an int, string, or dbref.

If a given entry is of the "dbref" type, it will also have the extra field:
    "objtype"  The type of object the dbref is restricted to.  Can be one of
                the strings "player", "thing", "room", "exit", "program",
                "garbage", or "any".



SETSYSPARM ( s1 s2 -- )

  Assigns the @tunable parameter s1 a value given by s2.  s2 must contain a
legal value for s1.  (wizbit only)


NAME ( d -- s )

  Takes object d and returns its name (@name) string field.


SETNAME  ( d s -- )

  Takes object d, and sets the name to s. A program may only set the
names of objects that are owned by the effective user of the program,
or any object if the program is Wizard.  The name of a player can never
be set, since that would normally require a password.


TRUENAME ( d -- s )

  Takes object d and returns its true name string field.
This is the same as name if the MUCK doesn't use anoniminity.


DESC ( d -- s )

  Takes object d and returns its description (@desc) string field.


SETDESC (d s -- )

  Takes object d, and sets the @description string property _/de to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setdesc  "_/de"  swap 0 addprop $enddef


SUCC ( d -- s )

  Takes object d and returns its success (@succ) string field s.


SETSUCC (d s -- )

  Takes object d, and sets the @success string property _/sc to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setsucc  "_/sc" swap 0 addprop $enddef


FAIL ( d -- s )

  Takes object d and returns its fail (@fail) string field.


SETFAIL (d s -- )

  Takes object d, and sets the @fail string property _/fl to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setfail  "_/fl" swap 0 addprop $enddef


DROP ( d -- s )

  Takes object d and returns its drop (@drop) string field.


SETDROP (d s -- )

  Takes object d, and sets the @drop string property _/dr to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setdrop  "_/dr" swap 0 addprop $enddef


OSUCC ( d -- s )

  Takes object d and returns its osuccess (@osucc) string field.


SETOSUCC (d s -- )

  Takes object d, and sets the @osuccess string property _/osc to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setosucc  "_/osc" swap 0 addprop $enddef


OFAIL ( d -- s )

  Takes object d and returns its ofail (@ofail) string field.


SETOFAIL (d s -- )

  Takes object d, and sets the @ofail string property _/ofl to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setofail  "_/ofl" swap 0 addprop $enddef


ODROP ( d -- s )

  Takes object d and returns its odrop (@odrop) string field.


SETODROP (d s -- )

  Takes object d, and sets the @odrop string property _/odr to s.
If the program is Mucker Level 1 or 2, then it may only set this property
on objects that are owned by the player that the program is running with
the permissions of.  This is actually a $define that uses addprop.  This
is identical to:
    $define setodrop  "_/odr" swap 0 addprop $enddef


GETLINK ( d -- d' )

  Returns what object d is linked to, or #-1 if d is unlinked.  The
interpretation of link depends on the type of d: for an exit, returns
the room, player, action, or thing that the exit is linked
to.  For a player or thing, it returns its `home', and for
rooms returns the drop-to.


GETLINKS ( d -- dn..d1 n )

  Returns what objects d is metalinked to.  If d is an unlinked exit
or a room with no dropto, getlinks returns 0.  A count of
1 and #-3 is returned if the dropto is linked to HOME.


GETLINKS_ARRAY ( d -- a )

  Returns a list array that contains the dbref of every object that the
given object is linked to.


SETLINK     ( d1 d2 -- )

  Takes an exit dbref d1, and sets its destination to d2.  You must have
control of the exit, and if the exit is already linked, it must be unlinked
first by doing setlink with #-1 as the destination.


SETLINKS_ARRAY ( ref:Obj arr:Destinations -- )

  Sets the destinations/dropto/home of "Obj" to "Destinations".  Objects may be
unlinked by passing in an empty array.


TIMESTAMPS ( d -- i i2 i3 i4 )

  Returns the following for a program, the time created (i), the time last
modified (i2), the time last used (i3), and the number of uses(i4) for
any object.


STATS ( d -- total rooms exits things programs players garbage )

  Returns the number of objects owned by 'd', or the total objects in
the system if d == #-1. This is broken up into a total, rooms, exits,
things, programs, players, and garbage. This functions much as the
@STAT command.
(Needs Mucker Level 3)


OBJMEM ( d -- i )

  Returns the current number of bytes in use by the given object.


COPYOBJ ( d -- d' )

  Creates a new object (returning d' on top of the stack), that is a
copy of object d. Each program is allowed to create only one new
object per run.


COPYPLAYER ( d1 s1 s2 -- d2 )

  Creates a new player object with the name s1, and the password s2, and the
properties, flags, links, etc. of the template object d1.  This returns
the dbref of the newly created player object.


TOADPLAYER ( d1 d2 -- )

  @toads player d2, and chowns all their posessions to player d1.
You can't toad wizard players.


NEWPLAYER ( s1 s2 -- d )

  Creates a new player object, with the name s1, and the password s2.
This returns the dbref of the new player object.


NEWROOM (d s -- d)

  Takes the dbref of the parent and the name of the room. It returns the
dbref of the created room. Owner is the person running the program.
(program must have a wizbit)


NEWOBJECT (d s -- d)

  Takes location and name and returns new thing's dbref.
Owner is the person running the program.
(program must have a wizbit)


NEWEXIT (d s -- d)

  Takes location and name and returns new exit's dbref.
Owner is the person running the program.
(program must have a wizbit)


NEWPROGRAM ( s -- d )

  Creates a new program object with the given name, and returns its dbref.


RECYCLE (d -- )

  Recycles the given object d.  Will not recycle players, the global
environment, the player starting room, or any currently running program.
(Can recycle objects owned by uid if running with Mucker Level 3
permissions.  Can recycle other people's items with wizbit)


IGNORING? ( ref:Player1 ref:Player2 -- int:Result )

  Returns true if either player has an ignore set for the other.  If one of
the players is an unquelled wizard this will always return false.
This primitive requires at least Mucker Level 3.


IGNORE_ADD ( ref:Player ref:Who -- )

  Adds the player "Who" to "Player"'s ignore list.
This primitive requires at least Mucker Level 3.


IGNORE_DEL ( ref:Player ref:Who -- )

  Removes the player "Who" from "Player"'s ignore list.
This primitive requires at least Mucker Level 3.


ARRAY_GET_IGNORELIST ( ref:Player -- list:Players )

  Returns a list array of players "Player" is ignoring.
This primitive requires at least Mucker Level 3.





----------------------------------------------------------------------------
                        Time Manipulation Operators
----------------------------------------------------------------------------




TIME ( -- s m h )

  Returns the time of day as integers on the stack, seconds, then minutes,
then hours.


DATE ( -- i i i)

  Returns the monthday, month, and year.  ie:  if it were February 6, 1992,
date would return 6 2 1992 as three integers on the stack.


SYSTIME ( -- i )

  Returns the number of seconds from Jan 1, 1970 GMT. This is compatible with
the system timestamps and may be broken down into useful values through
'timesplit'.


SYSTIME_PRECISE ( -- f )

  Returns the number of seconds from Jan 1, 1970 GMT as a floating point
number, with microsecond accuracy.


GMTOFFSET ( -- i)

  Returns the machine's offset from Greenwich Mean Time in seconds.


TIMESPLIT ( i -- is im ih id im iy iw iyd )

  Splits a systime value into 8 values in the following order: seconds,
minutes, hours, monthday, month, year, weekday, yearday.  Weekday starts
with sunday as 1, and yearday is the day of the year (1-366).


TIMEFMT (s i -- s)

  Takes a format string and a SYSTIME integer and returns a string formatted
with the time.  The format string is ascii text with formatting commands:
  %% -- "%"
  %a -- abbreviated weekday name.
  %A -- full weekday name.
  %b -- abbreviated month name.
  %B -- full month name.
  %C -- "%A %B %e, %Y"
  %c -- "%x %X"
  %D -- "%m/%d/%y"
  %d -- month day, "01" - "31"
  %e -- month day, " 1" - "31"
  %h -- "%b"
  %H -- hour, "00" - "23"
  %I -- hour, "01" - "12"
  %j -- year day, "001" - "366"
  %k -- hour, " 0" - "23"
  %l -- hour, " 1" - "12"
  %M -- minute, "00" - "59"
  %m -- month, "01" - "12"
  %p -- "AM" or "PM"
  %R -- "%H:%M"
  %r -- "%I:%M:%S %p"
  %S -- seconds, "00" - "59"
  %T -- "%H:%M:%S"
  %U -- week number of the year. "00" - "52"
  %w -- week day number, "0" - "6"
  %W -- week# of year, starting on a monday, "00" - "52"
  %X -- "%H:%M:%S"
  %x -- "%m/%d/%y"
  %y -- year, "00" - "99"
  %Y -- year, "1900" - "2155"
  %Z -- Time zone.  "GMT", "EDT", "PST", etc.


SLEEP (i -- )

  Makes the program pause here for 'i' seconds.  the value of i cannot
be negative.  If the sleep is for more than 0 seconds, then the program
may not thereafter use the READ primitive.





----------------------------------------------------------------------------
                        Process Management Operators
----------------------------------------------------------------------------




MODE ( -- i)

  Returns an integer denoting the current multitasking mode.  This ignores
BOUND bits on programs.  The integer this returns will be the same as
one of those defined by the standard $defines bg_mode, fg_mode, and
pr_mode, being background, foreground, and preempt mode, respectively.


SETMODE (i -- )

  Sets the current multitasking mode to the given mode.  The integer this
uses will be the same as one of those defined by the standard $defines
bg_mode, fg_mode, and pr_mode, being background, foreground, and preempt
mode, respectively.  Programs set BOUND will run PREEMPT, ignoring this
mode.


PR_MODE ( -- i)

  This is a standard built in $define.  This is used with MODE and
SETMODE to show what mode the program is running in, or to set what mode
it will run in.  For example, MODE returns an integer on the stack, that
you can compare against PR_MODE, FG_MODE, or BG_MODE, to determine what
mode the program is in.  PR_MODE is preempt mode, and is defined as 0.


FG_MODE ( -- i)

  This is a standard built in $define.  This is used with MODE and
SETMODE to show what mode the program is running in, or to set what mode
it will run in.  For example, MODE returns an integer on the stack, that
you can compare against PR_MODE, FG_MODE, or BG_MODE, to determine what
mode the program is in.  FG_MODE is foreground mode, and is defined as 1.


BG_MODE ( -- i)

  This is a standard built in $define.  This is used with MODE and
SETMODE to show what mode the program is running in, or to set what mode
it will run in.  For example, MODE returns an integer on the stack, that
you can compare against PR_MODE, FG_MODE, or BG_MODE, to determine what
mode the program is in.  BG_MODE is background mode, and is defined as 2.


PREEMPT ( -- )

  Prevents a program from being swapped out to do multitasking.  Needed in
some cases to protect crucial data from being changed while it is being
worked on.  A program will remain in preempt mode until it's execution is
completed.  Basically what this command does is to turn off multitasking,
but then you have a limit on how many instructions you can run without
needing either to pause with a SLEEP, or have a wizbit on the program.
This primitive is actually an inserver $define to 'pr_mode setmode'.


FOREGROUND ( -- )

  To turn on multitasking, you can issue a foreground command.  While a
program is in foreground mode, the server will be multitasking and
handling multiple programs at once, and input from other users, but it
will be blocking any input from the user of the program until the program
finishes.  You cannot foreground a program once it is running in the
background. A program will stay in foreground mode until it finishes
running or until you change the mode.
This primitive is actually an inserver $define to 'fg_mode setmode'.


BACKGROUND ( -- )

  Another way to turn on multitasking is to use the background command.
Programs in the background let the program user go on and be able to do
other things while waiting for the program to finish.  You cannot use
the READ command in a background program.  Once a program is put into
background mode, you cannot set it into foreground or preempt mode.
A program will remain in the background until it finishes execution.
This primitive is actually an inserver $define to 'bg_mode setmode'.


QUEUE (i d s -- i)

  Takes a time in seconds, a program's dbref, and a parameter string.  It
will execute the given program with the given string as the only string on
the stack, after a delay of the given number of second.  Returns  the pid
of the queued process, or 0 if the timequeue was full.
(Requires Mucker Level 3)


FORK ( -- i)

  This primitive forks off a BACKGROUND (muf) process from the currently
running program.  It returns the pid of the child process to the parent
process, and returns a 0 to the child.  If the timequeue was full, then
it returns a -1 to the parent process, and there is no child process.
(Requires Mucker Level 3)


KILL (i -- i)

  Attempts to kill the process referred to by the given process ID.
Returns 1 if the process existed, and 0 if it didn't.
(Requires Mucker Level 3)


PID ( -- i)

  Returns the process ID of the program that is currently running.


ISPID? (i -- i)

  Takes a process id and checks to see if an event with that pid is in the
timequeue.  It returns 1 if it is, and 0 if it is not.  ispid? will also
return 1 if the given process id is that of the currently running program.
This primitive requires at least mucker level 3.


GETPIDS ( ref:obj -- list:pids )

  If obj is a program dbref, this will return a list of the process IDs
of every active process that has the given program in their call stack.
If obj is a player dbref, this will return a list of all the PIDs assigned to
that player.  If obj is a trigger dbref, it will return all the active PIDs
associated with that trigger.   And finally, if obj is #-1, then all active
PIDs will be included in the array that gets returned.


GETPIDINFO ( int:pid -- dict:info )

  Given a valid active PID, returns a dictionary with information about
that process. The information returned is:
    CALLED_DATA - The string the program was queued with, if any
    CALLED_PROG - The program dbref# of the process' current call level.
    CPU         - The amount of CPU time used up by the process.
    DESCR       - The descriptor that called the program.
    INSTCNT     - The number of instructions run so far.
    NEXTRUN     - When the process is due to run again.
    PID         - That process ID.
    PLAYER      - The player dbref that PID belongs to.
    STARTED     - Systime in seconds when the process started.
    SUBTYPE     - Additional information about the process.
    TRIG        - The trigger that called that process.
    TYPE        - What type of process it is. MUF/MPI.


INSTANCES ( d -- i )

  Returns the number of active instances of the given program.  Ie: the
number of active processes that are running, using the given program.


COMPILE ( d i1 -- i2 )

  Compiles the given program.  If i1 is true, errors and warnings are printed
out to the user.  If the program fails to compile, this returns 0.  If the
compile is successful, this returns the number of compiled instructions.
This will throw an error if the program has any current instances running.


UNCOMPILE ( d -- )

  Uncompiles the given muf program.  This will throw an error if the program
has any current instances running.


COMPILED? ( d -- i )

  Returns 0 if the given program is not compiled.  Otherwise returns the
number of compiled instructions.


PROGRAM_GETLINES ( d i1 i2 -- a )

  Returns a list array of strings containing the muf program lines in
program d, from line i1 to line i2, inclusive.  If both i1 and i2 are
zero, then the entire program is returned.  If i1 is zero, it is assumed
to mean the first line.  If i2 is zero, it is assumed to mean the very
last line.  If i1 and i2 are the same, and non-zero, then only that line
will be returned, as a list array with a single string element.  The target
program must be controlled by the current program's UID, be set VIEWABLE,
or the current program must be running with wizard permissions.


PROGRAM_SETLINES ( ref:Program list:Lines -- )

  Sets all the lines of the given program to the lines in the array.
This primitive requires at least mucker level 4.





----------------------------------------------------------------------------
                      Connection Management Operators
----------------------------------------------------------------------------




DESCR ( -- i)

  Returns the descriptor number that invoked this program.  The value
returned may be -1 in the case of listener or autostart programs.


AWAKE? ( d -- i )

  Passed a players dbref, returns the number of connections they have to
the game. This will be 0 if they are not connected.


ONLINE ( -- d ... i )

  Returns a dbref for every connection to the server, and lastly the number
of connections.


ONLINE_ARRAY ( -- a )

  Returns a single stack item, which is a list array, containing a dbref for
every connection to the server.


CONCOUNT ( -- i)

  Returns how many connections to the server there are.
(Requires Mucker Level 3)


CONDBREF (i -- d)

  Returns the dbref of the player connected to this connection.
(Requires Mucker Level 3)


CONTIME (i -- i)

  Returns how many seconds the given connection has been connected
to the server.  (Requires Mucker Level 3)


CONIDLE (i -- i)

  Returns how many seconds the connection has been idle.
(Requires Mucker Level 3)


CONUSER (i -- s)

  Returns the username of the connection. (wizbit only)


CONHOST (i -- s)

  Returns the hostname of the connection. (wizbit only)


CONBOOT (i -- )

  Takes a connection number and disconnects that connection from
the server.  Basically @boot for a specific connection. (wizbit only)


CONNOTIFY (i s -- )

  Sends a string to a specific connection to the server.
(Requires Mucker Level 3)


CONDESCR ( i -- i )

  Takes a connection number and returns the descriptor number associated
with it.  (Requires Mucker Level 3)  See DESCRIPTORS, DESCRCON.


DESCRCON (i -- i)

  Takes a descriptor and returns the associated connection number,
or 0 if no match was found.
(Requires Mucker Level 3)


DESCRDBREF (i -- d)

  Returns the dbref of the player connected to this descriptor number.
This may return #-1 if there is no player connected to the given descriptor.
(Requires Mucker Level 3)


DESCRTIME (i -- i)

  Returns how many seconds the given descriptor connection has been connected
to the server.  (Requires Mucker Level 3)


DESCRIDLE (i -- i)

  Returns how many seconds the descriptor connection has been idle.
(Requires Mucker Level 3)


DESCRLEASTIDLE (d -- i)

  Returns the descriptor number for the least idle connection of the given
player dbref.  (Requires Mucker Level 3)


DESCRMOSTIDLE (d -- i)

  Returns the descriptor number for the most idle connection of the given
player dbref.  (Requires Mucker Level 3)


DESCRSECURE? (d -- i)

  Returns 1 if the descriptor number corresponds to a secure connection, and
0 otherwise. (Requires Mucker Level 3)


DESCRHOST (i -- s)

  Returns the hostname of the descriptor connection. (wizbit only)


DESCRUSER (i -- s)

  Returns the username of the descriptor connection. (wizbit only)


DESCRBOOT (i -- )

  Takes a descriptor number and disconnects that connection from
the server.  Basically @boot for a specific descriptor connection.
(wizbit only)


DESCRNOTIFY (i s -- )

  Sends a string to a specific descriptor connection, similar to NOTIFY.
(Requires Mucker Level 3)


FIRSTDESCR (d -- i)

  Returns the first descriptor number associated with the given player.
If the player object is given as #-1, then this returns the first descriptor
in the list of all connections.


NEXTDESCR (i -- i)

  Takes a descriptor number, and returns the next connected descriptor
number.  To get the first descriptor number, use '1 condescr'.  Between
these, you can step through the descriptors list.  If you try to use
nextdescr on an invalid descriptor, it will return 0.  If you have
reached the end of the descriptor list, it returns 0.
(Requires Mucker Level 3)


LASTDESCR (d -- i)

  Returns the last descriptor number associated with the given player.
If the player object is given as #-1, then this returns the last descriptor
in the list of all connections.


DESCRFLUSH (i -- )

  Flushes the output text on the given descriptor.  If i is -1, flushes
output on all descriptors.
(Requires Mucker Level 3)


DESCRIPTORS (d -- ix...i1 i)

  Takes a player dbref, or #-1, and returns the range of descriptor numbers
associated with that dbref (or all for #-1) with their count on top.
Descriptors are numbers that always stay the same for a connection, while
a connection# is the relative position in the WHO list of a connection.


DESCR_ARRAY (d -- a)

  Takes a player dbref, or #-1, and returns a list array that contains the
current descriptor numbers associated with that dbref.  (Or all connected
descriptors, if the dbref is #-1)  This can return an empty list if there
are no connections for that player.  This is effectively the same as the
sequence 'descriptors array_make', but doesn't overflow the stack if too
many descriptors are available.  Descriptors are numbers that always stay
the same for a connection, while a connection# is the relative position
in the WHO list of a connection.


DESCR_SETUSER ( i d s -- i )

  Reconnects descriptor i to the player with dbref d and password s.  It first
disconnects from the old dbref, then connects the new one, as if QUIT was
typed then the new character was logged in.  If the password doesn't match
the player's password, then it gives a permission denied error.  This
returns a 1 if successful or a 0 if the given descriptor wasn't found.
Wizbit only.


DESCRBUFSIZE ( int:dscr -- int:bytes )

  Returns the number of bytes of free space in the given descriptor's output
buffer.  If more data is written to the buffer than it has space for, the
data at the beginning of the buffer gets erased with an <output flushed>.
Remember that each NOTIFY adds a CR LF byte pair at the end of each line.
Also note that \r in lines gets translated to CR LF byte pairs.





----------------------------------------------------------------------------
                          Event Handling Operators
----------------------------------------------------------------------------




EVENT_COUNT ( -- i )

  Returns the number of pending events waiting to be processed with EVENT_WAIT.


EVENT_EXISTS ( s -- i )

  Returns the number of pending events that have the given eventid type.
The given eventid type can be an smatch wildcard pattern.


EVENT_WAIT ( -- ? s )

  This is an inserver muf macro, that expands to '0 array_make event_waitfor'
See: EVENT_WAITFOR


EVENT_WAITFOR (a -- ? s )

Waits for an event to occur that matches one of the eventIDs given in the
string list array.  The comparison is NOT case sensitive, and you may use
smatch wildcard patterns.  If a matching event isn't in the event queue
already, this will pause the MUF process until a matching event is added
to the queue.  The first matching event to become available will be removed
from the event queue.  This returns an event-specific context data item,
and the matching eventID string.  If an empty list array is passed to this
primitive, then it will match any and all events, and return the first one
pending.

Timer events have eventID strings that are created by prepending "TIMER."
to the timerID passed to the TIMER_START primitive.  The context for Timer
events is an integer, representing the systime that the timer event was
scheduled to occur at.  This might not be the time that the event is actually
processed at, due to system delays.

GUI events have eventID strings that are created by prepending "GUI." to
the dlogID of the dialog that generated the event.  The context for GUI
events is a dictionary contains the following keys:
descr      Holds the descriptor that generated the event.
dlogid     Holds the DlogID of the dialog that generated the event.
id         Holds the ID of the control that generated the event.
dismissed  Holds 1 if the dialog was dismissed, 0 otherwise.
event      Holds the type of gui event.  ie: buttonpress, menuselect.
values     Holds the dictionary of control values, keyed by control name.
data       Holds array of extra gui-event specific data.

User events have eventID strings that are created by prepending "USER." to
the eventID given to the EVENT_SEND muf primitive.  The context for User
events is a dictionary containing the following keys:
caller_pid   Holds the integer Process ID of the sending program.
caller_prog  Holds the dbref of the sending program.
data         Holds the stack item sent by the EVENT_SEND primitive.
descr        Holds the descr that initiated the calling program.
trigger      Holds the trigger dbref that initiated the calling program.
player       Holds the player dbref that ran the calling program.
prog_uid     Holds the dbref of the player whose permissions the caller
               program is running as.

MCP events have eventID strings formatted like "MCP.packagename-mesgname"
where 'packagename' is the name of the MCP package being invoked, and
'mesgname' is the specific message in the package being invoked.  If the
'mesgname' is a null string, then the trailing '-' is removed.
Some example MCP eventIDs are:
    MCP.com-belfry-image       Where pkg is 'com-belfry-image' & mesg is ''
    MCP.com-belfry-image-view  Where pkg is 'com-belfry-image' & mesg is 'view'
The context for MCP events is a dictionary containing the following keys:
    descr     Holds the integer descriptor of the sending connection.
    package   Holds the string package name the MCP mesg is sent for.
    message   Holds the string message name within that package.
    args      Holds a dictionary, containing the message arguments.
                Each mesg arg has an array list of strings as a value.

Read events have eventID strings of just "READ".  The context of Read events
is the integer descriptor of the first waiting line to be READ.  To get the
actual line sent by the user you need to use the READ primitive.

Process exit events have eventID strings that are created by prepending
"PROC.EXIT." to the pid of the watched process that exited.  The context
is the pid of the process that exited.


EVENT_SEND ( i s ? -- )

  Sends a "USER." event to the process referred to by the given pid.
The target process will receive an event that can be read with EVENT_WAIT.
The event type will be "USER." with the given event id string appended
to it.  The given event id string will be truncated at 32 characters.
The receiving process will be passed a dictionary with items "data" for
the given arbitrary stack element, "caller_pid" with the pid of the
process calling EVENT_SEND, and "caller_prog" with the dbref of the
program calling EVENT_SEND.
ie: '23 "foobar" 3.1416 event_send' will send an event to process 23, with
an eventid of "USER.foobar", and a floating point data value of 3.1416.
This primitive requires at least Mucker Level 3.


TIMER_START ( i s -- )

  Requests that a timer event be sent to this program in i seconds,
with an event name of "TIMER."  with the given string appended.  ie:
'5 "one" timer_start' will cause a "TIMER.one" event to be sent to
the program in 5 seconds.  This is used with EVENT_WAIT.  If a timer
with the given timerid already exists, it will be rescheduled to occur
after the new delay.  Timer ids will be truncated to 32 characters.
Each MUF process can only have a limited number of timers, specified
by the @tune setting 'process_timer_limit'.  Timers are listed on
the @ps timequeue with the PID of the timer's process in parentheses.
Timers are one-shot events.  To get a repeating timer, you'll need to
restart it when you process a new timer event.


TIMER_STOP ( s -- )

  Stops the timer with the given timerid, if it exists.  If there is
already a timer event on the event queue, it will STAY on the queue
until processed.  As with the timer_start primitive, the "TIMER." part
of the event name is assumed.  '"first" timer_stop' will stop the timer
created by '5 "first" timer_start'.  Timer ids ARE case sensitive.


WATCHPID (d -- )

  Sends a "PROC.EXIT." event to the current process when the process referred
to by the given pid exits.  If the process process does not exist, the event
will be sent immediately.  The exit event can be retrieved by a call to
EVENT_WAIT.  The event type will be "PROC.EXIT." with the pid of the process
appended to it.  The pid will also be returned as the data value from the
event.  This primitive requires at least Mucker Level 3.





----------------------------------------------------------------------------
                           MCP Support Operators
----------------------------------------------------------------------------




MCP_REGISTER ( strPkgName fltMinVers fltMaxVers -- )

  Registers an MCP package so that clients can know what is supported.
The minimum and maximum versions supported are represented as floating
point numbers, with the minor version number being divided by 1000.
For example, an MCP package of version 1.1 is represented as 1.001,
and a version of 1.23 is represented as 1.023.  This lets you use
mathematical compares to check version numbers.


MCP_REGISTER_EVENT ( strPkgName fltMinVers fltMaxVers -- )

  Registers an MCP package so that clients can know what is supported,
and marks this process as wanting to receive MCP messages as Muf Events.
These events can be read with EVENT_WAIT, and will have event ids starting
with "MCP.", followed by the package and message names.  The event data
will be a dictionary, containing "descr", "package", "message", and "args"
elements.  The args element will have a dictionary of message arguments
as it's value.  The minimum and maximum package versions supported are
represented as floating point numbers, with the minor version number being
divided by 1000.  For example, an MCP package of version 1.1 is represented
as 1.001, and a version of 1.23 is represented as 1.023.  This lets you
use arithmetic compares to check version numbers.  Since this primitive
arranges for MCP messages to be received as muf events, there is no need
to use the MCP_BIND primitive with this.  A side benefit is that _any_ MCP
message sent for this package can be caught, not just the ones you bound.
Also, the process that will handle the events is kept alive, so your data
stored in variables, or on the stack, is kept.


MCP_BIND ( strPkgName strMesgName addrCallback -- )

  Binds a specific message, so if it is received, the given function is
called.  The callback function is assumed to accept the args:
( intDescr dictArgs -- ) where dictArgs is a dictionary array contain-
ing key-value pairs that represent the arguments of the message.  Each
argument can either have a string value, or a list array of strings,
where the list array is used for multi-line values.


MCP_SUPPORTS ( intDescr strPkgName -- fltVersion )

  Returns the version number of this package that is supported by this
connection descriptor.  If this package isn't supported, returns 0.0
The version number is represented as a floating point number, with the
minor version number being divided by 1000.  For example, an MCP
package of version 1.1 is represented as 1.001, and a version of 1.23
is represented as 1.023.  This lets you use mathematical compares to
check version numbers.


MCP_SEND ( intDescr strPkgName strMsgName dictArgs -- )

  Sends an MCP message for the given package to the given connection
descriptor.  dictArgs contains key-value pairs, where each key is
an argument name, and the value is the argument value.  Values can
be strings, floats, dbrefs, integers, or array lists of strings.
They all get translated into an appropriate string format before
getting sent.





----------------------------------------------------------------------------
                           GUI Support Operators
----------------------------------------------------------------------------




GUI_AVAILABLE (intDescr -- fltVersion)

  Returns the floating point version number of the MCP GUI protocol
supported by the given descriptor's connection.  The version is
encoded in the number such that major version 8, minor version 12
is represented as 8.012.  If the MCP protocol is not available on
that descriptor, then 0.0 is returned.


GUI_DLOG_CREATE (intDescr strType strTitle dictArgs -- strDlogID)

  If a user has a client that can support the MCP GUI protocol, then this
primitive can be used to generate a dialog on their screen.  The intDescr
is the integer descriptor of the connection to show the dialog on. The
strType is the type of the dialog to create.  Currently, the only options
for strType are D_SIMPLE, D_TABBED, or D_HELPER.  The strTitle argument
is the title to show in the titlebar of the dialog.  dictArgs is a
dictionary array that contains extra optional arguments for creating
the dialog.

This primitive returns a string containing the dialogid, used by other
prims to add controls or make various changes.  This dialog will be
hidden and not shown to the user until it has been displayed with the
GUI_DLOG_SHOW command.

Supported optional args are:
    names      list of user-viewable pane names for D_TABBED & D_HELPER dlogs.
    panes      list of pane ids for D_TABBED and D_HELPER dialogs.
    width      requested width of dialog in pixels.
    height     requested height of dialog in pixels.
    resizable  allows resizing in "x", "y", or "both" dimensions.
    minwidth   minimum width of window in pixels.
    minheight  minimum height of window in pixels.
    maxwidth   maximum width of window in pixels.
    maxheight  maximum height of window in pixels.


GUI_DLOG_SIMPLE (intDescr strTitle -- strDlogID)

  If a user has a client that can support the MCP GUI protocol, then
this primitive can be used to generate a simple dialog on their
screen.  By "simple" I mean just an empty window with no controls.
The intDescr argument specifies what connection descriptor to
create the dialog for (ie: what user's screen to show it on), and
the strTitle arg specifies what the title of the dialog will be.
This returns a string containing the dialogid, used by other prims
to add controls or make various changes.  This dialog will be hidden
and not shown to the user until it has been displayed with the
GUI_DLOG_SHOW command.  GUI_DLOG_SIMPLE is actually an inserver
convenience macro that uses GUI_DLOG_CREATE.


GUI_DLOG_TABBED (intDescr strTitle dictPages -- strDlogID)

  If a user has a client that can support the MCP GUI protocol, then
this primitive can be used to generate a tabbed dialog on their
screen.  By "tabbed" I mean a window with a tabbed notebook, similar
to Win95 "property sheets", with three standard buttons at the bottom.
The standard buttons return values of "_ok", "_cancel", and "_apply".
The intDescr argument specifies what connection descriptor to create
the dialog for (ie: what user's screen to show it on).  The strTitle
arg specifies what the title of the dialog will be.  The dictPages
argument is a dictionary array of page ids and display names to be
created.  (ids as dictionary keys, display names as vals) This prim
returns a string containing the dialogid, used by other prims to add
controls or make various changes.  When you create a new control, you
can specify which page to put it in by passing a pageid in as the
value of the "pane" argument.  This dialog will be hidden and not
shown to the user until it has been displayed with the GUI_DLOG_SHOW
command.  GUI_DLOG_SIMPLE is actually an inserver convenience macro
that uses GUI_DLOG_CREATE.


GUI_DLOG_HELPER (intDescr strTitle dictPages -- strDlogID)

  If a user has a client that can support the MCP GUI protocol, then
this primitive can be used to generate a helper dialog on their
screen.  By "helper" I mean a dialog similar to a Win95 wizard dialog.
The standard buttons return values of "_cancel", and "_finish".
The intDescr argument specifies what connection descriptor to
create the dialog for (ie: what user's screen to show it on), and
the strTitle arg specifies what the title of the dialog will be.
The dictPages argument is a dictionary array of page ids and display
names to be created.  (ids as dictionary keys, display names as vals)
This returns a string containing the dialogid, used by other prims
to add controls or make various changes.  When you create a new
control, you can specify which page to put it in by passing a pageid
in as the value of the "pane" argument.  This dialog will be hidden
and not shown to the user until it has been displayed with the
GUI_DLOG_SHOW command.  GUI_DLOG_SIMPLE is actually an inserver
convenience macro that uses GUI_DLOG_CREATE.


GUI_DLOG_SHOW (strDlogID -- )

  Forces a given dialog to be shown to the user.  The strDlogId is what
was returned by the GUI_DLOG_CREATE (or similar) command.


GUI_DLOG_CLOSE (strDlogID -- )

  Forces a given dialog to be closed and destroyed.  The strDlogId is
what was returned by the GUI_DLOG_CREATE (or similar) command.


GUI_CTRL_CREATE (strDlogID strType strCtrlID dictArgs -- )

  Creates a new control in a given dialog.  strDlogID contains the dlogid
returned from a GUI_DLOG_SIMPLE (or similar) command.  strType contains
the control type.  To make debugging easier and faster, MUF $defs have
been provided for each control type.  They are:
C_DATUM, C_LABEL, C_IMAGE, C_HRULE, C_VRULE, C_BUTTON, C_CHECKBOX,
C_RADIOBTN, C_EDIT, C_MULTIEDIT, C_COMBOBOX, C_SPINNER, C_SCALE,
C_LISTBOX, C_MENU, C_FRAME, C_NOTEBOOK.
If you use these instead of the actual type name strings, then if you
mistype one, it will throw an error when trying to compile, instead of
when you try to run it.  The strCtrlID arg is the id to give the control,
for use in reading the values back later, or modifying the control.
dictArgs is used to pass any other arguments needed to create the control.
This will be used by almost all controls.  It is a dictionary array that
contains argnames as keys, each with an argument value.


GUI_VALUES_GET (strDlogID -- dictValues)

  Returns a dictionary containing all the control values for the given
dialog.  The keys are the control ids.


GUI_VALUE_GET (strDlogID strCtrlID -- arrValue)

  This gets the current value of the given GUI control, and returns it as a
string list array.


GUI_VALUE_SET (strDlogID strCtrlID strValue -- )

  Sets the value of a given control in a given dialog.


GUI_CTRL_COMMAND (strDlogID strCtrlID strCommand dictArgs -- )

  This is the generic primitive for executing a GUI control specific command.
The dictionary contains the arguments for the given command.

At the time of this writing, the following commands are supported:

"insert" Inserts text or list items into the given control.
        Takes the following arguments:
        "values" list of values or text to insert.
        "before" position in widget to insert before.  Defaults to "end".

"delete" Deletes text or list items from the given control.
        Takes the following arguments if the widget is a listbox:
        "items" The list of listbox items to delete, given by index.
        Takes the following arguments if the widget is not a listbox:
        "first" gives the first item to delete.
        "last"  gives the last item of the range to delete.  If not given,
                this defaults to the same value as "first".

"select" Selects text or list items in the given control.
        Takes the following arguments if the widget is a listbox:
        "items" The list of listbox items to select, given by index.
                All other items will be deselected.
        Takes the following arguments if the widget is not a listbox:
        "first" gives the first character to select.
        "last"  gives the last character of the range to select.  If not
                given, this defaults to the same value as "first".

"show"   Scrolls the given item or character into view.
        Takes the following arguments:
        "position" The item or character position to make visible.

"cursor" Moves the cursor of the given control.
        Takes the following arguments:
        "position" The item or character to move the cursor to or before.


MCP GUI Options:

  The MCP GUI package has several common options used when creating controls
in dialog.  These options are common to almost all control types.  They
are as follows:
    value     Holds the value of the control.
    valname   Specifies the name used with GUI_VALUE_GET/SET, to refer to the
            value for this control.  Multiple controls can share the same
            valname, in the case of radio buttons and the like.
    report    If set to 1, image, checkbox, and radiobutton controls will send
            a 'buttonpress' event when the user clicks on them.  All other
            control types send a 'valchanged' gui event when their value
            is changed If the value is changed several times within a few
            seconds, only the final value is guaranteed to have a valchanged
            event.  It is possible to receive valchanged events even though
            the value appears to have not changed.
    pane      The pane in which to place this control.  Some controls, like
            the notebook or frame controls, create new panes in which you
            can place controls.
    newline   If 1, next control will be at the beginning of the next row.
            If 0, next control will be in the next column to the right,
            taking into account colspan and colskip.  Defaults to 1.
    sticky    Which sides of the cell this control sticks to.  This is a
            string with any or all of the letters 'n', 's', 'e', or 'w',
            corresponding to north, south, east, and west.
    row       If given, forces the control to be placed in the given row.
    column    If given, forces the control to be placed in the given column.
    rowspan   Number of rows this control spans across.  Defaults to 1.
    colspan   Number of columns this control spans across.  Defaults to 1.
    colskip   Number of columns to skip before placing this control.
            Defaults to 0.
    minwidth  Minimum width of control in pixels.
    minheight Minimum width of control in pixels.
    hweight   How much the starting column of this control should expand.
            When filling unused space, if there are two columns, one with
            hweight 2 and the other with hweight 1, then the column with
            hweight 2 will be expanded twice as much as the other column.
            The default hweight is 0.  Note that the last control in the
            given column sets the hweight for the column.  If no hweights
            are given in a pane, then if the pane is forced to be wider
            than the contained controls, the empty space will be placed
            in the right side of the pane.
    vweight   How much the starting row of this control should expand.
            When filling unused space, if there are two rows, one with
            vweight 2 and the other with vweight 1, then the row with
            vweight 2 will be expanded twice as much as the other row.
            The default hweight is 0.  Note that the last control in the
            given row sets the vweight for the row.  If no vweights
            are given in a pane, then if the pane is forced to be taller
            than the contained controls, the empty space will be placed
            in the bottom of the pane.
    toppad    Number of pixels padding to add above this control.
    leftpad   Number of pixels padding to add to the left of this control.


C_DATUM ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Datum control in a GUI dialog.  The Datum control is a non-
visible control that just holds a value.  It's useful for keeping program
state information.
The control has no control-specific options.


C_MENU ( -- s)

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a menu control in a GUI dialog.  The menu control is a pull-down
menu that a user can select commands from.  It can contain labels, hrules,
buttons, checkboxes, radiobuttons, and other menus.
The control options specific to this type of control are:
    text    The text to display as the user-visible name of this menu. For
            example: "Settings", "Help", etc.
    pane    The id of the menu in which to place this menu as a cascading
            menu.  If specified as "", then this is a toplevel menu.


C_LABEL ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a text label control in a GUI dialog.  The label control is just
a text label, nothing more.
The control options specific to this type of control are:
    value    Contains the text to be displayed.
    justify  Which way to justify the text, if word wrapped.  Can be one of
            left, right, or center.
    maxwidth The max width in pixels for the label, before it word wraps.


C_IMAGE ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create an image control in a GUI dialog.  The image control is a picture
whose image is loaded from a URL.
The control options specific to this type of control are:
    value    Holds the url of the image to be displayed.
    width    The width of the image in pixels.  This is required.
    height   The height of the image in pixels.  This is required.


C_HRULE ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Horizontal Rule control in a GUI dialog.
The hrule control is just a horizontal line, nothing more.
The control options specific to this type of control are:
    height   Number of pixels of vertical thickness of the horizontal line.


C_VRULE ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Vertical Rule control in a GUI dialog.
The vrule control is just a vertical line, nothing more.
The control options specific to this type of control are:
    width    Number of pixels of horizontal thickness of the vertical line.


C_BUTTON ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Button control in a GUI dialog.
The Button control is a simple button the user can press.
The control options specific to this type of control are:
    text     The text label that will show on the button face.
    width    Number of characters text the button should be able to hold.
    dismiss  If 1, the dialog will be dismissed when this button is pressed.
            Defaults to 1.


C_CHECKBOX ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a CheckBox control in a GUI dialog.
The CheckBox control is used for indicating simple "on/off" boolean settings.
The control options specific to this type of control are:
    text     The text label that will show to the right of the checkbox.
    onvalue  The value this control should have when checked.
    offvalue The value this control should have when not checked.
    value    The current state/value of the control.  This should match either
            the value of the "onvalue" or "offvalue" argument.


C_RADIOBTN ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a radio button control in a GUI dialog.
The radio button control is used for selecting one of a number of options.
The control options specific to this type of control are:
    text     The text label that will show to the right of the radio button.
    valname  The name used to refer to the value of this radio button group.
            A radio button group is defined as radio buttons that share the
            same valname.
    selvalue The value of this radio button group, when this is selected.
    value    The current state/value of the radio button group.  This should
            match one of the selvalues of a radio button in this group.


C_EDIT ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a single-line text Edit control in a GUI dialog.
The Edit control is used for single-line text string editing.
The control options specific to this type of control are:
    text     The text label that will show to the left of the control.
            Defaults to "" (no label).  If there is a label, then this
            control will be split across two columns, with the label in
            the first one, the edit control in the second.
    value    The current contents/value of the control.
    maxlen   The maximum string length allowed.  Defaults to 1024 chars.
    width    Number of average character widths wide this control should be.
            Defaults to 40 characters wide.
    height   Number of lines high this control will be.  Defaults to 1.
            If this is greater than 1, then text will wrap as you type it,
            but you still won't be able to insert carriage returns.


C_MULTIEDIT ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Multi-line text Edit control in a GUI dialog.
The MultiEdit control is used for multi-line text string editing.
The control options specific to this type of control are:
    value    The current contents/value of the control.
    width    Number of average character widths wide this control should be.
            Defaults to 40 characters wide.
    height   Number of lines high this control will be.  Defaults to 1.
    font     Specifies whether the font used is "fixed" or "proportional".


C_COMBOBOX ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Win95 style combobox with a pulldown menu of options.
The ComboBox control is used for selecting from multiple standard options
in a compact form factor.  Optionally the user can enter arbitrary data.
The control options specific to this type of control are:
    text     The text label that will show to the left of the control.
            Defaults to "" (no label).  If there is a label, then this
            control will be split across two columns, with the label in
            the first one, the combobox control in the second.
    value    The current contents/value of the control.
    width    Number of average character widths wide this control should be.
            Defaults to 20 characters wide.
    options  Contains a list of entries for the combobox pulldown menu, one
            per line.
    editable If 1, the user can edit the value arbitrarily.  If 0, then the
            user can only pick a value from the combobox pulldown menu.
            Defaults to 0
    sorted   Causes the contents of the pulldown menu to be auto-sorted.


C_LISTBOX ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a ListBox control in a GUI dialog.  The ListBox control is used
for selecting one or more entries from a list of options.
The control options specific to this type of control are:
    value    The list of the currently selected list items, given as a list
            of integers that refer to list positions.  0 is the first item.
    font     Specifies whether the font used is "fixed" or "proportional".
    width    Number of average character widths wide this control should be.
            Defaults to 40 characters wide.
    height   Number of lines high this control will be.  Defaults to 10.
    options  The list of entries for the listbox contents, one per line.
    selectmode  One of "single", "multiple", or "extended".  Specifies how
            list item selection is performed, and whether more than one item
            can be selected at a time.


C_SPINNER ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Spinner control in a GUI dialog.  The Spinner control is used
for setting an integer value, that can be incremented and decremented via
up and down buttons.
The control options specific to this type of control are:
    value    The current integer value of the control.
    text     If given, makes a label with the given text next to the spinner.
    minval   The minimum integer value that this control can be set to.
    maxval   The maximum integer value that this control can be set to.
    width    Number of digits that this control should be able to hold.
            Defaults to 12 digits.


C_SCALE ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a Scale control in a GUI dialog.  The Scale control is used for
setting a floating point value, that can be changed by moving a slider.
The control options specific to this type of control are:
    value      The current floating point value of the control.
    text       If given, makes a label with the given text next to the scale.
    minval     The minimum value that this control can be set to.
    maxval     The maximum value that this control can be set to.
    resolution This is the smallest change available via the slider.
                Defaults to 1.
    bigincrement  How much to change the value when the user clicks in the
                bar on either side of the slider.  Defaults to 10.
    digits     The number of significant digits of resolution for the value.
    orient     The orientation, "horiz" or "vert".  (Defaults to horiz.)
    length     The length of the long axis of the scale, in pixels.
            Defaults to 100 pixels.
    width      The length of the short axis of the scale, in pixels.
            Defaults to 15 pixels.


C_FRAME ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE
to create a frame control in a GUI dialog.  Frame controls are used to
contain and organize other controls.  Frames can be either invisible
containers that just organize the positions of other controls, or they
can be visible groupboxes with borders and labels.
The control options specific to this type of control are:
    text        If set, the frame, as a groupbox, will have the given label.
    visible     If set to 1, causes a border to be drawn around the frame.
    collapsible This, is set to 1, allows the group box to be collapsed.
    collapsed   If the frame is collapsible, this sets the state to collapsed.


C_NOTEBOOK ( -- s )

  This is a standard server define used in conjunction with GUI_CTRL_CREATE to
create a tabbed notebook control in a GUI dialog.  Tabbed notebook controls
are used to contain and organize other controls in multiple pages that the
user can select between.
The control options specific to this type of control are:
    panes       The list of pane ids to create.  Those are used by other
                controls, when you wish to specify which pane the control
                is in.
    names       The list of names that should be displayed on the pane's tabs.
                The first name should be for the first pane, the second name
                should be for the second name, etc.
    width       The minimum width of the notebook's client area, in pixels.
    height      The minimum height of the notebook's client area, in pixels.





----------------------------------------------------------------------------
                             Exception Handling
----------------------------------------------------------------------------




TRY ( i -- )
CATCH ( -- s ) or CATCH_DETAILED ( -- a )
ENDCATCH ( -- )

  The TRY statement marks the start of the TRY-CATCH block, and locks all
but the top i stack items against removal or alteration.  If code inside
of a TRY-CATCH block gets an error, or attempts to remove or alter locked
stack items, then execution immediately jumps to the CATCH statement.
If, instead, execution reaches the end of the TRY-CATCH block without
error, then the stack is unlocked, and execution is resumed after the
ENDCATCH statement.

  On an error, the CATCH statement will pop off all stack items that were
not locked, to return the stack to a known state.  The stack will then
be unlocked, and the thrown error string will be pushed onto the stack.
Finally, the code inside the CATCH-ENDCATCH block will then be executed.
If you have nested TRY-CATCH blocks, then the most recent TRY-CATCH
block will catch the error thrown.  If the error is thrown in another
called function or program, then those calls are unwound back to the
most recent TRY-CATCH block.

  The CATCH_DETAILED statement can be used in place of the CATCH statement.
It behaves identically to CATCH, except it pushes a dictionary onto the
stack, instead of a string.  This dictionary holds much more detailed
information about the thrown exception.  The following dictionary entries
are currently supported:

    "error"    The error message string, like what CATCH returns.
    "instr"    The name string of the instruction which threw the error.
    "line"     The integer program line number where the error was thrown.
    "program"  The dbref of the program in which the error was thrown.

  The ABORT primitive may be used to throw an arbitrary error anywhere.
If you need to re-propagate an error, you can use ABORT.

Example code:
    : get_a_prop ( d s -- s )
        2 TRY
            getpropstr
        CATCH
            pop (We got an error trying to read the prop.  Ignore it.)
            ""
        ENDCATCH
    ;


ABORT ( s -- )

  Aborts the MUF program with an error.  ie:  '"Bad vibes." abort' would
Stop the MUF program and tell the user a message like:
Programmer error.  Please tell Revar the following message:
#1234 (line 23) ABORT: Bad vibes.


CHECKARGS (??? s -- )

  Takes a string argument that contains an expression that is used
to test the arguments on the stack below the given string.  If they
do not match what the expression says should be there, then it aborts
the running program with an appropriate Program Error Message.  The
expression is formed from single character argument tests that refer
to different argument types.  The tests are:

  a - function address.
  d - dbref.  (#-1, #-2, #-3 are okay)
  D - valid, non-garbage dbref.  (#-1, #-2 NOT allowed.  #-3 is okay)
  e - exit dbref.  (#-1, #-2 allowed)
  E - exit dbref.  (#-1, #-2 NOT allowed)
  f - program dbref.  (#-1, #-2 allowed)
  F - program dbref.  (#-1, #-2 NOT allowed)
  i - integer.
  l - lock boolean expression.
  p - player dbref.  (#-1, #-2 allowed)
  P - player dbref.  (#-1, #-2 NOT allowed)
  r - room dbref.  (#-1, #-2 allowed)  (#-3 is a room)
  R - room dbref.  (#-1, #-2 NOT allowed)  (#-3 is a room)
  s - string.
  S - non-null string.
  t - thing dbref.  (#-1, #-2 allowed)
  T - thing dbref.  (#-1, #-2 NOT allowed)
  v - local or global variable.
  ? - any stack item type.

Tests can be repeated multiple times by following the test with a number.
ie: '"i12" checkargs' would test the stack for 12 integers.

The last test in the string expression will be done on the top stack item.
Tests are done from the top of the stack down, in order, so the last test
that fails in a string expression will be the one that the Program Error
will be given for.  ie: '"sdSi" checkargs' will test that the top stack
item is an integer, then it tests that the next item down is a non-null
string, then it tests the third item from the top to see if it is a dbref,
and lastly it tests to make sure that the 4th item from the top is a string.

Spaces are ignored, so "s d i" is the same as "sdi".  However, multipliers
are ignored if they follow a space, so "s 4d i" is also the same as "sdi".
This is because you are basically telling it to repeat the space 4 times,
and since spaces are ignored, it has no effect.

If you have a function that takes a stack item of any type, you can use
the "?" test.  "?" will match a string, integer, dbref, or any other type.

Since sometimes arguments are passed in ranges, such as the way that the
explode primitive returns multiple strings with an integer count on top,
there is a way to group arguments, to show that you expect to receive a
range of that type.  ie: '"{s}" checkargs' would test the stack for a set
of strings like '"first" "second" "third" "fourth" 4' where the top stack
item tells how many strings to expect within the range.

Sometimes a function takes a range of paired arguments, such as:
'"one" 1 "two" 2 "three" 3 "four" 4 4' where the count on the top of the
range refers to the number of pairs.  To test for the range given above,
you would use '"{si}" checkargs' to tell it that you want to check for
a range of paired strings and integers.  You can group as many argument
tests together in a range as you would like.  ie: you could use "{sida}"
as an expression to test for a range of related strings, integers, dbrefs,
and function addresses.

Since the argument multipliers refer to the previous test OR range, you
can test for two string ranges with the test '"{s}2" checkargs'.  ie:
It would succeed on a stack of: '"one" "two" "three" 3 "four" "five" 2'.
'"{s2}" checkargs', however, would test for one range of paired strings.
ie: It would succeed with a stack of: '"one" "1" "two" "2" "three" "3" 3'.

If, for some reason, you need to pass a range of ranges to a function,
you can test for it by nesting the braces.  ie: '"{{s}}" checkargs'

Now, as one last example, the primitive notify_exclude, if we were to test
the arguments passed to it manually, would use the test '"R{p}s" checkargs'
to test for a valid room dbref, a range of player dbrefs or #-1s, and a
string.





----------------------------------------------------------------------------
                                 Debugging
----------------------------------------------------------------------------




DEBUG_ON ( -- )

  Turns the programs debug stack trace on.


DEBUG_OFF ( -- )

  Turns the programs debug stack trace off.


DEBUG_LINE ( -- )

  Displays a single line of debug stack trace if the player running the program
controls it.


DEBUGGER_BREAK ( -- )

  If the user controls the currently running program, and the program hasn't
ever backgrounded, this will force the program into the interactive MUF
debugger at the current location.  If the user was already in the MUF
debugger, this will force a breakpoint stop at the current location.


The MUF Debugger:

  To use the interactive debugger, set the ZOMBIE (Z) flag on a program.  When
you run a programm you own which is set ZOMBIE, you will be placed in the
interactive MUF debugger.
  When you enter the debugger, the program counter will be placed at the entry
point of the MUF.  This should always be the start of a function.  From
there, you may set breakpoints, examine or change the stack or variables,
list lines of code, step through, or continue execution.
  Every time execution halts and returns you to the debugger, the argument
stack is displayed, as well as a dump of the current line.  If execution
is at the beginning of the line, the actual line of source will be
displayed, otherwise the compiled instructions will be displayed with the
current instruction marked by surrounding braces.


Debugger commands:

  cont            continues execution until a breakpoint is hit.
  finish          completes execution of current function.
  step [NUM]      executes one (or NUM, 1) lines of muf.
  stepi [NUM]     executes one (or NUM, 1) muf instructions.
  next [NUM]      like step, except skips CALL and EXECUTE.
  nexti [NUM]     like stepi, except skips CALL and EXECUTE.
  break LINE#     sets breakpoint at given LINE number.
  break FUNCNAME  sets breakpoint at start of given function.
  breaks          lists all currently set breakpoints.
  delete NUM      deletes breakpoint by NUM, as listed by 'breaks'
  where [LEVS]    displays function call backtrace of up to num levels deep.
  stack [NUM]     shows the top num items on the stack.
  print v#        displays the value of given global variable #.
  print lv#       displays the value of given local variable #.
  trace [on|off]  turns on/off debug stack tracing.
  list [L1,[L2]]  lists source code of given line range.
  list FUNCNAME   lists source code of given function.
  listi [L1,[L2]] lists instructions in given line range.
  listi FUNCNAME  lists instructions in given function.
  words           lists all function word names in program.
  words PATTERN   lists all function word names that match PATTERN.
  exec FUNCNAME   calls given function with the current stack data.
  prim PRIMITIVE  executes given primitive with current stack data.
  push DATA       pushes an int, dbref, var, or string onto the stack.
  pop             pops top data item off the stack.
  help            displays this help screen.
  quit            stop execution here.


Breakpoints:

  Breakpoints can be set on a specefic line number, or on execution of a
specific word.  To set a breakpoint, simply enter 'break LINE', as in
'break 123', or 'break WORD', as in 'break do-something'.  To list current
breakpoints, simply enter the command 'breaks'.  To delete a breakpoint,
'delete NUM', where NUM is the number 'breaks' listed for that breakpoint.
An implied breakpoint is always triggered on return of words after an
execute, or an EXEC, when the line they were called from was stepped with
next.
  A breakpoint is triggered after execution of the program has continued with
either 'continue', 'finish', or while in a word called when 'next' or
'nexti' is used.


Instruction notation as given by DEBUG dumps and the MUF debugger:

    PRIMITIVE:      A call to that primitive. (As in POP or ROTATE)
    NUM:            An integer. (As in 5 or -154)
    #dbref:         An object dbref. (As in #1 or #63516)
    "Text":         A string.  (As in "Wizard" or "Hello world!") If it is
                    followed by _, there is more in the string than shown.
    [Lock]:         A lock in it's native structure. (As in [#0|!#0])
    VNUM:           Variable number NUM. (As in V0 or V10)
    LVNUM:          Local variable number NUM. (As in LV2 or LV5)
    SVNUM:          Scoped function variable number NUM. (As in SV2 or SV5)
    (word):         The start of a word. (As in (do-something))
    'word:          The address of word. (As in 'do-something)
    '#dbref'word:   The address of word in another program.
                    (As in '#2345'do-something)
    EXEC->word:     A subroutine call to word. (As in EXEC->do-something)
    JMP->word:      A jump to word. (As in JMP->do-something)
    JMP->lineNUM:   An internal jump used by IF-ELSE-THEN and loops.
                    (As in JMP->line9)
    IF->lineNUM:    An internal IF jump.  If the top stack item is 0, the jump
                    occurs, otherwise this is just a no-op. (As in IF->line9)
    ???:            An unknown instruction type. (As in ???)
    ???<file:line>: An instruction that has been freed.  If you see this please
                    report it to the current server code maintainer.
                    (As in ???<p_db.c:1042>)
Some tokens are just used as placeholders, and disappear as soon as the MUF
is compiled.  These are BEGIN, and THEN.  In addition, FOR loops will
produce at least two extra instruction, and an IF->lineNUM.  FORITER, the
iteration counter, and FORPOP, which cleans up from the for loop.  If you
JMP or EXIT out of a word from nested FOR loops, you will see a FORPOP
before the JMP or EXIT for each nexted FOR loop.





----------------------------------------------------------------------------
                               Miscellaneous
----------------------------------------------------------------------------




VERSION ( -- s)

  Returns the version of this code in a string. "Muck2.2fb5.55", currently.


FORCE (d s -- )

  Forces player d to do action s as if they were @forced.  (wizbit only)


FORCE_LEVEL ( -- i)

  Returns non-zero if the code we are running was triggered by an @force.