MUF Reference Manual for Muck2.2fb7.10 by Revar Desmera You may get a listing of topics that you can get help on, either sorted Alphabetically or sorted by Category. To get these lists, type: man alpha or man category ~ ~---------------------------------------------------------------------------- ~ CATEGORY|CATEGORIES|TOPICS|SECTIONS List of Topics by Category: You can get more help on the following topics: Details and Definitions (DefDets) Macros and Compiler Directives (CompDefs) Stack Manipulation Operators (StackOps) Variables and Handling Thereof (VarHandling) Logical Operators (LogicOps) Execution Control Structures (ExecStructs) I/O Operators (IOOps) Mathematical Operators (MathOps) Floating Point Operators (FloatOps) String Manipulation Operators (StringOps) Lock Manipulation Operators (LockOps) Array Manipulation Operators (ArrayOps) Property Manipulation Operators (PropOps) Database Related Operators (DBOps) Time Manipulation Operators (TimeOps) Process Management Operators (ProcOps) Connection Management Operators (ConnOps) Event Handling Operators (EventOps) MCP Support Operators (MCPOps) GUI Support Operators (GUIOps) Exception Handling (Exceptions) Debugging (Debug) Miscellaneous (MiscOps) Use 'man ' to get more information on a topic. ~ ~---------------------------------------------------------------------------- ~ ALPHA|ALPHABETICAL|COMMANDS Alphabetical List of Topics: You can get more help on the following topics: Symbols ! != $abort $author $cleardefs $def $define $doccmd $echo $entrypoint $ifcancall $ifdef $iflib $iflibver $ifncancall $ifndef $ifnlib $ifnlibver $ifnver $ifver $include $language $lib-version $libdef $note $pragma $pubdef $undef $version % ' * + ++ - -- -rot / < <= = > >= ?dup @ \ __fuzzball__ __muckname __prog__ __version { } }cat }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_default_pinning array_delitem array_delrange array_diff array_excludeval array_explode array_extract array_filter_flags array_filter_lock 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_interpret 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_notify_secure array_nunion array_pin 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_unpin array_vals 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? case ceil checkargs checkpassword clear clear_error cmd command compilation compile compiled? contents contents_array continue controls convtime copyobj copyplayer cos ctoi D's date dbcmp dbref dbref? dbtop debug notation debug_line debug_off debug_on debugger debugger_break debugger_commands deep_copy depth desc descr descr_array descr_setuser descrboot descrbufsize descrcount descrdbref descrflush descrhost descridle descriptors descrleastidle descrmostidle descrnotify descrsecure? descrtime descruser dictionary? diff3 dist3d drop dump dup dupn E's else entrances_array 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 ext-name-ok? F's fabs fail fg_mode findnext firstdescr flag? flags float float? floor fmod fmtstring fmttime for force force_level forcedby forcedby_array foreach foreground fork frand ftostr ftostrc fulldepth G's gaussian 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 H's height 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 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 md5hash 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 nip not notify notify_except notify_exclude notify_nolisten notify_secure number? O's objmem odrop ofail ok? online online_array or osucc otell over owner P's parselock parsempi parsempiblessed parseprop parsepropex part_pmatch pennies pi pick pid player? pmatch pname-ok? pname_history polar_to_xyz pop popn pose-separator? pow pr_mode preempt prettylock prog program? program_getlines program_setlines pronoun_sub prop-name-ok? propdir? propqueues public put Q's queue R's random read read_wants_blanks read_wants_no_blanks recycle reflist_add reflist_del reflist_find regexp regsplit regsplit_noempty regsub remove_prop repeat reverse rinstr rinstring rmatch room? rot rotate round rsplit S's secure_sysvars set set_error setdesc setdrop setfail setheight setlink setlinks_array setlockstr setmode setname setodrop setofail setosucc setown setprop setseed setsucc setsysparm setwidth shallow_copy sign sin sleep smatch smtp_send split sqrt srand stats stats_array stod strcat strcmp strcut strdecrypt strencrypt string? stringcmp stringpfx strip striplead striptail strlen strncmp strtof subst succ supplicant swap sysparm sysparm_array systime systime_precise T's tan tell testlock textattr then thing? time timefmt timer_start timer_stop timesplit timestamps toadplayer tokensplit tolower toupper tread trig trigger truename try tuck U's unblessprop uncompile unparselock unparseobj until userlog V's var var! variable version W's watchpid while width wizcall X's xor xyz_to_polar Use 'man ' to get more information on a topic. ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Details and Definitions|DefDets Details and Definitions compilation flags libraries mucker levels multitasking propqueues ~---------------------------------------------------------------------------- ~ ~ ~ ~ MUCKER LEVELS|LEVELS|MUCKER1|MUCKER2|MUCKER3|MUCKER4 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: DESCRBREF, 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 DESCRHOST 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 its own MUCKER level and the MUCKER level of its 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 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 Libraries: How to use a library: 1) Use "@register lib" to list what libraries exist. 2) Use "@view $lib/" 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/ 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 =_docs: 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|HARDUID|SETUID|AUTOSTART|BOUND 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 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. ~ ~ PROPQUEUES|LISTENERS|_LISTEN|CONNECT|DISCONNECT|_CONNECT|_DISCONNECT|ARRIVE|DEPART|_ARRIVE|_DEPART|ARRIVE|DEPART|_ARRIVE|_DEPART Propqueues: A propqueue is defined as one or more properties in a directory which cause MUF or MPI 'things' to happen based on a MUCK event. Each property in the directory may contain either a program reference number or some MPI. Propqueues are triggered by certain activities that can occur on the MUCK, such as listeners, arrival, departure, connection, and disconnection. For the most part, these propqueues all follow the same 'rules' and operate in similar fashions. Where there are exceptions or oddities, they will be noted. Propqueues can follow the following formats, using _connect as an example: @set here=_connect:1234 @set here=_connect:#1234 @set here=_connect:&{somempi} @set here=_connect/subprop:1234 @set here=_connect/subprop:#1234 @set here=_connect:&{somempi} Where #1234 is some MUF program reference. Note that $ references are currently not supported, although you could use &{muf:$reference,{&arg}} if you really wanted to. You can also use @REGISTER to set a "ref" type property and use that as well, but using a ref property is not required. Because a property can both have a value and be a prop directory, that works here as well. The MUF or MPI set on the parent property runs first, and then the children are run in the order in which they appear in the prop directory (alphabetical). Children within the property queue may have children themselves. Propqueues are a special form of 'environment' property; propqueues are looked for starting with the triggering object (usually the player that triggered it), then whatever thing that object is in (usually a room), and then up the environment from there. Unlike most environment properties, such as those fetched with ENVPROP, the MUCK keeps looking for propqueues all the way up the environment to #0 and runs all of them with the most 'local' propqueues run first. There is no way to prevent upstream propqueues from being run. If a propqueue property is blessed, the MPI run by it will be blessed as well. Programs will only run if all of these conditions are met: * The program is LINK_OK or owned by the triggering player * The MUCKER level of the program exceeds the MUCKER requirements * The owner of the program's MUCKER level exceeds the MUCKER requirements For most propqueues, the minimum MUCKER level is 1, making a fairly low bar. The exception is the listen propqueue, which by default requires a MUCKER level of 3 but can be changed with the listen_mlev @TUNE setting. Propqueues usually come in regular and "O" forms, similar to other things. For instance, _arrive vs. _oarrive. The difference means nothing to MUFs being run, however they do impact how MPI is run following the same rules as, for example, @SUCCESS / @OSUCCESS and other such commands that run MPI. The following propqueues are supported: ARRIVE: _arrive OARRIVE: _oarrive Triggered on arrival to the room. Arrive propqueues are run after the user has been displayed the 'look' message for the room, so theoretically arrive messages sent to the user won't be lost in the text. CONNECT: _connect OCONNECT: _oconnect Triggered on a player connecting. Like arrive, connection propqueues are run after everything else produced by the MUCK (like motd and room description) are displayed so as to minimize the chance they will be lost in the mess. Note that MUCKs also support a 'connect' exit which the user will automatically trigger as if they typed 'connect' upon connecting. This action is only run if the user isn't already connected. The connect propqueues are run each time the player connects, regardless of if they are already connected or not. DEPART: _depart ODEPART: _odepart Triggered on a player departing the room. The exact method of functioning is slightly unusual. First, the player is moved to the new location. Then, the depart propqueue is run just on the player. After that, the depart propqueue is run normally (i.e. checking the environment) starting from the player's old location and going up the environment tree from there. DISCONNECT: _disconnect ODISCONNECT: _odisconnect Triggered when a player disconnects. This is actually run after the player connection is dropped, so you won't be able to send a message to the player unless they are still connected due to multiple connections. Like connect, you can also have a 'disconnect' exit which the user will automatically trigger as if they typed 'disconnect'. There are a few oddities here; the 'disconnect' action will be used only if this is the player's last connection. Also, unlike the propqueue, the exit is activated before the player's connection is dropped. As with connect, the disconnect propqueues are run with each disconnect, even if the user has multiple connections and thus can disconnect many times. LISTEN: _listen WLISTEN: ~listen WOLISTEN: ~olisten Due to the sensitive nature of listen props and the desire to keep player conversations and actions as private as those players wish them to be, _listen (the prop that anybody can set) cannot run MPI in addition to the MUCKER restrictions for MUF mentioned above. Wizards can set ~listen and ~olisten propqueues and use MPI in them, which is the reason for the 'WLISTEN' and 'WOLISTEN' variants. Listen propqueues can also use patterns in order to have MUF or MPI trigger when certain things are 'heard' by the MUCK. The patterns use the same engine as SMATCH so see that man page for full details on available patterns. However, as a simple example, you could do this: @set here=_listen/run:*run the muf please*=#1234 The match is case insensitive, and this also works with MPI if you use the WLISTEN/WOLISTEN versions, i.e.: @set here=~listen/run_mpi:*run the mpi please*=&{tell:Okay!} LOOK: _lookq This is a propqueue that is triggered by 'look' after all messages from 'look' itself are displayed. Please note that many MUCKs override 'look' with a custom program, and it is likely in such cases that this propqueue won't work. The environment search is started from the looked-at thing, rather than the player doing the looking. Note that entering a room will do an implied 'look' which will trigger this propqueue. The look propqueue is run as if it was a 'public' message, so the o-message rules apply to any MPI triggered by this propqueue even though the queue isn't called 'olook'. There is no 'private' variant of this propqueue. Also see: SMATCH ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Macros and Compiler Directives|Macros|Directives|CompDefs Macros and Compiler Directives $abort $author $cleardefs $def $define $doccmd $echo $entrypoint $ifcancall $ifdef $iflib $iflibver $ifncancall $ifndef $ifnlib $ifnlibver $ifnver $ifver $include $language $lib-version $libdef $note $pragma $pubdef $undef $version \ __fuzzball__ __muckname __prog__ __version max_variable_count ~---------------------------------------------------------------------------- ~ ~ ~ ~ __FUZZBALL__ __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 __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 __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 ~ ~ __PROG__ __PROG__ A compile-time token replaced with the dbref of the current program. Currently recognized within $doccmd and $pubdef directives. ~ ~ MAX_VARIABLE_COUNT 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 $AUTHOR Sets the _author string property on the program to . The preferred format is an email address with name comment. ie: $author Revar Desmera To denote multiple authors, separate them with commas. ie: $author Revar Desmera , Foxen If you don't want to include your email address, just omit it. ie: $author Revar, Foxen ~ ~ $VERSION $VERSION Sets the _version string property on the program to . 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 $LIB-VERSION Sets the _lib-version string property on the program to . 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 $NOTE Sets the _note string property on the program to . ~ ~ $DOCCMD $DOCCMD Sets the _docs string property on the program to . This property holds the command used to view documentation for the program. ~ ~ $DEFINE|$ENDDEF $DEFINE $enddef Basically the same as C's #define ~ ~ $DEF $DEF This is the same as $define, except that the definition stops at the end of the program line, without using an ending $enddef. ~ ~ $UNDEF $UNDEF About the same as C's #undef ~ ~ $INCLUDE $INCLUDE $ $INCLUDE 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 : $PUBDEF $PUBDEF $PUBDEF \ 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 Clears the _defs/ prop on the prog. $pubdef Sets _defs/ prop to . $pubdef \ Sets _defs/ 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 $LIBDEF $LIBDEF \ 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 ' "myfunc" call' Also see: $PUBDEF, PUBLIC, WIZCALL, CANCALL? and CALL ~ ~ $CLEARDEFS $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|$ELSE|$ENDIF $IFDEF $endif $IFDEF $else $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 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= 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 $endif 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 and $DEF ~ ~ $IFNDEF $IFNDEF $endif $IFNDEF $else $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 is false. The four accepted forms of the 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 $endif $IFVER this $else $endif $IFVER $ $endif $IFVER $ $else $endif $IFVER $endif $IFVER $else $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 will be compiled if the given program's $version is greater than or equal to the given , using a floating point number comparison. Otherwise, the , if given, will be compiled. Also see: $IFNVER, $IFLIBVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFNVER $IFNVER this $endif $IFNVER this $else $endif $IFNVER $ $endif $IFNVER $ $else $endif $IFNVER $endif $IFNVER $else $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 will be compiled if the given program's $version is less than the given , using a floating point number comparison. Otherwise, the , if given, will be compiled. Also see: $IFVER, $IFLIBVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFLIBVER $IFLIBVER this $endif $IFLIBVER this $else $endif $IFLIBVER $ $endif $IFLIBVER $ $else $endif $IFLIBVER $endif $IFLIBVER $else $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 will be compiled if the given program's $lib-version is greater than or equal to the given , using a floating point number comparison. Otherwise, the , if given, will be compiled. Also see: $IFNLIBVER, $IFNVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFNLIBVER $IFNLIBVER this $endif $IFNLIBVER this $else $endif $IFNLIBVER $ $endif $IFNLIBVER $ $else $endif $IFNLIBVER $endif $IFNLIBVER $else $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 will be compiled if the given program's $lib-version is less than the given , using a floating point number comparison. Otherwise, the , if given, will be compiled. Also see: $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFLIB $IFLIB $ $endif $IFLIB $ $else $endif $IFLIB $endif $IFLIB $else $endif This determines whether or not to compile optional sections of code, depending on the existence of a given program. The will be compiled if the given object exists and is a program. Otherwise, the , if given, will be compiled. Also see: $IFNLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFNLIB $IFNLIB $ $endif $IFNLIB $ $else $endif $IFNLIB $endif $IFNLIB $else $endif This determines whether or not to compile optional sections of code, depending on the existence of a given program. The will be compiled if the given object does not exist, or if it is not a program. Otherwise, the , if given, will be compiled. Also see: $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFCANCALL $IFCANCALL $ $endif $IFCANCALL $ $else $endif $IFCANCALL $endif $IFCANCALL $else $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. The 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 , if given, will be compiled. Also see: $IFNCANCALL, $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $IFNCANCALL $IFNCANCALL $ $endif $IFNCANCALL $ $else $endif $IFNCANCALL $endif $IFNCANCALL $else $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. The 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 , if given, will be compiled. Also see: $IFCANCALL, $IFLIB, $IFLIBVER, $IFVER, $IFDEF, $VERSION and $LIB-VERSION ~ ~ $ECHO $ECHO Echos the given string to the screen of the person compiling the program. Runs at compile-time. ~ ~ $ABORT $ABORT Aborts compiling and prints out the error message. ~ ~ $PRAGMA $PRAGMA [] 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. ~ ~ $ENTRYPOINT $ENTRYPOINT Sets the function used to start the program. Defaults to the last one. ~ ~ $LANGUAGE $LANGUAGE "" Sets the language used to compile the program. "MUF" is currently supported. ~ ~ \|BACKSLASH 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|StackOps Stack Manipulation Operators -rot ?dup deep_copy depth dup dupn fulldepth ldup lreverse nip over pick pop popn put reverse rot rotate shallow_copy swap tuck { } ~---------------------------------------------------------------------------- ~ ~ ~ ~ POP POP ( x -- ) Pops the top of the stack into oblivion. Also see: POPN ~ ~ POPN POPN ( ?n..?1 i -- ) Pops the top i stack items. Also see: POP ~ ~ DUP DUP ( x -- x x ) Duplicates the item at the top of the stack. Also see: DUPN and LDUP ~ ~ DUPN DUPN ( ?n..?1 i -- ?n..?1 ?n..?1 ) Duplicates the top i stack items. Also see: DUP and LDUP ~ ~ ?DUP ?DUP ( x -- x x | x ) Duplicates the item at the top of the stack if it does not resolve to false. Also see: DUP ~ ~ NIP NIP ( x y -- y ) Pops the second item off the stack. Also see: POP ~ ~ TUCK TUCK ( x y -- y x y ) Duplicates y and places it under x. Also see: OVER ~ ~ LDUP LDUP ( {?} -- {?} {?} ) Duplicates a stackrange on top of the stack. Also see: DUP and DUPN ~ ~ SHALLOW_COPY SHALLOW_COPY ( x -- x x ) Duplicates the item at the top of the stack. If it is an array, it makes a shallow copy of it that is decoupled from the original array. Also see: DUP, DUPN, LDUP and DEEP_COPY ~ ~ DEEP_COPY DEEP_COPY ( x -- x x ) Duplicates the item at the top of the stack. If it is an array, it makes a deep copy of it that is decoupled from the original array. Also see: DUP, DUPN, LDUP and SHALLOW_COPY ~ ~ SWAP SWAP ( x y -- y x ) Takes objects x and y on the stack and reverses their order. Also see: PICK, OVER and DUP ~ ~ OVER 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 ROT ( x y z -- y z x ) Rotates the top three things on the stack. This is equivalent to 3 rotate. Also see: ROTATE, -ROT and SWAP ~ ~ -ROT -ROT ( x y z -- z x y ) Rotates the top three things on the stack, in reverse. Equivalent to -3 rotate. Also see: ROTATE, ROT and SWAP ~ ~ 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. Also see: ROT and SWAP ~ ~ PICK 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 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 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 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 DEPTH ( -- i ) Returns the number of unlocked items currently on the stack. Also see: FULLDEPTH ~ ~ FULLDEPTH FULLDEPTH ( -- i ) Returns the number of items currently on the stack. Also see: DEPTH ~ ~ { { ( -- 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|VarHandling Variables and Handling Thereof ! @ cmd command loc localvar lvar me secure_sysvars trigger var var! variable ~---------------------------------------------------------------------------- ~ ~ ~ ~ ME 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 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 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 ~ ~ CMD CMD ( -- s ) Returns the command the user invoked the program with, without its command line arguments. Also see: COMMAND and TRIG ~ ~ COMMAND 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 COMMAND global variable is the same variable as '3 variable' Also see: TRIGGER, LOC and ME ~ ~ VAR VAR 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 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! VAR! This must be used within a function. It declares a function-scoped variable named 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 LVAR 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 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. Its 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 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 ! ~ ~ SECURE_SYSVARS SECURE_SYSVARS ( -- ) Sets the value of variables "me", "loc", "trigger" and "command" to their correct values in one instruction. ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Logical Operators|LogicOps 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 ~ ~ = = ( ?1 ?2 -- i ) Compares two numbers, dbrefs, or strings and returns 1 if ?1 is equal to ?2, and 0 otherwise. Also see: <, >, <=, >=, !=, NOT, AND and OR ~ ~ != != ( ?1 ?2 -- i ) Compares two numbers, dbrefs, or strings and returns 0 if ?1 is equal to ?2, and 1 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 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 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 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 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? STRING? ( x -- i ) Returns true if x is a string. ~ ~ INT? INT? ( x -- i ) Returns true if x is a int. ~ ~ FLOAT? FLOAT? ( ? -- i ) Returns true if the item on the stack is a floating point value. ~ ~ DBREF? DBREF? ( x -- i ) Returns true if x is a dbref. ~ ~ ARRAY? 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? 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? ADDRESS? (? -- i) Returns true if the top stack item is a function address. ~ ~ LOCK? LOCK? (? -- i) Returns true if the top stack item is a lock. Also see: GETPROP, SETPROP, PARSELOCK, UNPARSELOCK, PRETTYLOCK and TESTLOCK ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Execution Control Structures|ExecStructs Execution Control Structures ' begin break call cancall? case continue else execute exit for foreach if interp jmp loop-example1 loop-example2 loop-example3 loops public repeat then until while wizcall ~---------------------------------------------------------------------------- ~ ~ ~ ~ IF 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. ~ ~ ELSE 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 ~ ~ 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 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 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 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 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 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 BEGIN ( -- ) Marks the beginning of BEGIN-UNTIL or BEGIN-REPEAT loops. Also see: LOOPS ~ ~ FOR 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 FOREACH (a -- @ ? ) Marks the beginning of an iterative FOREACH loop, stepping through every index/value pair in the array. Also see: LOOPS ~ ~ WHILE 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 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 CONTINUE ( -- ) Jumps execution to the beginning of the current loop. Also see: LOOPS ~ ~ REPEAT 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 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 ~ ~ CASE|DEFAULT|END|ENDCASE|WHEN Case statements Inserver defines to achieve case statements. Allows: case when end when end when end when end default end endcase This compiles to the following MUF code: begin dup if pop break then dup if pop break then dup if pop break then dup if pop break then dup pop 1 if break then dup pop pop 1 until ~ ~ 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-EXAMPLE1 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-EXAMPLE2 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-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 PUBLIC 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 WIZCALL 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? 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|IOOps I/O Operators notify notify_except notify_exclude notify_nolisten notify_secure otell read read_wants_blanks read_wants_no_blanks tell tread userlog ~---------------------------------------------------------------------------- ~ ~ ~ ~ NOTIFY 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_NOLISTEN NOTIFY_NOLISTEN ( 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 not trigger any _listen'er properties on the object the message is sent to. ~ ~ NOTIFY_EXCEPT 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 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. ~ ~ NOTIFY_SECURE NOTIFY_SECURE ( d s1 s2 -- ) Notifies player d with s1 over their secure descriptors and s2 over their insecure descriptors. Triggers listener prop queues only with s2. ~ ~ READ_WANTS_BLANKS READ_WANTS_BLANKS ( -- ) Tells the interpreter that this process wants to be able to receive blank lines from the READ primitive. This can be reversed with the READ_WANTS_NO_BLANKS primitive. Also see: READ, TREAD and READ_WANTS_NO_BLANKS ~ ~ READ_WANTS_NO_BLANKS READ_WANTS_NO_BLANKS ( -- ) Tells the interpreter that this process should ignore blank lines from the READ primitive. This is only necessary after a call to READ_WANTS_BLANKS has been made. Also see: READ, TREAD and READ_WANTS_BLANKS ~ ~ READ 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, READ_WANTS_NO_BLANKS and TREAD ~ ~ 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 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)] 2002-06-11T03:09:31: 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. ~ ~ TELL TELL ( s -- ) Displays the message s to the player, triggering applicable listeners. ~ ~ OTELL OTELL ( s -- ) Displays the message s to all occupants of the player's location, except the player. This primitive triggers applicable listeners. ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Mathematical Operators|MathOps Mathematical Operators % * + ++ - -- / abs bitand bitor bitshift bitxor getseed int random setseed sign srand ~---------------------------------------------------------------------------- ~ ~ ~ ~ INT 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. Also concatenates two strings. ~ ~ - - ( 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. Also repeats a string given an integer argument. ~ ~ / / ( 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 ABS ( i -- i ) Given an integer, returns its absolute value. ~ ~ SIGN SIGN ( i -- i ) Given an integer, returns 1 if positive, -1 if negative, and 0 if 0. ~ ~ GETSEED GETSEED ( -- s ) Returns the the current SRAND seed string. ~ ~ SETSEED 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 SRAND ( -- i ) Generates a seeded random number. Also see: SETSEED and GETSEED ~ ~ RANDOM RANDOM ( -- i ) Returns a random integer from 0 to (2^31)-1, which is 2,147,483,647. This is based on the C random() function, so it's not very secure. Also see: SETSEED, GETSEED, SRAND, FRAND and GAUSSIAN ~ ~ BITOR BITOR (i i -- i) Does a mathematical bitwise or. ~ ~ BITXOR|^ BITXOR (i i -- i) Does a mathematical bitwise exclusive or. ~ ~ BITAND|& BITAND (i i -- i) Does a mathematical bitwise and. ~ ~ BITSHIFT|<< 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|FloatOps 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 ftostrc gaussian inf is_set? log log10 modf pi polar_to_xyz pow round set_error sin sqrt strtof tan xyz_to_polar ~---------------------------------------------------------------------------- ~ ~ ~ ~ FLOAT FLOAT ( i -- f ) Converts integer to floating point type. ~ ~ PI PI ( -- f ) Returns the value of Pi. ~ ~ INF 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 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 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. Also see: FMTSTRING and FTOSTRC ~ ~ FTOSTRC 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. Also see: FMTSTRING and FTOSTR ~ ~ STRTOF 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 FABS ( f -- f ) Returns the absolute value of the float f. ~ ~ CEIL CEIL ( f - f ) Returns the next highest integer, as a floating point type. Also see: ROUND and FLOOR ~ ~ FLOOR FLOOR ( f -- f ) Returns the next lowest integer number, as a floating point type. Also see: ROUND and CIEL ~ ~ ROUND 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 FMOD ( f1 f2 -- f ) Returns the floating point remainder of f1 divided by f2. (f1/f2) ~ ~ MODF 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 SQRT ( f -- f ) Returns a float's square root. Expects a value greater than or equal to zero. ~ ~ COS COS ( f -- f ) Returns the cosine of a float. Only operates in the range of -Pi/4 to Pi/4. ~ ~ ACOS ACOS ( f -- f ) Returns the inverse cosine of a float. Only operates within the range from 0 to Pi. ~ ~ SIN SIN ( f -- f ) Returns the sine of a float. Only operates within the range of -Pi/4 to Pi/4. ~ ~ ASIN ASIN ( f -- f ) Returns the inverse sine of a float. Only operates within the range from -Pi/2 to Pi/2. ~ ~ TAN TAN ( f -- f ) Returns the tangent of a float. Only operates within the range of K*pi + pi/2 (for some K). ~ ~ ATAN ATAN ( f -- f ) Returns the inverse tangent of a float. Only operates within the range from -Pi/2 to Pi/2. ~ ~ ATAN2 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 LOG ( f -- f ) Returns the natural log of float f. Requires a value greater than zero. Very small values will return INF. ~ ~ EXP EXP ( f -- f ) Returns the value of e raised to the power of the passed float. ~ ~ LOG10 LOG10 ( f -- f ) Returns the log base 10 of float f. Requires a value greater than zero. Very small values will return INF. ~ ~ POW|^ POW ( f1 f2 -- f ) ^ ( 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 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 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 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 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 FRAND ( -- f ) Returns a random floating point number between 0 and 1. ~ ~ GAUSSIAN 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 CLEAR ( -- ) Clears all error flags for floating point math operations. Also see: ERROR?. ~ ~ CLEAR_ERROR CLEAR_ERROR ( s|i -- i ) Clears a specific error flag for floating point math operations. Also see: ERROR?. ~ ~ 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 out of range. IBOUNDS - (4) Calculation resulted in an integer overflow or underflow. ~ ~ ERROR_BIT ERROR_BIT ( s -- i ) Returns the bit identifier for a given floating point error flag string name. Also see: ERROR?. ~ ~ ERROR_NAME ERROR_NAME ( i -- s ) Returns the string name for the error flag, given a floating point error identifier. Also see: ERROR?. ~ ~ ERROR_NUM ERROR_NUM ( -- i ) Returns the total number of floating point error flag types. Also see: ERROR?. ~ ~ ERROR_STR ERROR_STR ( s|i -- s ) Returns a user-readable error string, given a floating point error identifier. Also see: ERROR?. ~ ~ IS_SET? IS_SET? ( s|i - i ) Checks if a specific floating point error flag is set. Also see: ERROR? ~ ~ SET_ERROR SET_ERROR ( s|i -- i ) Sets the specified error flag for floating point operations. Also see: ERROR? ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ String Manipulation Operators|StringOps String Manipulation Operators ansi_midstr ansi_strcut ansi_strip ansi_strlen array_fmtstrings atoi ctoi explode explode_array ext-name-ok? fmtstring instr instring intostr itoc md5hash midstr name-ok? number? pname-ok? pose-separator? pronoun_sub regexp regsplit regsplit_noempty regsub rinstr rinstring rsplit smatch split stod strcat strcmp strcut strdecrypt strencrypt stringcmp stringpfx strip striplead striptail strlen strncmp subst textattr tokensplit tolower toupper ~---------------------------------------------------------------------------- ~ ~ ~ ~ ATOI ATOI ( s -- i ) Turns string s into integer i. If s is not a string, then 0 is pushed onto the stack. ~ ~ CTOI CTOI ( s -- i ) Converts the first character in s into its ASCII equivilent. Also see: ITOC. ~ ~ STRLEN STRLEN ( s -- i ) Returns the length of string s. ~ ~ STRCAT STRCAT ( s1 s2 -- s ) Concatenates two strings s1 and s2 and pushes the result s = s1s2 onto the stack. ~ ~ STRCMP 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, "z" "a" 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. Also see: STRNCMP ~ ~ STRNCMP STRNCMP ( s1 s2 i -- i' ) Compares the first i characters in strings s1 and s2. Return value is like strcmp. Also see: STRINGCMP ~ ~ STRINGCMP 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, "z" "a" stringcmp returns 25. This function is not case sensitive, unlike strcmp. Also see: STRNCMP ~ ~ STRINGPFX 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 INSTR ( s s1 -- i ) Returns the first occurrence of string s1 in string s, or 0 if s1 is not found. Also see: RINSTR and INSTRING ~ ~ RINSTR 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. Also see: INSTR and RINSTRING ~ ~ STRCUT 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 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 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. Also see: RSPLIT ~ ~ RSPLIT RSPLIT ( s1 s2 -- s1' s2' ) Splits a string, as SPLIT, but splits on the last occurence of s2. Also see: SPLIT ~ ~ EXPLODE 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. Also see: EXPLODE_ARRAY ~ ~ EXPLODE_ARRAY 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. Also see: EXPLODE ~ ~ SUBST 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 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. Also see: ARRAY_FMTSTRINGS ~ ~ ARRAY_FMTSTRINGS 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_fmtstrings { 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 the appropriate false value for 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.) Also see: FMTSTRING ~ ~ PRONOUN_SUB 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|ATTRIBUTES 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 italic uline flash reverse overstrike black red green yellow blue magenta cyan white bg_black bg_red bg_green bg_yellow bg_blue bg_magenta bg_cyan bg_white ~ ~ STOD STOD ( s -- d ) Attempts to extract a dbref from s, recognizing both plain numerical strings, and those prepended with a '#' sign. ~ ~ ANSI_STRIP ANSI_STRIP ( s -- s' ) Takes a string and removes ansi escapes from with in the string, returning the de-ansified string. ~ ~ ANSI_STRLEN ANSI_STRLEN ( s -- i ) Returns the length of string s ignoring ansi escape within the string. ~ ~ ANSI_STRCUT ANSI_STRCUT ( s i -- s1 s2 ) Like STRCUT, but ignores ansi escapes when finding the location to divide the string at. ~ ~ ANSI_MIDSTR 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? NUMBER? ( s -- i ) Returns 1 if string on top of the stack contains a number. Otherwise returns 0. ~ ~ POSE-SEPARATOR? POSE-SEPARATOR? ( s -- i ) Returns 1 if the argument could be used as a pose without requiring a space. Otherwise returns 0. ~ ~ INTOSTR INTOSTR ( x -- s ) x must be an integer or a dbref. Converts x into string s. ~ ~ ITOC ITOC ( i -- s ) Converts an integer i to its ASCII equivilent character, or a null if i is not a valid display character. Also see: CTOI ~ ~ STRENCRYPT 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. Also see: STRDECRYPT ~ ~ STRDECRYPT STRDECRYPT ( s1 s2 -- s3 ) Takes the encrypted string s1, and decrypts it, using the key s2, returning the plaintext string s3. Also see: STRENCRYPT ~ ~ MD5HASH MD5HASH ( s -- s' ) Calculates the MD5 hash of the given string. ~ ~ TOUPPER TOUPPER (s -- s) Takes a string and returns it with all the letters in uppercase. ~ ~ TOLOWER TOLOWER (s -- s) Takes a string and returns it with all the letters in lowercase. ~ ~ STRIPLEAD STRIPLEAD (s -- s) Strips leading spaces from the given string. ~ ~ STRIPTAIL STRIPTAIL (s -- s) Strips trailing spaces from the given string. ~ ~ STRIP 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 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 INSTRING ( s s1 -- i ) Returns the first occurrence of string s1 in string s, or 0 if s1 is not found. Non-case sensitive. Also see: RINSTRING, INSTR and RINSTR ~ ~ RINSTRING RINSTRING ( s s1 -- i ) Returns the last occurrence of string s1 in string s, or 0 if s1 is not found. Non-case sensitive. Also see: INSTRING, INSTR and RINSTR ~ ~ NAME-OK? NAME-OK? (s -- i) Returns true if the given string would be okay as a general object name. This is deprecated, and internally defined as: "exit" ext-name-ok? Also see: EXT-NAME-OK? ~ ~ PNAME-OK? PNAME-OK? (s -- i) Returns true if the given string would be okay as a player name. This is deprecated, and internally defined as: "player" ext-name-ok? Also see: EXT-NAME-OK? ~ ~ EXT-NAME-OK? EXT-NAME-OK? ( str:Name ref:Obj -- int:Ok? ) EXT-NAME-OK? ( str:Name str:Type -- int:Ok? ) Returns true if Name would be a legal name for an object depending on the object type. If Obj is the object you are going to SETNAME, then EXT-NAME-OK? will use the naming rules for that type of object. If the object does not exist yet, you may specify a string Type: "exit" or "e" "muf" or "program" or "f" "player" or "p" "thing" or "t" "room" or "r" Type's case is ignored. ~ ~ REGEXP 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 appropriate for use with the MIDSTR primitive, and consider the first character of the string to be position 1. The "flags" 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 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 "flags" argument may be 0, or a combination 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 ~ ~ REGSPLIT REGSPLIT ( str:text str:pattern int:flags -- list:result ) Splits the text by the given regular expression pattern. Empty pieces will be returned for consecutive matches. The "flags" 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.) Also see: REGSPLIT_NOEMPTY ~ ~ REGSPLIT_NOEMPTY REGSPLIT_NOEMPTY ( str:text str:pattern int:flags -- list:result ) Splits the text by the given regular expression pattern, into non-empty pieces. The "flags" 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.) Also see: REGSPLIT ~ ~ TOKENSPLIT 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|LockOps Lock Manipulation Operators getlockstr locked? parselock prettylock setlockstr supplicant testlock unparselock ~---------------------------------------------------------------------------- ~ ~ ~ ~ LOCKED? 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 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. Also see: UNPARSELOCK, LOCK?, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR and LOCKED? ~ ~ UNPARSELOCK UNPARSELOCK (l -- s) Unparses a lock into a string fit for program editing. Also see: LOCK?, PARSELOCK, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR and LOCKED? ~ ~ PRETTYLOCK PRETTYLOCK (l -- s) Unparses a lock into a string fit for players to see. Also see: LOCK?, PARSELOCK, UNPARSELOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR and LOCKED? ~ ~ TESTLOCK 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. Also see: LOCK?, PARSELOCK, UNPARSELOCK, PRETTYLOCK, GETLOCKSTR, SETLOCKSTR and LOCKED? ~ ~ SETLOCKSTR 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 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. ~ ~ SUPPLICANT SUPPLICANT ( -- d ) If the current program is being executed due to lock evaluation, returns the object the lock is being tested against. Otherwise, returns #-1. ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Array Manipulation Operators|ArrayOps Array Manipulation Operators array_appenditem array_compare array_count array_cut array_default_pinning array_delitem array_delrange array_diff array_excludeval array_explode array_extract array_findval array_first array_getitem array_getrange array_insertitem array_insertrange array_interpret 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_notify_secure array_nunion array_pin array_prev array_reverse array_setitem array_setrange array_sort array_sort_indexed array_union array_unpin array_vals }cat }dict }join }list }tell ~---------------------------------------------------------------------------- ~ ~ ~ ~ ARRAY_MAKE ARRAY_MAKE ( {?} -- a ) Creates a list type array from a stackrange. ~ ~ }LIST }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 ARRAY_MAKE_DICT ( {@ ?} -- a ) Creates a dictionary type array from a stackrange of index/value pairs. ~ ~ }DICT }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 ARRAY_NOTIFY ( a1 a2 -- ) Notifies all strings in array a1 to all dbrefs in array a2. Arrays must be homogenous of their respective types. ~ ~ ARRAY_NOTIFY_SECURE ARRAY_NOTIFY_SECURE ( a1 a2 a3 -- ) For every dbref in a3, notify a2 over their secure descriptors and a1 over their insecure descriptors. Triggers listener prop queues only with a1. ~ ~ }TELL }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'. Also see: ARRAY_NOTIFY ~ ~ ARRAY_JOIN 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" Also see: }JOIN, ARRAY_INTERPRET and }CAT ~ ~ ARRAY_INTERPRET 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" Also see: ARRAY_JOIN, }CAT and }JOIN ~ ~ }JOIN }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'. Also see: ARRAY_JOIN, }CAT and ARRAY_INTERPRET ~ ~ }CAT }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'. Also see: ARRAY_JOIN, }JOIN and ARRAY_INTERPRET ~ ~ ARRAY_COUNT ARRAY_COUNT ( a -- i ) Returns the count of number of items in the array. ~ ~ ARRAY_GETITEM|[] ARRAY_GETITEM ( a @ -- ? ) Returns item with index @ from an array. ~ ~ ARRAY_SETITEM|->[] ARRAY_SETITEM ( ? a @ -- a') Overwrites a given array item at index @ with new value ?. ~ ~ ARRAY_INSERTITEM ARRAY_INSERTITEM ( ? a @ -- a' ) Inserts a given value into an array. ~ ~ ARRAY_APPENDITEM|[]<- ARRAY_APPENDITEM ( ? a -- a') Appends the given item to the given list array. ~ ~ ARRAY_DELITEM ARRAY_DELITEM ( a @ -- a' ) Removes an item with index @ from an array. ~ ~ ARRAY_GETRANGE ARRAY_GETRANGE ( a @ @ -- a' ) Returns as an array the range between two indexes (inclusive) from an array. ~ ~ ARRAY_SETRANGE 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 ARRAY_INSERTRANGE ( a1 @ a2 -- a' ) Inserts items from array a2 into a1, starting at the given index. Returns the resulting array. ~ ~ ARRAY_DELRANGE ARRAY_DELRANGE ( a @ @ -- a' ) Deletes a range of items between two indexes (inclusive) from an array. ~ ~ ARRAY_NESTED_GET 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 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 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_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 ARRAY_REVERSE (a -- a') Takes a list array and reverses the order of its elements. ~ ~ ARRAY_COMPARE 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 ARRAY_EXPLODE ( a -- {@ ?} ) Explodes an array into a stackrange of its index/value pairs. Example: "index0" "value0" "index1" "value1" 2 ~ ~ ARRAY_KEYS ARRAY_KEYS ( a -- {@} ) Returns the keys of an array in a stackrange. Example: "index0" "index1" 2 ~ ~ ARRAY_VALS ARRAY_VALS ( a -- {?} ) Returns the values of an array in a stackrange. Example: "value0" "value1" 2 ~ ~ ARRAY_FIRST 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 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 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 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 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_PIN ARRAY_PIN ( arr -- arr' ) Given an array or dictionary, pins it such that changes to any dup'ed copy of that array on the stack will make changes to ALL copies. ~ ~ ARRAY_UNPIN ARRAY_UNPIN ( arr -- arr' ) Given an array or dictionary, unpins it such that changes to any dup'ed copy of that array on the stack will NOT change any other copy of that array. ~ ~ ARRAY_DEFAULT_PINNING ARRAY_DEFAULT_PINNING ( int -- ) Sets whether future arrays/dictionaries created in this process will be pinned by default. ~ ~ ARRAY_SORT|SORTTYPE_CASEINSENS|SORTTYPE_DESCENDING|SORTTYPE_SHUFFLE|SORTTYPE_CASE_ASCEND|SORTTYPE_NOCASE_ASCEND|SORTTYPE_CASE_DESCEND|SORTTYPE_NOCASE_DESCEND 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 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. Also see: ARRAY_SORT ~ ~ ARRAY_UNION 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 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 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 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 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 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 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 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: { #10 }list { #5 #10 #15 #10 #20 }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 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 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|PropOps Property Manipulation Operators addprop array_filter_flags array_filter_lock array_filter_prop array_get_propdirs array_get_proplist array_get_propvals array_get_reflist array_put_proplist array_put_propvals array_put_reflist blessed? blessprop envprop envpropstr getprop getpropfval getpropstr getpropval nextprop parsempi parsempiblessed parseprop parsepropex prop-name-ok? propdir? reflist_add reflist_del reflist_find remove_prop setprop unblessprop ~---------------------------------------------------------------------------- ~ ~ ~ ~ GETPROP 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, or if it is a valueless propdir. Also see: SETPROP, ADDPROP, REMOVE_PROP, GETPROPSTR, GETPROPVAL, INT?, DBREF?, STRING? and LOCK? ~ ~ GETPROPSTR 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 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 GETPROPFVAL ( d s -- f ) Returns the float value stored in the property ~ ~ ENVPROP 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 0. If the property is found, it will return the dbref of the object it was found on, and the value it contained. Also see: ENVPROPSTR ~ ~ ENVPROPSTR 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. Also see: ENVPROP ~ ~ ADDPROP 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 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. Also see: ADDPROP, REMOVE_PROP, GETPROPSTR and GETPROPVAL ~ ~ REMOVE_PROP 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? 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 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 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 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 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 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 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 UNBLESSPROP (dbrefObject strPropname -- ) Unblesses the given property for MPI. Requires Wizbit perms. ~ ~ BLESSPROP BLESSPROP (dbrefObject strPropname -- ) Blesses the given property for MPI. Requires Wizbit perms. ~ ~ BLESSED? 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 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_LOCK ARRAY_FILTER_LOCK ([d] l -- [d']) Takes a homogenous list array of dbrefs, and returns a list array with only those players and things who pass the given lock. ~ ~ ARRAY_FILTER_FLAGS 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 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 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 max_propfetch props maximum. (ML3 required.) ~ ~ ARRAY_PUT_PROPVALS 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 ARRAY_GET_PROPLIST ( d s -- a ) Reads in properties from a sequential proplist, and returns them in a list array. Proplists can be in any of these proplist styles: "propname#/1", "propname/1", or "propname1". If the program doesn't have permission to read the list, it returns an empty array. Reads up to max_propfetch props maximum. ~ ~ ARRAY_PUT_PROPLIST 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. ~ ~ PARSEPROP 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. ~ ~ PARSEMPI PARSEMPI (d s s i -- s) Returns the string output of the MPI Parser, given an object, an MPI string 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 PARSEMPI with a mucker level of less than 3. ~ ~ PARSEMPIBLESSED PARSEMPIBLESSED (d s s i -- s) Returns the string output of blessed execution of the MPI Parser, given an object, an MPI string 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. Requires Wizard permissions. ~ ~ PARSEPROPEX 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. ~ ~ PROP-NAME-OK? PROP-NAME-OK? (s -- i) Returns true if the given string is an acceptable property name that will not cause an error for SETPROP or any other property related primitive. Also see: SETPROP ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Database Related Operators|DBOps Database Related Operators addpennies array_get_ignorelist caller checkpassword contents contents_array controls copyobj copyplayer dbcmp dbref dbtop desc drop dump entrances_array exit? exits exits_array fail findnext flag? getlink getlinks getlinks_array ignore_add ignore_del ignoring? location match mlevel movepennies moveto name newexit newobject newpassword newplayer newprogram newroom next nextentrance nextowned objmem odrop ofail ok? osucc owner part_pmatch pennies player? pmatch pname_history prog program? recycle rmatch room? set setdesc setdrop setfail setlink setlinks_array setname setodrop setofail setosucc setown setsucc setsysparm stats stats_array succ sysparm sysparm_array thing? timestamps toadplayer trig truename unparseobj ~---------------------------------------------------------------------------- ~ ~ ~ ~ DBREF DBREF ( i -- d ) Converts integer i to object reference d. ~ ~ PROG PROG ( -- d) Returns the dbref of the currently running program. ~ ~ TRIG TRIG ( -- d) Returns the dbref of the original trigger. ~ ~ CALLER 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 DBTOP ( -- d) Returns the dbref of the first object beyond the top object of the database. 'dbtop ok?' would return a false value. ~ ~ DBCMP 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. This is deprecated, and internally defined as: = Also see: = ~ ~ UNPARSEOBJ 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 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 SETOWN (d d -- ) Sets the ownership of the first object to the player given in the second dbref. (wizbit only) ~ ~ LOCATION LOCATION ( d -- d' ) Returns location of object d as object d'. ~ ~ MOVETO 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 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 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 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 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 NEXT ( d -- d' ) Takes object d and returns the next thing in the linked contents/exits list of d's location. ~ ~ NEXTOWNED 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. Also see: NEXT ~ ~ FINDNEXT 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 Also see: NEXT and NEXTOWNED ~ ~ NEXTENTRANCE 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 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 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 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 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 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 PENNIES ( d -- i ) Gets the amount of pennies player object d has, or the penny value of thing d. ~ ~ ADDPENNIES 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 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 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 NEWPASSWORD ( d s -- ) Changed the password of the given player d to s. ~ ~ SET SET ( d s -- ) Sets flag s to object d. Recognizes negation (e.g. `!abode'). Also see: SETNAME, SETDESC and FLAG? ~ ~ FLAG? 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 absence 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.) Also see: SET and MLEVEL ~ ~ MLEVEL MLEVEL (d -- i) returns the mucker (or priority) level of the given object. If #-1 is passed, this returns the effective mucker level of the current program. Also see: MUCKER LEVELS ~ ~ OK? 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. Also see: EXIT?, PLAYER?, PROGRAM? and THING? ~ ~ PLAYER? 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. Also see: PROGRAM?, ROOM?, THING?, EXIT? and OK? ~ ~ ROOM? 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. Also see: PLAYER?, PROGRAM?, THING?, EXIT? and OK? ~ ~ THING? THING? ( d -- i ) Returns i as 1 if object d is a thing, otherwise returns i as 0. Also see: PLAYER?, PROGRAM?, ROOM?, EXIT? and OK? ~ ~ EXIT? EXIT? ( d -- i ) Returns 1 if object d is an exit object, 0 if otherwise. Also see: PLAYER?, PROGRAM?, ROOM?, THING? and OK? ~ ~ PROGRAM? 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. Also see: PLAYER?, ROOM?, THING?, EXIT? and OK? ~ ~ SYSPARM 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: (bool) 7bit_other_names - Limit exit/room/muf names to 7-bit characters (bool) 7bit_thing_names - Limit thing names to 7-bit characters (int) addpennies_muf_mlev - Mucker Level required to create/destroy pennies (time) aging_time - When to considered an object old and unused (bool) allow_listeners - Allow programs to listen to player output (bool) allow_listeners_env - Allow listeners down environment (bool) allow_listeners_obj - Allow objects to be listeners (bool) allow_zombies - Enable Zombie things to relay what they hear (bool) autolink_actions - Automatically link @actions to NIL (str) autolook_cmd - Room entry look command (time) clean_interval - Interval between memory/object cleanups (int) cmd_log_threshold_msec - Log commands that take longer than X millisecs (bool) cmd_only_overrides - Disable all built-in commands except wizard !overrides (int) command_burst_size - Max. commands per burst before limiter engages (int) command_time_msec - Millisecs per spam limiter time period (int) commands_per_time - Commands allowed per time period during limit (bool) compatible_priorities - Use legacy exit priority levels on things (str) connect_fail_mesg - Failed player connect message (bool) consistent_lock_source - Maintain trigger as lock source in TESTLOCK (str) cpennies - Currency name, capitalized, plural (str) cpenny - Currency name, capitalized (bool) dark_sleepers - Make sleeping players dark (bool) dbdump_warning - Enable warnings for upcoming database dumps (ref) default_room_parent - Place to parent new rooms to (str) description_default - Default description (bool) diskbase_propvals - Enable property value diskbasing (req. restart) (bool) do_mpi_parsing - Parse MPI strings in messages (bool) do_welcome_parsing - Parse MPI in welcome file or proplist (time) dump_interval - Interval between dumps (time) dump_warntime - Interval between warning and dump (str) dumpdone_mesg - Database dump finished message (bool) dumpdone_warning - Notify when database dump complete (str) dumping_mesg - Database dump started message (str) dumpwarn_mesg - Database dump finished message (bool) enable_home - Enable 'home' command (bool) enable_prefix - Enable prefix actions (int) exit_cost - Cost to create an exit (bool) exit_darking - Allow players to set exits dark (bool) expanded_debug_trace - MUF debug trace shows array contents (str) file_connection_help - 'help' before login (str) file_credits - Acknowledgements (str) file_editor_help - Editor help (str) file_help - 'help' main content (str) file_help_dir - 'help' topic directory (str) file_info_dir - 'info' topic directory (str) file_log_cmd_times - Command times (str) file_log_commands - Player commands (str) file_log_gripes - Player gripes (str) file_log_malloc - Memory allocations (str) file_log_muf_errors - MUF compile errors and warnings (str) file_log_programs - Text of changed programs (str) file_log_sanfix - Database fixes (str) file_log_sanity - Database corruption and errors (str) file_log_status - System errors and stats (str) file_log_stderr - Server error redirect (str) file_log_stdout - Server output redirect (str) file_log_user - MUF-writable messages (str) file_man - 'man' main content (str) file_man_dir - 'man' topic directory (str) file_motd - Message of the day (str) file_mpihelp - 'mpi' main content (str) file_mpihelp_dir - 'mpi' topic directory (str) file_news - 'news' main content (str) file_news_dir - 'news' topic directory (str) file_welcome_screen - Opening screen (bool) force_mlev1_name_notify - MUF notify prepends username for ML1 programs (int) free_frames_pool - Size of allocated MUF process frame pool (str) gender_prop - Property name used for pronoun substitutions (str) huh_mesg - Unrecognized command warning (str) idle_boot_mesg - Boot message given to users idling out (bool) idle_ping_enable - Enable server side keepalive pings (time) idle_ping_time - Server side keepalive time in seconds (bool) idleboot - Enable booting of idle players (bool) ieee_bounds_handling - Use IEEE standard for operations with INF and NAN (bool) ignore_bidirectional - Enable bidirectional ignore (bool) ignore_support - Enable support for @ignoring players (int) instr_slice - Max. uninterrupted instructions per timeslice (str) leave_mesg - Logoff message for QUIT (bool) legacy_password_hash - Use Legacy (insecure, compatible) Password Hash (int) link_cost - Cost to link an exit (int) listen_mlev - Mucker Level required for Listener programs (bool) lock_envcheck - Locks check environment for properties (bool) log_commands - Log player commands (bool) log_failed_commands - Log unrecognized commands (bool) log_interactive - Log text sent to MUF (bool) log_programs - Log programs every time they are saved (int) lookup_cost - Cost to lookup a player name (ref) lost_and_found - Place for things without a home (bool) m3_huh - Enable huh? to call an exit named "huh?" and set M3, with full command string (int) max_force_level - Max. number of forces processed within a command (int) max_instr_count - Max. MUF instruction run length for ML1 (int) max_interp_recursion - Max. MUF interpreter recursion (int) max_loaded_objs - Max. percent of proploaded database objects (int) max_ml4_nested_interp_loop_count - Max. MUF preempt interp loop nesting level for ML4 (0 = no limit) (int) max_ml4_preempt_count - Max. MUF preempt instruction run length for ML4, (0 = no limit) (int) max_nested_interp_loop_count - Max. MUF preempt interp loop nesting level (int) max_object_endowment - Max. value of an object (int) max_output - Max. output buffer size (int) max_pennies - Max. pennies a player can own (int) max_plyr_processes - Concurrent processes allowed per player (int) max_process_limit - Total concurrent processes allowed on system (int) max_propfetch - Max. size of returned property array (time) maxidle - Maximum idle time before booting (int) mcp_muf_mlev - Mucker Level required to use MCP (int) movepennies_muf_mlev - Mucker Level required to move pennies non-destructively (bool) mpi_continue_after_logout - Continue executing MPI after logout (int) mpi_max_commands - Max. number of uninterruptable MPI commands (str) muckname - Name of the MUCK (bool) muf_comments_strict - MUF comments are strict and not recursive (str) new_program_flags - Initial flags for newly created programs (int) object_cost - Cost to create an object (bool) optimize_muf - Enable MUF bytecode optimizer (int) pause_min - Min. millisecs between MUF input/output timeslices (str) pcreate_flags - Initial flags for newly created players (str) pennies - Currency name, plural (int) pennies_muf_mlev - Mucker Level required to read the value of pennies, settings above 1 disable {money} (str) penny - Currency name (int) penny_rate - Avg. moves between finding currency (bool) periodic_program_purge - Periodically free unused MUF programs (int) player_name_limit - Limit on player name length (ref) player_start - Home where new players start (bool) playermax - Limit number of concurrent players allowed (str) playermax_bootmesg - Max. players connection error message (int) playermax_limit - Max. player connections allowed (str) playermax_warnmesg - Max. players connection login warning (bool) pname_history_reporting - Report player name change history (time) pname_history_threshold - Length of player name change history (int) process_timer_limit - Max. timers per process (bool) quiet_moves - Suppress basic arrive and depart notifications (bool) realms_control - Enable support for realm wizzes (bool) recognize_null_command - Recognize null command (str) register_mesg - Login registration denied message (bool) registration - Require new players to register manually (str) reserved_names - String-match list of reserved names (str) reserved_player_names - String-match list of reserved player names (int) room_cost - Cost to create an room (bool) secure_teleport - Restrict actions to Jump_OK or controlled rooms (bool) secure_thing_movement - Moving things act like player (bool) secure_who - Disallow WHO command from login screen and programs (bool) server_cipher_preference - Honor server cipher preference order over client's (int) smtp_auth_type - SMTP auth type - 0 for CRAM_MD5, 1 for none, 2 for plain, 3 for login (str) smtp_from_email - SMTP From user email for the email header (str) smtp_from_name - SMTP From user name for the email header (bool) smtp_no_verify_cert - SMTP if true, don't verify server certs (str) smtp_password - SMTP Password (str) smtp_port - SMTP Port. If blank, SMTP will not work. (str) smtp_server - SMTP Server Host Name. If blank, SMTP will not work. (int) smtp_ssl_type - SMTP SSL type - 0 for StartTLS, 1 for TLS, 2 for no SSL (str) smtp_user - SMTP Username (bool) ssl_auto_reload_certs - Automatically reload certs if the cert file changes (str) ssl_cert_file - Path to SSL certificate .pem (str) ssl_cipher_preference_list - Allowed OpenSSL cipher list (str) ssl_key_file - Path to SSL private key .pem (str) ssl_keyfile_passwd - Password for SSL private key file (str) ssl_min_protocol_version - Min. allowed SSL protocol version for clients (int) start_pennies - Player starting currency count (bool) starttls_allow - Enable TELNET STARTTLS encryption on plaintext port (bool) strict_god_priv - Only God can touch God's objects (bool) tab_input_replaced_with_space - Change tab to space when processing input (bool) teleport_to_player - Allow using exits linked to players (bool) thing_darking - Allow players to set things dark (ref) toad_default_recipient - Default owner for @toaded player's things (bool) toad_recycle - Recycle newly-created toads (bool) use_hostnames - Resolve IP addresses into hostnames (int) userlog_mlev - Mucker Level required to write to userlog (ref) welcome_mpi_what - Effective 'this' for welcome.txt MPI (ref) welcome_mpi_who - Effective 'me' for welcome.txt MPI (bool) who_hides_dark - Hide dark players from WHO list (bool) wiz_vehicles - Only let Wizards set vehicle bits ~ ~ SYSPARM_ARRAY 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: "type" One of "string", "integer", "timespan", "dbref", or "boolean". "group" The logical group that this parameter belongs to. "name" The name of the @tune setting. "value" The value of the sysparm. May be an int, string, or dbref. "mlev" The mucker level required to read the value of this sysparm. "readmlev" The mucker level required to read the value of this sysparm. "writemlev" The mucker level required to write the value of this sysparm. "label" A description of the parameter. "nullable" Whether the parameter can have no value. "active" Whether the parameter currently affects the system. "default" Whether the parameter has been changed from defaults. 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". Also see: SETSYSPARM and SYSPARM ~ ~ SETSYSPARM SETSYSPARM ( s1 s2 -- ) Assigns the @tunable parameter s1 a value given by s2. s2 must contain a legal value for s1. If s1 is prefixed with '%', reset s1 to default instead, ignoring the value of s2. (wizbit only) Also see: SYSPARM and SYSPARM_ARRAY ~ ~ NAME NAME ( d -- s ) Takes object d and returns its name (@name) string field. ~ ~ SETNAME 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. Also see: SET, NAME, SETDESC and EXT-NAME-OK? ~ ~ TRUENAME TRUENAME ( d -- s ) Takes object d and returns its name string field. This is deprecated, and internally defined as: name Also see: NAME ~ PNAME_HISTORY PNAME_HISTORY ( d -- a ) Returns a dictionary representing the times in which the given player had a name change. If determinable, the "created_as" key holds the name at creation. The result of this wizbit-only primitive is affected by the following sysparms: pname_history_reporting - if no, the result is an empty dictionary. pname_history_threshold - amount of history to keep (0s = unlimited) ~ ~ DESC DESC ( d -- s ) Takes object d and returns its description (@desc) string field. ~ ~ SETDESC 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ SUCC SUCC ( d -- s ) Takes object d and returns its success (@succ) string field s. ~ ~ SETSUCC 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ FAIL FAIL ( d -- s ) Takes object d and returns its fail (@fail) string field. ~ ~ SETFAIL 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ DROP DROP ( d -- s ) Takes object d and returns its drop (@drop) string field. ~ ~ SETDROP 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ OSUCC OSUCC ( d -- s ) Takes object d and returns its osuccess (@osucc) string field. ~ ~ SETOSUCC 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ OFAIL OFAIL ( d -- s ) Takes object d and returns its ofail (@ofail) string field. ~ ~ SETOFAIL 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ ODROP ODROP ( d -- s ) Takes object d and returns its odrop (@odrop) string field. ~ ~ SETODROP 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 Also see: DESC, SUCC, FAIL, DROP, OSUCC, OFAIL, ODROP, ADDPROP and GETPROPSTR ~ ~ GETLINK 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 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 GETLINKS_ARRAY ( d -- a ) Returns a list array that contains the dbref of every object that the given object is linked to. ~ ~ ENTRANCES_ARRAY ENTRANCES_ARRAY ( d -- a ) Returns a list array that contains the dbref of every object linked to the given object. ~ ~ SETLINK 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 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 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 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 is #-1. This is broken up into a total, rooms, exits, things, programs, players, and garbage. This functions much as the @STATS command. (Needs Mucker Level 3) ~ ~ STATS_ARRAY STATS_ARRAY ( d -- a ) Returns, as an array, the number of objects owned by 'd', or the total objects in the system if d is #-1. This is broken up into a total, rooms, exits, things, programs, players, and garbage. This functions much as the @STATS command. (Needs Mucker Level 3) ~ ~ OBJMEM OBJMEM ( d -- i ) Returns the current number of bytes in use by the given object. ~ ~ COPYOBJ COPYOBJ ( d -- d' ) Creates a new object (returning d' on top of the stack), that is a copy of object d, in the inventory of the current player. Can only create one object per program run, if under Mucker Level 3. ~ ~ COPYPLAYER 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 TOADPLAYER ( d1 d2 -- ) @toads player d2, and chowns all their posessions to player d1. You can't toad wizard players. ~ ~ NEWPLAYER 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 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. Can only create one object per program run, if under Mucker Level 3. ~ ~ NEWOBJECT NEWOBJECT (d s -- d) Takes location and name and returns new thing's dbref. Owner is the person running the program. Can only create one object per program run, if under Mucker Level 3. ~ ~ NEWEXIT NEWEXIT (d s -- d) Takes location and name and returns new exit's dbref. Owner is the person running the program. Mucker level 3 and higher. ~ ~ NEWPROGRAM NEWPROGRAM ( s -- d ) Creates a new program object with the given name, and returns its dbref. Requires wizbit. ~ ~ RECYCLE 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? 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 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 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 ARRAY_GET_IGNORELIST ( ref:Player -- list:Players ) Returns a list array of players "Player" is ignoring. This primitive requires at least Mucker Level 3. ~ ~ DUMP DUMP ( -- b ) Triggers a database dump. Returns boolean true if it was triggered, false if not. The only reason a dump would fail to trigger is if there is already a dump happening at the time you run this. Fuzzball dumps are asynchronous, so if you want to know when the dump finishes, you can wait for an event with eventId "DUMP". This event is sent to all running processes. This primitive requires a Wizard bit. ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Time Manipulation Operators|TimeOps Time Manipulation Operators convtime date fmttime gmtoffset sleep systime systime_precise time timefmt timesplit ~---------------------------------------------------------------------------- ~ ~ ~ ~ TIME TIME ( -- s m h ) Returns the time of day as integers on the stack, seconds, then minutes, then hours. ~ ~ DATE 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 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'. Also see: SYSTIME_PRECISE, TIMESPLIT and TIMESTAMPS ~ ~ SYSTIME_PRECISE SYSTIME_PRECISE ( -- f ) Returns the number of seconds from Jan 1, 1970 GMT as a floating point number, with microsecond accuracy. Also see: SYSTIME ~ ~ GMTOFFSET GMTOFFSET ( -- i) Returns the server's offset from UTC in seconds. Result is negative for time zones west of the prime meridian. Result is positive for time zones east of the prime meridian. ~ ~ TIMESPLIT 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 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 -- date and time (default: %a %b %e %T %Y) %C -- year divided by 100 and truncated to an integer, as a decimal number (00-99) %d -- day of the month as a decimal number (01-31) %D -- %m/%d/%y %e -- day of the month as a decimal number (1-31); a single digit is preceded by a space %F -- %Y-%m-%d (ISO 8601 date) %g -- last 2 digits of the ISO 8601 week-based year as a decimal number (00-99) %G -- ISO 8601 week-based year as a decimal number %h -- %b %H -- hour (24-hour clock) as a decimal number (00-23) %I -- hour (12-hour clock) as a decimal number (01-12) %j -- day of the year as a decimal number (001-366) %m -- month as a decimal number (01-12) %M -- minute as a decimal number (00-59) %n -- new-line character %p -- AM or PM %r -- 12-hour clock time (default: %I:%M:%S %p) %R -- %H:%M %S -- second as a decimal number (00-60) %t -- horizontal-tab character %T -- %H:%M:%S (ISO 8601 time) %u -- ISO 8601 weekday as a decimal number (1-7), where Monday is 1 %U -- week number of the year (the first Sunday as the first day of week 1) as a decimal number (00-53) %V -- ISO 8601 week number as a decimal number (01-53) %w -- weekday as a decimal number (0-6), where Sunday is 0 %W -- week number of the year (the first Monday as the first day of week 1) as a decimal number (00-53) %x -- date (default: %m/%d/%y) %X -- time (default: %T) %y -- last 2 digits of the year as a decimal number (00-99) %Y -- year as a decimal number %z -- offset from UTC in the ISO 8601 format, or by no characters if no time zone is determinable (example: -0500 for EST) %Z -- time zone name or abbreviation, or by no characters if no time zone is determinable (examples: UTC, EDT, PST) %% -- % (percent sign) TIMEFMT processes format strings with the C function strftime(). The above list of conversion specifiers (formatting commands) is from the C (draft C17/C18) standard: some MUCKs may have more conversion specifiers available. Also see: FMTSTRING and FMTTIME ~ ~ CONVTIME CONVTIME (s -- i) Converts time string from "HH:MM:SS MO/DY/YR" format to systime seconds. ~ ~ FMTTIME FMTTIME (s1 s2 -- i) Converts time string s1 from the format given by s2 to systime seconds. Also see: TIMEFMT ~ ~ SLEEP 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|ProcOps Process Management Operators background bg_mode compile compiled? fg_mode foreground fork getpidinfo getpids instances ispid? kill mode pid pr_mode preempt program_getlines program_setlines queue setmode uncompile ~---------------------------------------------------------------------------- ~ ~ ~ ~ MODE 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. Also see: PR_MODE, FG_MODE, BG_MODE and SETMODE ~ ~ SETMODE 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. Also see: PR_MODE, FG_MODE, BG_MODE and MODE ~ ~ PR_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. Also see: PREEMPT, MULTITASKING, PR_MODE, MODE and SETMODE ~ ~ FG_MODE 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. Also see: FOREGROUND, MULTITASKING, PR_MODE, MODE and SETMODE ~ ~ BG_MODE 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. Also see: BACKGROUND, MULTITASKING, PR_MODE, MODE and SETMODE ~ ~ PREEMPT 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 its 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. Also see: MULTITASKING and MODE ~ ~ FOREGROUND 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. Also see: MULTITASKING and MODE ~ ~ BACKGROUND 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. Also see: MULTITASKING and MODE ~ ~ QUEUE 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) Also see: SLEEP, FORK, KILL, ISPID? and GETPIDINFO ~ ~ FORK 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) Also see: QUEUE, KILL, ISPID? and GETPIDINFO ~ ~ KILL 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. Must own the process if under Mucker Level 3. Also see: QUEUE, FORK, KILL, ISPID? and GETPIDINFO ~ ~ PID PID ( -- i) Returns the process ID of the program that is currently running. Also see: ISPID?, GETPIDS and GETPIDINFO ~ ~ ISPID? 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. Also see: GETPIDINFO, GETPIDS and PID ~ ~ GETPIDS 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. Also see: GETPIDINFO, ISPID? and PID ~ ~ GETPIDINFO 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. FILTERS - Array of event strings being watched for. INSTCNT - The number of instructions run so far. MLEVEL - The current MUCKER level. 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. Requires Mucker level 3 to check a pid other than current. Also see: GETPIDS ~ ~ INSTANCES 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 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 UNCOMPILE ( d -- ) Uncompiles the given muf program. This will throw an error if the program has any current instances running. ~ ~ COMPILED? COMPILED? ( d -- i ) Returns 0 if the given program is not compiled. Otherwise returns the number of compiled instructions. ~ ~ PROGRAM_GETLINES 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 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|ConnOps Connection Management Operators awake? descr descr_array descr_setuser descrboot descrbufsize descrcount descrdbref descrflush descrhost descridle descriptors descrleastidle descrmostidle descrnotify descrsecure? descrtime descruser firstdescr height lastdescr nextdescr online online_array setheight setwidth width ~---------------------------------------------------------------------------- ~ ~ ~ ~ DESCR 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? 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 ONLINE ( -- d ... i ) Returns a dbref for every player connected to the server, and lastly the number of connections. ~ ~ ONLINE_ARRAY ONLINE_ARRAY ( -- a ) Returns a single stack item, which is a list array, containing a dbref for every player connected to the server. ~ ~ DESCRCOUNT DESCRCOUNT ( -- i) Returns how many connections to the server there are. (Requires Mucker Level 3) ~ ~ DESCRDBREF 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 DESCRTIME (i -- i) Returns how many seconds the given descriptor connection has been connected to the server. (Requires Mucker Level 3) ~ ~ DESCRIDLE DESCRIDLE (i -- i) Returns how many seconds the descriptor connection has been idle. (Requires Mucker Level 3) ~ ~ DESCRLEASTIDLE DESCRLEASTIDLE (d -- i) Returns the descriptor number for the least idle connection of the given player dbref, or -1 if the player is disconnected. (Requires Mucker Level 3) ~ ~ DESCRMOSTIDLE DESCRMOSTIDLE (d -- i) Returns the descriptor number for the most idle connection of the given player dbref, or -1 if the player is disconnected. (Requires Mucker Level 3) ~ ~ DESCRSECURE? DESCRSECURE? (d -- i) Returns 1 if the descriptor number corresponds to a secure connection, and 0 otherwise. (Requires Mucker Level 3) ~ ~ DESCRHOST DESCRHOST (i -- s) Returns the hostname of the descriptor connection. (wizbit only) ~ ~ DESCRUSER DESCRUSER (i -- s) Returns the username of the descriptor connection. (wizbit only) ~ ~ DESCRBOOT DESCRBOOT (i -- ) Takes a descriptor number and disconnects that connection from the server. Basically @boot for a specific descriptor connection. (wizbit only) ~ ~ DESCRNOTIFY DESCRNOTIFY (i s -- ) Sends a string to a specific descriptor connection, similar to NOTIFY. (Requires Mucker Level 3) ~ ~ FIRSTDESCR 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. Descriptors have no promised ordering as they are basically operating system file handles; thus, this is probably only useful when #-1 is given as a parameter but it maintains support for other dbrefs as well for compatibility reasons. ~ ~ NEXTDESCR NEXTDESCR (i -- i) Takes a descriptor number, and returns the next connected descriptor number. To get the first descriptor number, use '#-1 firstdescr'. 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 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. Descriptors have no promised ordering as they are basically operating system file handles; thus, this is probably only useful when #-1 is given as a parameter but it maintains support for other dbrefs as well for compatibility reasons. ~ ~ DESCRFLUSH DESCRFLUSH (i -- ) Flushes the output text on the given descriptor. If i is -1, flushes output on all descriptors. (Requires Mucker Level 3) ~ ~ DESCRIPTORS 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. ~ ~ DESCR_ARRAY 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. Also see: DESCRIPTORS, DESCRCON and CONDESCR ~ ~ DESCR_SETUSER 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 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 . 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. ~ ~ SETWIDTH SETWIDTH ( int:descr int:width -- ) For the given descriptor, set the reported terminal width. Note that this set width can be overriden if the players's client sends an updated size and is mostly here for cases where a user's client doesn't provide size information but you wish to use the WIDTH function. Width is in number of characters on a line visible without scrolling. The maximum width is 65535. Sizing is per-descriptor instead of per-player, because each descriptor represents a different connection (and a player may have multiple), and each connection may have a different terminal size. (Requires MUCKER level 3) Also see: SETHEIGHT, HEIGHT and WIDTH ~ ~ SETHEIGHT SETHEIGHT ( int:descr int:height -- ) For the given descriptor, set the reported terminal height. Note that this set height can be overriden if the players's client sends an updated size and is mostly here for cases where a user's client doesn't provide size information but you wish to use the HEIGHT function. Height is in number of lines visible without scrolling. The maximum height is 65535. Sizing is per-descriptor instead of per-player, because each descriptor represents a different connection (and a player may have multiple), and each connection may have a different terminal size. (Requires MUCKER level 3) Also see: SETWIDTH, HEIGHT and WIDTH ~ ~ WIDTH WIDTH ( int:descr -- int:columns ) For the given descriptor, fetch the width of the client window in characters. This is the maximum number of characters the client can display without scrolling. Not all clients support NAWS (the Telnet protocol that reports screen size) and not all clients properly support NAWS (some don't report updates to screen size). If the size is unknown, this will return 0. You may use the SETWIDTH and SETHEIGHT primitives to force a size setting in such a case. Sizing is per-descriptor instead of per-player, because each descriptor represents a different connection (and a player may have multiple), and each connection may have a different terminal size. Also see: SETWIDTH, SETHEIGHT and HEIGHT ~ ~ HEIGHT HEIGHT ( int:descr -- int:rows ) For the given descriptor, fetch the height of the client window in rows (lines). This is the maximum number of lines the client can display without scrolling. Though practically speaking, you may need to subtract a few lines from this in order to insure no scrolling as this count of lines may include input fields and other UI elements as would vary from client to client. Not all clients support NAWS (the Telnet protocol that reports screen size) and not all clients properly support NAWS (some don't report updates to screen size). If the size is unknown, this will return 0. You may use the SETWIDTH and SETHEIGHT primitives to force a size setting in such a case. Sizing is per-descriptor instead of per-player, because each descriptor represents a different connection (and a player may have multiple), and each connection may have a different terminal size. Also see: SETWIDTH, SETHEIGHT and WIDTH ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Event Handling Operators|EventOps Event Handling Operators event_count event_exists event_send event_wait event_waitfor timer_start timer_stop watchpid ~---------------------------------------------------------------------------- ~ ~ ~ ~ EVENT_COUNT EVENT_COUNT ( -- i ) Returns the number of pending events waiting to be processed with EVENT_WAIT. ~ ~ EVENT_EXISTS 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 EVENT_WAIT ( -- ? s ) This is an inserver muf macro, that expands to '0 array_make event_waitfor' See: EVENT_WAITFOR ~ ~ 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 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 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 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 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|MCPOps MCP Support Operators mcp_bind mcp_register mcp_register_event mcp_send mcp_supports ~---------------------------------------------------------------------------- ~ ~ ~ ~ MCP_REGISTER 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 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 its 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 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 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 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|GUIOps GUI Support Operators 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 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 ~---------------------------------------------------------------------------- ~ ~ ~ ~ GUI_AVAILABLE 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 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 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 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 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 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 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 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 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 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 GUI_VALUE_SET (strDlogID strCtrlID strValue -- ) Sets the value of a given control in a given dialog. ~ ~ GUI_CTRL_COMMAND 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. ~ ~ GUI-OPTIONS|GUI_OPTIONS|GUIOPTIONS 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 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_MENU 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. Also see: GUI_CTRL_CREATE and GUI_DLOG_CREATE ~ ~ C_LABEL 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_IMAGE 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_HRULE 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_VRULE 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_BUTTON 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_CHECKBOX 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_RADIOBTN 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_EDIT 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_MULTIEDIT 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". Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_COMBOBOX 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_LISTBOX 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_SPINNER 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_SCALE 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_FRAME 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ C_NOTEBOOK 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. Also see: GUI_CTRL_CREATE, GUI_DLOG_CREATE and GUI_OPTIONS ~ ~ ~ ~ ~ ~---------------------------------------------------------------------------- ~ ~ Exception Handling|Exceptions Exception Handling abort checkargs try ~---------------------------------------------------------------------------- ~ ~ ~ ~ TRY|CATCH|CATCH_DETAILED|ENDCATCH|EXCEPTION|EXCEPTIONS|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 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 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. n - floating point number. 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 - variable. x - dictionary. y - array. (dictionary allowed) Y - array. (dictionary NOT allowed) ? - 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 Debugging breakpoints debug notation debug_line debug_off debug_on debugger debugger_break debugger_commands ~---------------------------------------------------------------------------- ~ ~ ~ ~ DEBUG_ON DEBUG_ON ( -- ) Turns the programs debug stack trace on. ~ ~ DEBUG_OFF DEBUG_OFF ( -- ) Turns the programs debug stack trace off. ~ ~ DEBUG_LINE DEBUG_LINE ( -- ) Displays a single line of debug stack trace if the player running the program controls it. ~ ~ DEBUGGER_BREAK 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. ~ ~ DEBUGGER|ZOMBIE|DEBUGGING 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. Also see: DEBUGGER_COMMANDS, BREAKPOINTS and NOTATION ~ ~ DEBUGGER_COMMANDS 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. Also see: DEBUGGER, BREAKPOINTS and NOTATION ~ ~ BREAKPOINTS 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. ~ ~ DEBUG NOTATION 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 its 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 ???) ???: An instruction that has been freed. If you see this please report it to the current server code maintainer. (As in ???) 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|MiscOps Miscellaneous force force_level forcedby forcedby_array smtp_send version ~---------------------------------------------------------------------------- ~ ~ ~ ~ VERSION VERSION ( -- s) Returns the version of this code in a string. Also see: __VERSION ~ ~ SMTP_SEND SMTP_SEND ( s:to s:to_name s:subject a:body -- i) Sends an email to email address 'to'. 'to_name' can be an empty string or it may be the name of the recipient. 'subject' will be the email subject, and 'body' will be an array that will be joined together with carriage return and newline to form the message body. The rules for how 'body' is joined together and what can be in 'body' are the same as ARRAY_JOIN. The return value will be an integer. 0 if the send was successful, -1 if SMTP is not configured for this server and thus not available, or -2 if there was an error sending. The error message will be in the MUCK's status log instead of output to the user for security reasons. The following @tune parameters are used by this program. They are only visible / settable by One: smtp_server The host to connect to smtp_port The port to connect to smtp_ssl_type 0 for StartTLS, 1 for TLS, 2 for no SSL smtp_no_verify_cert If true, do not verify server's SSL cert. smtp_auth_type 0 for CRAM_MD5, 1 for none, 2 for plain, 3 for login smtp_user User for authentication smtp_password Password for authentication smtp_from_name The name to use in the From message header smtp_from_email The email to use in the From message header Note that, unfortunately, the password is not encrypted on disk and is in plain text in @tune if logged in as the One user. WARNING: This primitive will (currently) block the MUCK server when sending mail. The timeouts used are pretty aggressive so we won't allow extended blocking, but it is easily possible for the MUCK to pause for a few seconds while a mail is sent. We have future plans to remedy this, but it is something you should be aware of as a "side effect". This primitive is Wizbit only. Also see: ARRAY_JOIN ~ ~ FORCE FORCE (d s -- ) Forces player d to do action s as if they were @forced. (wizbit only) Also see: FORCE_LEVEL and FORCEDBY ~ ~ FORCE_LEVEL FORCE_LEVEL ( -- i) Returns non-zero if the code we are running was triggered by an @force. Also see: FORCE and FORCEDBY ~ ~ FORCEDBY FORCEDBY ( -- d) Returns the dbref of the most recent object forcing the code to run, or #-1 if none. (Wizbit only) Also see: FORCE, FORCE_LEVEL and FORCEDBY_ARRAY ~ ~ FORCEDBY_ARRAY FORCEDBY_ARRAY ( -- a) Returns an array containg the dbrefs of all objects forcing the code to run, most recent first. (Wizbit only) Also see: FORCE, FORCE_LEVEL and FORCEDBY ~ ~