MUF Reference Manual for FBMuck 6.00

by Revar Desmera <revar@belfry.com>


List of Topics by Category

You can get more help on the following topics:


Alphabetical List of Topics

Symbols

  !     $abort     $author     $cleardefs     $def  
  $define     $echo     $ifcancall     $ifdef     $iflib  
  $iflibver     $ifncancall     $ifndef     $ifnlib     $ifnlibver  
  $ifnver     $ifver     $include     $lib-version     $libdef  
  $note     $pubdef     $undef     $version     %  
  '     *     +     ++     -  
  --     /     <     <=     =  
  >     >=     @     \     __fuzzball__  
  __muckname     __version     {     }     }dict  
  }join     }list     }tell  

A's

  abort     abs     acos  
  addpennies     addprop     address?  
  and     ansi_midstr     ansi_strcut  
  ansi_strip     ansi_strlen     array?  
  array_appenditem     array_compare     array_count  
  array_cut     array_delitem     array_delrange  
  array_diff     array_excludeval     array_explode  
  array_extract     array_filter_prop     array_findval  
  array_first     array_fmtstrings     array_get_ignorelist  
  array_get_propdirs     array_get_proplist     array_get_propvals  
  array_get_reflist     array_getitem     array_getrange  
  array_insertitem     array_insertrange     array_intersect  
  array_join     array_keys     array_last  
  array_make     array_make_dict     array_matchkey  
  array_matchval     array_ndiff     array_nested_del  
  array_nested_get     array_nested_set     array_next  
  array_nintersect     array_notify     array_nunion  
  array_prev     array_put_proplist     array_put_propvals  
  array_put_reflist     array_reverse     array_setitem  
  array_setrange     array_sort     array_sort_indexed  
  array_union     array_vals     arrive  
  asin     atan     atan2  
  atoi     awake?  

B's

  background     begin     bg_mode     bitand     bitor     bitshift  
  bitxor     blessed?     blessprop     break     breakpoints  

C's

  c_button     c_checkbox     c_combobox     c_datum  
  c_edit     c_frame     c_hrule     c_image  
  c_label     c_listbox     c_menu     c_multiedit  
  c_notebook     c_radiobtn     c_scale     c_spinner  
  c_vrule     call     caller     cancall?  
  ceil     checkargs     checkpassword     clear  
  clear_error     command     compilation     compile  
  compiled?     conboot     concount     condbref  
  condescr     conhost     conidle     connect  
  connotify     contents     contents_array     contime  
  continue     controls     conuser     copyobj  
  copyplayer     cos     ctoi  

D's

  date     dbcmp     dbref     dbref?  
  dbtop     debug notation     debug_line     debug_off  
  debug_on     debugger     debugger_break     debugger_commands  
  depth     desc     descr     descr_array  
  descr_setuser     descrboot     descrbufsize     descrcon  
  descrdbref     descrflush     descrhost     descridle  
  descriptors     descrleastidle     descrmostidle     descrnotify  
  descrsecure?     descrtime     descruser     dictionary?  
  diff3     dist3d     drop     dup  
  dupn  

E's

  else     envprop     envpropstr     epsilon     error?  
  error_bit     error_name     error_num     error_str     event_count  
  event_exists     event_send     event_wait     event_waitfor     execute  
  exit     exit?     exits     exits_array     exp  
  explode     explode_array  

F's

  fabs     fail     fg_mode     findnext     firstdescr     flag?  
  flags     float     float?     floor     fmod     fmtstring  
  for     force     force_level     foreach     foreground     fork  
  frand     ftostr  

G's

  getlink     getlinks     getlinks_array     getlockstr  
  getpidinfo     getpids     getprop     getpropfval  
  getpropstr     getpropval     getseed     gmtoffset  
  gui-options     gui_available     gui_ctrl_command     gui_ctrl_create  
  gui_dlog_close     gui_dlog_create     gui_dlog_helper     gui_dlog_show  
  gui_dlog_simple     gui_dlog_tabbed     gui_value_get     gui_value_set  
  gui_values_get  

I's

  if     ignore_add     ignore_del     ignoring?     inf     instances  
  instr     instring     int     int?     interp     intostr  
  is_set?     ispid?     itoc  

J's

  jmp  

K's

  kill  

L's

  lastdescr     ldup     libraries     listeners     loc  
  localvar     location     lock?     locked?     log  
  log10     loop-example1     loop-example2     loop-example3     loops  
  lreverse     lvar  

M's

  match     max_variable_count     mcp_bind  
  mcp_register     mcp_register_event     mcp_send  
  mcp_supports     me     midstr  
  mlevel     mode     modf  
  movepennies     moveto     mucker levels  
  multitasking  

N's

  name     name-ok?     newexit     newobject  
  newpassword     newplayer     newprogram     newroom  
  next     nextdescr     nextentrance     nextowned  
  nextprop     not     notify     notify_except  
  notify_exclude     number?  

O's

  objmem     odrop     ofail     ok?     online  
  online_array     or     osucc     over     owner  

P's

  parselock     parseprop     parsepropex     part_pmatch  
  pennies     pi     pick     pid  
  player?     pmatch     pname-ok?     polar_to_xyz  
  pop     popn     pow     pr_mode  
  preempt     prettylock     prog     program?  
  program_getlines     program_setlines     pronoun_sub     propdir?  
  public     put  

Q's

  queue  

R's

  random     read     read_wants_blanks     recycle  
  reflist_add     reflist_del     reflist_find     regexp  
  regsub     remove_prop     repeat     reverse  
  rinstr     rinstring     rmatch     room?  
  rot     rotate     round     rsplit  

S's

  set     set_error     setdesc     setdrop  
  setfail     setlink     setlinks_array     setlockstr  
  setmode     setname     setodrop     setofail  
  setosucc     setown     setprop     setseed  
  setsucc     setsysparm     sign     sin  
  sleep     smatch     split     sqrt  
  srand     stats     stod     strcat  
  strcmp     strcut     strdecrypt     strencrypt  
  string?     stringcmp     stringpfx     strip  
  striplead     striptail     strlen     strncmp  
  strtof     subst     succ     swap  
  sysparm     sysparm_array     systime     systime_precise  

T's

  tan     testlock     textattr     then     thing?     time  
  timefmt     timer_start     timer_stop     timesplit     timestamps     toadplayer  
  tokensplit     tolower     toupper     tread     trig     trigger  
  truename     try  

U's

  unblessprop     uncompile     unparselock     unparseobj     until     userlog  

V's

  var     var!     variable     version  

W's

  watchpid     while     wizcall  

X's

  xor     xyz_to_polar  


Details and Definitions

  arrive     compilation     connect     flags     libraries  
  listeners     mucker levels     multitasking  

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)

Also see: FOREGROUND, BACKGROUND, PREEMPT, FORK, QUEUE, KILL and SLEEP


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.

Also see: DEBUGGER


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

  $abort     $author     $cleardefs  
  $def     $define     $echo  
  $ifcancall     $ifdef     $iflib  
  $iflibver     $ifncancall     $ifndef  
  $ifnlib     $ifnlibver     $ifnver  
  $ifver     $include     $lib-version  
  $libdef     $note     $pubdef  
  $undef     $version     \  
  __fuzzball__     __muckname     __version  
  max_variable_count  

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

Also see: VERSION, $IFDEF, $DEFINE and $DEF


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.

Also see: $DEFINE, $DEF, $CLEARDEFS, $IFDEF, PUBLIC, WIZCALL, $PUBDEF and $LIBDEF


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

Also see: $LIBDEF, PUBLIC, WIZCALL, CANCALL? and CALL


$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'

Also see: $PUBDEF, PUBLIC, WIZCALL, CANCALL? and 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.

Also see: $DEFINE, $DEF and $UNDEF


$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

Also see: $IFNDEF, $DEFINE, $DEF and $DEF


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

Also see: $IFDEF, $DEFINE, $DEF and $DEF


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

Also see: $IFNVER, $IFLIBVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFVER, $IFLIBVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFNLIBVER, $IFNVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFNLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFNCANCALL, $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION


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

Also see: $IFCANCALL, $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION


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


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

  depth     dup     dupn     ldup     lreverse     over     pick  
  pop     popn     put     reverse     rot     rotate     swap  
  {     }  

POP ( x -- )

Pops the top of the stack into oblivion.

Also see: POPN


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

Pops the top i stack items.

Also see: POP


DUP ( x -- x x )

Duplicates the item at the top of the stack.

Also see: DUPN and LDUP


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

Duplicates the top i stack items.

Also see: DUP and LDUP


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

Duplicates a stackrange on top of the stack.

Also see: DUP and DUPN


SWAP ( x y -- y x )

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

Also see: PICK, OVER and DUP


OVER ( x y -- x y x )

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

Also see: PICK, SWAP and DUP


ROT ( x y z -- y z x )

Rotates the top three things on the stack. This is equivalent to 3 rotate.

Also see: ROTATE and SWAP


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.

Also see: ROT and SWAP


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.

Also see: OVER and PUT


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"

Also see: PICK


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"

Also see: LREVERSE


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

Also see: REVERSE


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.

Also see: }, }list, }dict, }tell and }join


} ( 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.

Also see: {, }list, }dict, }tell and }join


Variables and Handling Thereof

  !     @     command     loc     localvar     lvar     me  
  trigger     var     var!     variable  

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'

Also see: COMMAND, TRIGGER and LOC


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'

Also see: COMMAND, TRIGGER and ME


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,

Also see: COMMAND, LOC and ME


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'

Also see: TRIGGER, LOC and ME


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.

Also see: VAR!, LVAR, !, @, VARIABLE and LOCALVAR


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
    ;

Also see: VAR, LVAR, !, @, VARIABLE and LOCALVAR


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.

Also see: VAR, VAR!, !, @, VARIABLE and LOCALVAR


@ ( v -- x )

Retrieves variable v's value x.

Also see: !, VARIABLE, VAR, LVAR, LOCALVAR and MISCELLANEOUS


! ( x v -- )

Sets variable v's value to x.

Also see: @, VARIABLE, VAR, LVAR, LOCALVAR and MISCELLANEOUS


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.

Also see: @, !, VAR, ME, TRIGGER, LOC and COMMAND


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.

Also see: VARIABLE, VAR, LVAR, @ and !


Logical Operators

  <     <=     =     >     >=     address?  
  and     array?     dbref?     dictionary?     float?     int?  
  lock?     not     or     string?     xor  

< ( n1 n2 -- i )

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

Also see: >, <=, >=, =, NOT, AND and OR


> ( n1 n2 -- i )

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

Also see: <, <=, >=, =, NOT, AND and OR


= ( n1 n2 -- i )

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

Also see: <, >, <=, >=, NOT, AND and OR


<= ( n1 n2 -- i )

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

Also see: <, >, =, >=, NOT, AND and OR


>= ( n1 n2 -- i )

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

Also see: <, >, <=, =, NOT, AND and OR


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       ""

Also see: AND, OR and XOR


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       ""

Also see: NOT, OR and XOR


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       ""

Also see: NOT, AND and XOR


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       ""

Also see: NOT, AND and OR


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.

Also see: DICTIONARY?, INT?, DBREF?, ARRAY_MAKE_DICT and ARRAY_MAKE


DICTIONARY? ( ? -- i )

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

Also see: ARRAY?, INT?, DBREF?, ARRAY_MAKE_DICT and ARRAY_MAKE


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.

Also see: GETPROP, SETPROP, PARSELOCK, UNPARSELOCK, PRETTYLOCK and TESTLOCK


Execution Control Structures

  '     begin     break     call     cancall?  
  continue     else     execute     exit     for  
  foreach     if     interp     jmp     loop-example1  
  loop-example2     loop-example3     loops     public     repeat  
  then     until     while     wizcall  

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.

Also see: IF and THEN


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

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

Also see: IF and ELSE


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

Also see: '


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
    ;

Also see: ' and EXECUTE


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.

Also see: 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.

Also see: LOOPS


FOREACH (a -- @ ? )

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

Also see: LOOPS


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.

Also see: LOOPS


BREAK ( -- )

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

Also see: LOOPS


CONTINUE ( -- )

Jumps execution to the beginning of the current loop.

Also see: LOOPS


REPEAT ( -- )

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

Also see: LOOPS


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.

Also see: LOOPS


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.

Also see: LOOP-EXAMPLE1, LOOP-EXAMPLE2 and LOOP-EXAMPLE3


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

Also see: LOOPS, LOOP-EXAMPLE2 and LOOP-EXAMPLE3


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

Also see: LOOPS, LOOP-EXAMPLE1 and LOOP-EXAMPLE3


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)

Also see: LOOPS, LOOP-EXAMPLE1 and LOOP-EXAMPLE2


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

Also see: WIZCALL, CANCALL?, CALL, $LIBDEF and $PUBDEF


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

Also see: PUBLIC, CANCALL?, CALL, $LIBDEF and $PUBDEF


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.

Also see: PUBLIC, WIZCALL, CALL, $LIBDEF and $PUBDEF


I/O Operators

  notify     notify_except     notify_exclude     read  
  read_wants_blanks     tread     userlog  

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.

Also see: READ and TREAD


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.

Also see: READ_WANTS_BLANKS and TREAD


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

Also see: READ_WANTS_BLANKS and READ


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

  %     *     +     ++     -     --     /  
  abs     bitand     bitor     bitshift     bitxor     getseed     int  
  random     setseed     sign     srand  

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.

Also see: --


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

Also see: ++


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.

Also see: SETSEED and GETSEED


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.

Also see: SETSEED, GETSEED, SRAND and FRAND


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

  acos     asin     atan     atan2     ceil  
  clear     clear_error     cos     diff3     dist3d  
  epsilon     error?     error_bit     error_name     error_num  
  error_str     exp     fabs     float     floor  
  fmod     frand     ftostr     inf     is_set?  
  log     log10     modf     pi     polar_to_xyz  
  pow     round     set_error     sin     sqrt  
  strtof     tan     xyz_to_polar  

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.

Also see: EPSILON and FLOAT


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

Also see: INF, FLOAT, FABS, -, /, @, <, IF and THEN


FTOSTR ( f -- s )

Converts a floating point number into a string. Always includes the decimal point. 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.

Also see: FMTSTRING.


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.

Also see: ROUND and FLOOR


FLOOR ( f -- f )

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

Also see: ROUND and CIEL


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.

Also see: FLOOR and CIEL


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

Also see: POLAR_TO_XYZ, DIST3D, SIN, COS and TAN


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

Also see: XYZ_TO_POLAR, DIST3D, SIN, COS, TAN and ATAN2


FRAND ( -- f )

Returns a random floating point number between 0 and 1.


CLEAR ( -- )

Clears all error flags for floating point math operations.

Also see: ERROR?.


CLEAR_ERROR ( s|i -- i )

Clears a specific error flag for floating point math operations.

Also see: ERROR?.


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