==================================================================
                     ProtoMUCK 2.0 MUF Manual

Written and edited by Akari ( Nakoruru08@hotmail.com ) to reflect
the additions to MUF made in ProtoMUCK.
See CREDITS.

To get manual information on a topic, type MAN <topic>. 
There are several topics on working with MUF. See: MAN TOPIC LIST

To view lists of prims for different prim categories:
PRIMS1 - Variables, Multitasking, Math and Logic
PRIMS2 - Stacks, Control Structures, Props
PRIMS3 - Time, Data Conversion, Notifying (I/O)
PRIMS4 - Connections, Locks, Strings
PRIMS5 - Data Base, System, Sockets
PRIMS6 - Arrays, Files, MCP Prims
PRIMS7 - MUF editing prims, MySQL prims, ANSI prims

To view a list of prim topics: PRIMS LIST
~~~~~
PRIM1|PRIMS1|PRIMS|PRIMITIVES
Variable Prims:
  VAR     VARIABLE     VARIABLE?     LVAR     LOCALVAR
  @       !            ME            TRIGGER  COMMAND
  DESCR   VAR!

Multitasking Prims:
  PREEMPT       FOREGROUND      BACKGROUND     MODE         SETMODE
  PR_MODE       FG_MODE         BG_MODE        SLEEP
  EVENT_WAIT    EVENT_SEND      EVENT_COUNT    EVENT_EXISTS
  TIMER_START   TIMER_STOP      EVENT_WAITFOR  WATCHPID
  ONEVENT       INTERRUPT_LEVEL

Math and Logic Prims:
  +     -     *     /     %     <     >     =     <=     >=  
  RANDOM     BITOR     BITXOR     BITSHIFT     ++     -- 
  CEIL       FLOOR     SQRT       PI           ROUND  
  SIN        COS       TAN        ASIN         ACOS   ATAN
  ATAN2      DIST3D    XYZ_TO_POLAR            POLAR_TO_XYZ  
  EXP        LOG       LOG10      FABS         POW    FRAND
  FMOD       MODF      AND        OR           NOT    ABS
  SRAND      GETSEED   SETSEED    SIGN         XOR

See: PRIMS2
~~~~
PRIM2|PRIMS2
Stack Prims:
  DUP         DUPN       LDUP          OVER        POP          
  ROT         ROTATE     SORT          SWAP        DEPTH     
  NUMBER?     DBREF?     INT?          STRING?     ADDRESS?
  SOCKET?     LOCK?      FLOAT?        VARIABLE?   ARRAY?   
  MARK        }          CHECKARGS     REVERSE     LREVERSE 
  POPN        PICK       PUT           DESCR?      SQL? 
  MARK? 

Control Structures:
  EXIT         CALL       EXECUTE     READ        PUBLIC      SLEEP
  PID          ISPID?     KILL        IF          ELSE        THEN
  QUEUE        FORK       INTERP      CALLER      ABORT       CASE
  TRIG         PROG       PARSEMPI    PARSEPROP               CANCALL?
  BEGIN        UNTIL      REPEAT      WHILE       BREAK       CONTINUE
  COMPILED?    TREAD      FOREACH     FOR         PROPQUEUE   ENVPROPQUEUE         
  INSTANCES    MAGECALL   WIZCALL     ARCHCALL    BOYCALL     GETPIDINFO
  GETPIDS      TRY        CATCH       ENDCATCH    JMP         READ_WANTS_BLANKS
  PARSEPROPEX  DEBUG_ON   DEBUG_OFF   DEBUG_LINE  SELFCALL    DEBUGGER_BREAK
  ENQUEUE

Property Prims:
  ADDPROP     GETPROP       SETPROP         ENVPROP       REMOVE_PROP
  GETPROPSTR  GETPROPVAL    GETPROPFVAL     ENVPROPSTR    NEXTPROP
  DESC        IDESC         HTMLDESC        IHTMLDESC     PROPDIR?
  SETDESC     SETSUCC       SETFAIL         SETDROP       SETOSUCC
  SETOFAIL    SETODROP      SUCC            FAIL          DROP
  OSUCC       OFAIL         ODROP           GETLOCKSTR  
  ANSIDESC    SETANSIDESC   IANSIDESC       SETIANSIDESC
  REFLIST_ADD REFLIST_FIND  REFLIST_DEL     COPYPROPS

See: PRIMS3
~~~~~
PRIM3|PRIMS3
Time Prims:
  TIME     SYSTIME     TIMESTAMPS     TIMESPLIT     TIMEFMT
  DATE     GMTOFFSET   SYSTIME_PRECISE

Data Conversion:
  ATOI     DBREF     INT     INTOSTR     CTOI     ITOC
  STOD     DTOS      FLOAT   STRTOF      FTOSTR   ITOH
  HTOI     FTOSTRC

Notifying Prims (I/O):
  NOTIFY              NOTIFY_EXCLUDE              NOTIFY_EXCEPT
  ANSI_NOTIFY         ANSI_NOTIFY_EXCLUDE         ANSI_NOTIFY_EXCEPT
  NOTIFY_HTML         NOTIFY_HTML_EXCLUDE         NOTIFY_HTML_EXCEPT
  NOTIFY_HTML_NOCR    NOTIFY_HTML_EXCLUDE_NOCR    HTML_NOCR_EXCEPT
  NOTIFY_DESCRIPTOR   ARRAY_NOTIFY                DESCRFLUSH
  STOPMIDI            PLAYMIDI                    COMMANDTEXT
  ARRAY_ANSI_NOTIFY   ARRAY_NOTIFY_HTML           ANSI_NOTIFY_DESCRIPTOR
  NOTIFY_DESCRIPTOR_CHAR

See: PRIMS4
~~~~~
PRIM4|PRIMS4

Connection Prims:
  AWAKE?     ONLINE     CONCOUNT     CONDBREF     CONTIME
  CONIDLE    CONDESCR   CONHOST      CONBOOT      CONNOTIFY
  CONUSER    CONIPNUM   CONPORT      DESCRCON     NEXTDESCR 
  DESCRIPTORS      DESCR_SETUSER     DESCR        DESCRFLUSH
  DESCR_HTML?      DESCR_PUEBLO?     DESCR?       DESCR_WELCOME_USER
  DESCR_LOGOUT     DESCRDBREF        DESCRIDLE    DESCRTIME
  DESCRHOST        DESCRIPNUM        DESCRPORT    DESCRCONPORT
  DESCRLEASTIDLE   DESCRMOSTIDLE     FIRSTDESCR   LASTDESCR
  DESCRUSER        GETDESCRINFO      DESCRBOOT    DESCR_SET
  DESCR_FLAG?      DESCRBUFSIZE

Locks Management:
  SETLOCKSTR     GETLOCKSTR     LOCKED?     PARSELOCK
  UNPARSELOCK    PRETTYLOCK     TESTLOCK    LOCK?
  ISLOCKED? 

Strings Prims:
  EXPLODE       INSTR        INSTRING     RINSTR       RINSTRING
  PRONOUN_SUB   STRCMP       STRINGCMP    STRINGPFX    STRNCMP
  STRCAT        SUBST        STRIPTAIL    STRIPLEAD    STRIP
  STRCUT        SPLIT        RSPLIT       MIDSTR       SMATCH
  STRLEN        TOUPPER      TOLOWER      STRENCRYPT   STRDECRYPT
  FMTSTRING     TOKENSPLIT   TEXTATTR     PARSE_ANSI   UNPARSE_ANSI
  ESCAPE_ANSI   ANSI_STRLEN  ANSI_STRCUT  ANSI_STRIP   STRIPSPACES
  NAME-OK?      PNAME-OK?    ANSI_MIDSTR  PARSE_NEON   FLAG_2CHAR
  POWER_2CHAR   UNESCAPE_URL ESCAPE_URL
 
See: PRIMS5
~~~~~
PRIMS5|PRIM5

Data Base Prims:
  CONTENTS      EXITS       NEXT         NEXTOWNED      NEXTPLAYER
  SETNAME       SET         SETOWN       SETLINK        GETLINKS
  MATCH         RMATCH      PART_PMATCH  PMATCH         NEWPASSWORD
  NEWPLAYER     COPYPLAYER  TOADPLAYER   OBJMEM         SETPASSWORD
  GETLINK       LOCATION    OWNER        CONTROLS       NEXT_FLAG 
  FLAG?         MLEVEL      DBCMP        CHECKPASSWORD  NEXTOWNED_FLAG
  NEWROOM       NEWOBJECT   NEWEXIT      TIMESTAMPS     NEXTTHING_FLAG
  PENNIES       ADDPENNIES  NAME         UNPARSEOBJ     MOVEPENNIES
  COPYOBJ       RECYCLE     MOVETO       STATS          DBTOP
  OK?           THING?      EXIT?        PLAYER?        PROGRAM?   ROOM?
  NEXTPROGRAM   NEXTEXIT    NEXTROOM     NEXTTHING      NEXTPLAYER_FLAG
  NEXTENTRANCE  POWER?      ISPOWER?     NEWPROGRAM     NEXTPLAYER_POWER   
  PNAME-OK?     NAME-OK?    FINDNEXT     CONTENTS_ARRAY EXITS_ARRAY
  GETOBJINFO    FIND_ARRAY  FLAG_2CHAR   POWER_2CHAR    ENTRANCES_ARRAY
  ANSI_NAME     REFSTAMPS   TOUCH        USE            ANSI_UNPARSEOBJ
  ISFLAG?
      
System Prims:
  SYSPARM         SETSYSPARM     LOGSTATUS     VERSION     FORCE
  FORCE_LEVEL     MOTD_NOTIFY    COMPILE       UNCOMPILE   BANDWIDTH
  DUMP            DELTA          SHUTDOWN      RESTART     ARMAGEDDON
  SYSPARM_ARRAY   SUID

Socket Prims:
  SOCKOPEN        SOCKCLOSE      SOCKSEND      SOCKRECV       NBSOCKOPEN
  SOCKCHECK       LSOCKOPEN      SOCKACCEPT    GET_SOCKINFO   SOCKET_SETUSER
  SET_SOCKOPT     SOCKTODESCR    SOCKSHUTDOWN  SOCKSECURE     SOCKUNSECURE
  SSL_SOCKACCEPT  UDPSEND        UDPOPEN       UDPCLOSE       UDP6SEND
  NBSOCK6OPEN     LSOCK6OPEN     SOCK6OPEN

See: PRIMS6
~~~~~
PRIMS6|PRIM6

Array Prims:
  ARRAY_MAKE           ARRAY_MAKE_DICT     
  ARRAY_EXPLODE        ARRAY_VALS           ARRAY_KEYS         ARRAY_COUNT  
  ARRAY_FIRST          ARRAY_LAST           ARRAY_PREV         ARRAY_NEXT
  ARRAY_GETITEM        ARRAY_SETITEM        ARRAY_APPENDITEM   ARRAY_SORT
  ARRAY_GETRANGE       ARRAY_SETRANGE       ARRAY_INSERTRANGE  ARRAY?
  ARRAY_DELITEM        ARRAY_DELRANGE       ARRAY_NUNION       ARRAY_UNION
  ARRAY_NINTERSECT     ARRAY_INTERSECT      ARRAY_NDIFF        ARRAY_DIFF
  ARRAY_NOTIFY         ARRAY_REVERSE        DESCR_ARRAY        DICTIONARY?
  ARRAY_GET_PROPDIRS   ARRAY_GET_PROPVALS   ARRAY_PUT_PROPVALS 
  ARRAY_GET_PROPLIST   ARRAY_PUT_PROPLIST   ARRAY_INSERTITEM
  ARRAY_GET_REFLIST    ARRAY_PUT_REFLIST    ARRAY_FINDVAL
  ARRAY_INSERTITEM     ONLINE_ARRAY         ARRAY_EXCLUDEVAL   
  ARRAY_ANSI_NOTIFY    NOTIFY_ARRAY_HTML    ARRAY_JOIN         ARRAY_MATCHKEY
  ARRAY_MATCHVAL       ARRAY_EXTRACT        ARRAY_FILTER_PROP  CONTENTS_ARRAY
  EXITS_ARRAY          ENTRANCES_ARRAY      GETOBJINFO         GETDESCRINFO
  FIND_ARRAY           ARRAY_CUT            ARRAY_COMPARE      ARRAY_INTERPRET
  ARRAY_SORT_INDEXED   ARRAY_SUM            ARRAY_STRING_FRAGMENT
  }ARRAY     }LIST     }DICT     }JOIN      }CAT

File Prims: 
  FWRITE    FREAD    FREADN    FAPPEND    FCR      FREADTO
  BWRITE    BREAD    BAPPEND   FRM        FREN     MKDIR
  FPUBLISH  FSINFO   FSTATS    CURID      FSIZE    GETDIR
  RMDIR

MCP Prims:
  MCP_REGISTER    MCP_REGISTER EVENT   MCP_SUPPORTS       MCP_BIND
  MCP_SEND        GUI_AVAILABLE        GUI_DLOG_CREATE    GUI_DLOG_SHOW
  GUI_DLOG_CLOSE  GUI_CTRL_CREATE      GUI_VALUES_SET     GUI_VALUES_GET
  GUI_VALUE_GET   GUI_CTRL_COMMAND

~~~~~
PRIMS7|PRIM7

MUF Editing Prims:
  KILL_MACRO          INSERT_MACRO      GET_MACROS_ARRAY 
  PROGRAM_LINECOUNT   PROGRAM_GETLINES  PROGRAM_DELETELINES  
  PROGRAM_INSERTLINES

MySQL Prims:
  SQLQUERY    SQLCONNECT    SQLCLOSE    SQLPING    SQL?

ANSI Prims:
 ANSI_MIDSTR            ANSI_NAME              ANSI_NOTIFY
 ANSI_NOTIFY_DESCRIPTOR ANSI_NOTIFY_EXCEPT     ANSI_NOTIFY_EXCLUDE
 ANSI_STRCUT            ANSI_STRIP             ANSI_STRLEN
 ANSI_UNPARSEOBJ        ARRAY_ANSI_NOTIFY      ESCAPE_ANSI
 PARSE_ANSI             UNPARSE_ANSI

Webserver Prims:
 BASE64ENCODE           BASE64DECODE           HTTPDATA

Ignore Support Prims:
 MAX_IGNORES            IGNORE_ADD	       IGNORE_DEL
 IGNORING?              ARRAY_GET_IGNORES
    
~~~~~
PRIMSLIST|PRIMS LIST|LIST PRIMS
MATH PRIMS         - Prims that handle math.
LOGICAL PRIMS      - Prims that handle logic operations.
PROP PRIMS         - Prims that handle property manipulation.
NOTIFICATION PRIMS - Prims that handle notification.
CONVERSION PRIMS   - Prims for converting data types.
DATABASE PRIMS     - Prims that manipulate the MUCK database.
STACK PRIMS        - Prims used to manage the stack contents.
STRING PRIMS       - Prims for working with strings.
PROGRAM PRIMS      - Prims that handle MUF iteration and calls.
TIME PRIMS         - Prims for time related functions.
VARIABLE PRIMS     - Prims to work with MUF variables.
CONNECTION PRIMS   - Prims for working with player connections.
LOCK PRIMS         - Prims for manipulating locks.
SYSTEM PRIMS       - Prims for making system changes to the MUCK.
MULTITASKING PRIMS - Prims that handle MUF multitasking levels.
SOCKET PRIMS       - Prims for working with ProtoMUCK socket control.
FILE PRIMS         - Prims for managing files on the server level.
ARRAY PRIMS        - Prims for working with MUF arrays.
MCP PRIMS          - Prims for working with graphical MUF protocal.
MUF EDIT PRIMS     - Prims for making MUF editors.
SQL PRIMS          - Prims for working with MySQL databases.
ANSI PRIMS         - Prims for working with ANSI color.

See: TOPIC LIST for different discussions of topics.
~
TOPIC LIST|TOPICLIST|MUFTOPICS|TOPICS|MUF TOPICS|TOPICS LIST

The following entries expand on some of the different topics that one
may need to become familiar with in order to work with MUF effectively:

MUF INTRO          - A little background on MUF.
DATA TYPES         - Discussion of the types of data in MUF.
MUCKER LEVELS      - An explanation of permissions levels in MUF.
SPECIAL SYMBOLS    - Special tokens used in writing MUF.
MULTITASKING       - An explanation about the modes MUF can run in.
DIRECTIVES         - An explanation of compile time directives.
FLAGS              - Explanations of how flags will affect MUF.
ANSI               - Information on ANSI colors.
LIBRARIES          - An explanation about how to work with MUF libs.
LOOPS              - Explanation and examples of MUF loops.
PROPQUEUES         - How to use propqueues with MUF.
ADDRESS            - An explanation of what an address is in MUF.
SOCKETS            - Some notes about the socket support in ProtoMUCK.
FILE PRIMS         - Some notes about the file prims.
FLOAT PRIMS        - A note explaining float support in MUF.
ARRAY PRIMS        - Some notes on using arrays with MUF. 
FUNCTION HEADERS   - Notes about using function headers in MUF.
MUF EVENTS         - Notes on how to use events in MUF.
MUF LABELS         - Notes on how to use the new MUF label points system.
MCP PRIMS          - Notes on the graphical MUF prims.
WEBSERVER/HTMUF/CGI- Notes on how to take advantage of cgi MUF support.
EXCEPTION HANDLING - Notes on exception handling in MUF.
INTERRUPTS         - Explanation and examples of MUF interrupt support.
MUF OPTIMIZING     - What the new byte code optimizer actually does. 
CREDITS            - Who to blame this mess on!
~~~~
MATH PRIMS|MATHPRIMS

The following prims are used to perform arithmetic with MUF:

+     -     *     /     %     <     >     =     <=     >=  
RANDOM     BITOR     BITXOR     BITSHIFT     ++     --
CEIL       FLOOR     SQRT       PI           ROUND  
SIN        COS       TAN        ASIN         ACOS   ATAN
ATAN2      DIST3D    XYZ_TO_POLAR     	     POLAR_TO_XYZ  
EXP        LOG       LOG10      FABS         POW    FRAND
FMOD       MODF      ABS        SIGN
SRAND      GETSEED   SETSEED
See: FLOAT PRIMS
~~~~
LOGICAL OPERATORS|LOGIC PRIMS|LOGICAL PRIMS

The following prims are used to make logic comparisons in MUF:

AND     OR     NOT    XOR

~
PROP PRIMS|PROPS|PROPPRIMS

The following prims are used to work with properties on objects:
  
ADDPROP     GETPROP       SETPROP         ENVPROP       REMOVE_PROP
GETPROPSTR  GETPROPVAL    GETPROPFVAL     ENVPROPSTR    NEXTPROP
DESC        IDESC         HTMLDESC        IHTMLDESC     PROPDIR?
SETDESC     SETSUCC       SETFAIL         SETDROP       SETOSUCC
SETOFAIL    SETODROP      SUCC            FAIL          DROP
SUCC        OFAIL         ODROP           GETLOCKSTR  
ANSIDESC    SETANSIDESC   IANSIDESC       SETIANSIDESC
REFLIST_ADD REFLIST_FIND  REFLIST_DEL     COPYPROPS

~
NOTIFICATION PRIMS|NOTIFICATIONPRIMS|NOTIFICATION

The following prims are used to notify messages from MUF:

NOTIFY              NOTIFY_EXCLUDE              NOTIFY_EXCEPT
ANSI_NOTIFY         ANSI_NOTIFY_EXCLUDE         ANSI_NOTIFY_EXCEPT
NOTIFY_HTML         NOTIFY_HTML_EXCLUDE         NOTIFY_HTML_EXCLUDE
NOTIFY_HTML_NOCR    NOTIFY_HTML_EXCLUDE_NOCR    HTML_NOCR_EXCEPT
NOTIFY_DESCRIPTOR   ARRAY_NOTIFY                DESCRFLUSH
STOPMIDI            PLAYMIDI                    COMMANDTEXT
ARRAY_ANSI_NOTIFY   NOTIFY_ARRAY_HTML           ANSI_NOTIFY_DESCRIPTOR
NOTIFY_DESCRIPTOR_CHAR

~
CONVERSION PRIMS|COVERSION|CONVERSIONPRIMS|CONVERTING

The following prims are used to convert data types in the stack:

ATOI      ( s -- i )
DBREF     ( i -- d )
INT       ( d -- i )
INTOSTR   ( d/i -- s )
CTOI      ( s -- i )
ITOC      ( i -- s )
STOD      ( s -- d )
DTOS      ( d -- s )
FLOAT     ( i -- f )
STRTOF    ( s -- f )
FTOSTR    ( f -- s )
ITOH      ( i -- s )
HTOI      ( s -- i )

See: DATA TYPES
~~~~
DATABASE PRIMS|DATA BASE PRIMS|DATABASEPRIMS|DATA BASEPRIMS

The following prims are used to work with the MUCK database:

  CONTENTS      EXITS       NEXT         NEXTOWNED      NEXTPLAYER
  SETNAME       SET         SETOWN       SETLINK        GETLINKS
  MATCH         RMATCH      PART_PMATCH  PMATCH         NEWPASSWORD
  NEWPLAYER     COPYPLAYER  TOADPLAYER   OBJMEM         SETPASSWORD
  GETLINK       LOCATION    OWNER        CONTROLS       NEXT_FLAG 
  FLAG?         MLEVEL      DBCMP        CHECKPASSWORD  NEXTOWNED_FLAG
  NEWROOM       NEWOBJECT   NEWEXIT      TIMESTAMPS     NEXTTHING_FLAG
  PENNIES       ADDPENNIES  NAME         UNPARSEOBJ     MOVEPENNIES
  COPYOBJ       RECYCLE     MOVETO       STATS          DBTOP
  OK?           THING?      EXIT?        PLAYER?   PROGRAM?   ROOM?
  NEXTPROGRAM   NEXTEXIT    NEXTROOM     NEXTTHING      NEXTPLAYER_FLAG
  NEXTENTRANCE  POWER?      ISPOWER?     NEWPROGRAM     NEXTPLAYER_POWER   
  PNAME-OK?     NAME-OK?    FINDNEXT     EXITS_ARRAY    CONTENTS_ARRAY
  GETOBJINFO    FIND_ARRAY  FLAG_2CHAR   POWER_2CHAR    ENTRANCES_ARRAY
  ANSI_NAME     ANSI_UNPARSEOBJ
~~~~
STACK PRIMS|STACKPRIMS

These prims are used to move and manipulate things on the stack:

  DUP         DUPN       LDUP          OVER        POP          
  ROT         ROTATE     SORT          SWAP        DEPTH     
  NUMBER?     DBREF?     INT?          STRING?     ADDRESS?
  SOCKET?     LOCK?      FLOAT?        VARIABLE?   ARRAY?   
  MARK        }          CHECKARGS     REVERSE     LREVERSE 
  POPN        PICK       PUT           DESCR?      SQL? 
  MARK? 

See: DATA TYPES
~~~~~
STRING PRIMS|STRINGPRIMS|STRINGS

The following prims are used to work with strings in MUF:

EXPLODE       INSTR        INSTRING     RINSTR       RINSTRING
PRONOUN_SUB   STRCMP       STRINGCMP    STRINGPFX    STRNCMP
STRCAT        SUBST        STRIPTAIL    STRIPLEAD    STRIP
STRCUT        SPLIT        RSPLIT       MIDSTR       SMATCH
STRLEN        TOUPPER      TOLOWER      STRENCRYPT   STRDECRYPT
FMTSTRING     TOKENSPLIT   TEXTATTR     PARSE_ANSI   UNPARSE_ANSI
ESCAPE_ANSI   ANSI_STRLEN  ANSI_STRCUT  ANSI_STRIP   STRIPSPACES
PNAME-OK?     NAME-OK?     ANSI_MIDSTR  PARSE_NEON   FLAG_2CHAR
POWER_2CHAR   UNESCAPE_URL ESCAPE_URL

Note on ANSI compatability:
ANSI_NOTIFY works only with Neon style ANSI tags, like ^BLUE^.
NOTIFY will work with standard ANSI format, such as FB6 uses. To
use MUSH or TILDE style ANSI, run the string with MUSH or TILDE ANSI
tags through PARSE_ANSI and it will convert the tags to standard 
ANSI which are then compatible with NOTIFY. 
See STANDARD ANSI, MUSH ANSI, NEON ANSI.
~~~~
PROGRAM PRIMS|PROGRAMPRIMS

These prims are used to direct the MUF programs:

EXIT         CALL      EXECUTE     READ        PUBLIC      SLEEP
PID          ISPID?    KILL        IF          ELSE        THEN
QUEUE        FORK      INTERP      CALLER      ABORT       CASE
TRIG         PROG      PARSEMPI    PARSEPROP   CANCALL?
BEGIN        UNTIL     REPEAT      WHILE       BREAK       CONTINUE
COMPILED?    TREAD     FOREACH     FOR         PROPQUEUE   ENVPROPQUEUE         
INSTANCES    MAGECALL  WIZCALL     ARCHCALL    BOYCALL     GETPIDINFO
GETPIDS      TRY       CATCH       ENDCATCH    JMP         READ_WANTS_BLANKS
PARSEPROPEX  DEBUG_ON  DEBUG_OFF   DEBUG_LINE              DEBUGGER_BREAK

See: LOOPS, MULTITASKING
~~~~
TIME PRIMS|TIMEPRIMS

The following prims are used to work with time:

TIME     SYSTIME     TIMESTAMPS     TIMESPLIT     TIMEFMT
DATE     GMTOFFSET   SYSTIME_PRECISE

Like most UNIX programs, time manipulation is handled in
seconds, and then broken down into readable formats for users.
The time understood by the MUCK is the number of seconds that
have passed since Jan 1, 1970, so things like years, months,
days, ete., have to be accounted for by the programmer.
~~~~
VARIABLE PRIMS|VARIABLEPRIMS

The following prims are used to work with variables in MUF:

VAR     VARIABLE     VARIABLE?     LVAR     LOCALVAR
@       !            ME            TRIGGER  COMMAND
DESCR   VAR!

Some of the above are not true prims, in that they have no
affect on the stack, but are classified as prims for reference
purposes.
~~~~~
CONNECTION PRIMS|CONECTIONPRIMS

The following prims are used to work with connections:

For working with DBREFS:
  AWAKE?           ONLINE           

For working with Connection Numbers:
  CONCOUNT         CONDBREF          CONIDLE       CONDESCR
  CONHOST          CONBOOT           CONUSER       CONIPNUM
  CONPORT          CONTIME           CONNOTIFY    

For working with Descriptors:
  DESCRCON         NEXTDESCR         DESCRIPTORS   DESCR_SETUSER
  DESCR            DESCRFLUSH        DESCR?        DESCR_WELCOME_USER  
  DESCR_HTML?      DESCR_PUEBLO?     DESCR_LOGOUT  DESCRDBREF
  DESCRIDLE        DESCRTIME         DESCRHOST     DESCRIPNUM
  DESCRPORT        DESCRCONPORT      FIRSTDESCR    LASTDESCR
  DESCRLEASTIDLE   DESCRMOSTIDLE     DESCRUSER     GETDESCRINFO
  DESCRBOOT        DESCR_SET         DESCR_FLAG?   DESCRBUFSIZE
~~~~~~
LOCK PRIMS

These prims help MUF interact with locks on the MUCK:

SETLOCKSTR     GETLOCKSTR     LOCKED?     PARSELOCK
UNPARSELOCK    PRETTYLOCK     TESTLOCK    LOCK?
ISLOCKED?      CHECKLOCK      CHECKLOCK

~~~~~
SYSTEM PRIMS|SYSTEMPRIMS

These prims are used to make changes in the MUCK system:

SYSPARM         SETSYSPARM     LOGSTATUS     VERSION     FORCE
FORCE_LEVEL     MOTD_NOTIFY    COMPILE       UNCOMPILE   BANDWIDTH
DUMP            DELTA          SHUTDOWN      RESTART     ARMAGEDDON
SYSPARM_ARRAY
~~~~~
MULTITASKING PRIMS

These prims are used to manage MUF program run-modes:

PREEMPT       FOREGROUND       BACKGROUND     MODE     SETMODE
PR_MODE       FG_MODE          BG_MODE        SLEEP
EVENT_WAIT    EVENT_SEND       EVENT_COUNT
TIMER_START   TIMER_STOP       EVENT_WAITFOR  WATCHPID
ONEVENT       INTERRUPT_LEVEL

See: MULTITASKING
~~~~
ANSI PRIMS

These prims are used when dealing with ANSI colors:

ANSI_MIDSTR            ANSI_NAME              ANSI_NOTIFY
ANSI_NOTIFY_DESCRIPTOR ANSI_NOTIFY_EXCEPT     ANSI_NOTIFY_EXCLUDE
ANSI_STRCUT            ANSI_STRIP             ANSI_STRLEN
ANSI_UNPARSEOBJ        ARRAY_ANSI_NOTIFY      ESCAPE_ANSI
PARSE_ANSI             UNPARSE_ANSI

See: ANSI
~~~~
DATA TYPES|OBJECT TYPES|DATATYPES

These are the fundamental data types in MUF:

integers (i)       - Whole numbers.
floats   (f)       - Decimal numbers.
strings  (s)       - ASCII Character strings.
dbrefs   (d)       - Database reference numbers.
addresses(address) - Names of MUF functions.
socket   (socket)  - A socket pointer.
lsocket  (lsocket) - A listening socket pointer
array    (a)       - A MUF style array.
locks    (l)       - A special string that represents a lock
variables(v)       - Variables that store any data type.

Additional notations:
numbers  (n)       - Either float or int.
Unknown  (x)       - More than one data type.
Index    (@)       - Index name in arrays.
Value    (?)       - Value contents in arrays.
Stackrange({?})    - See STACKRANGE

~~~~
MUF|STACK|MUF OR STACK|MUF AND STACK|MUF INTRO|MUFINTRO

MUD FORTH
---------
MUF was introduced to TinyMUCK in ages past, and since then,
has become the most powerful programming language offered by
MU**s.
MUF stands for MUD FORTH, though other interpretations include 
Multi-User FORTH, or MUCK FORTH.

Like the FORTH that it is based on, MUF uses a stack based
architecture. Data types go onto the stack, prims act on
the data types, removing them from the stack, and return 
the result of the operation, if any, to the stack. 

PRIMS are always performed on the data types at the top of
the stack, except for those used to move the stack contents
around. This results in a style of math known as Reverse
Polish Notation (RPN). I.e,  1 2 + instead of 1 + 2.

See: DATA TYPES
~~~
SPECIAL SYMBOLS|TOKENS|SYMBOLS|SPECIALSYMBOLS|$|(|)|.|\

Comments in MUF are contained within parentheses: ( )
The comments may span more than one line, as long as there is
always a closing ( for every opening ). Comments may not contain
parentheses.

Words in MUF that start with a . mark are macros. See the MUF
editor help for more details on those.

Words that start with $ are compile time directives. See man
directives for more information.

By using \ in front of a prim name it is possible to force the 
MUF to compile using the inserver version of that prim instead of
any definitions of that prim.
~~~
MUSHANSI|MUSH ANSI|MUSH COLORS

MUSH ANSI uses the following letters, prepended with %c. 
Example: %cg turns the text green.

        f - flash                       i - inverse
        h - hilite(bold)                n - normal
        u - underline
        x - black foreground            X - black background
        r - red foreground              R - red background
        g - green foreground            G - green background
        y - yellow foreground           Y - yellow background
        b - blue foreground             B - blue background
        m - magenta foreground          M - magenta background
        c - cyan foreground             C - cyan background
        w - white foreground            W - white background

See: NEON ANSI, STANDARD ANSI, TILDE ANSI
~~~
TILDE ANSI|TILDEANSI|TILDE COLORS

TILDE ANSI started out as a MUF library on FB MUCKs, and was 
eventually worked into the internal notification routines of
GlowMUCK. It is basically a short cut format for STANDARD ANSI
formats. 
Example: ~&110 turns the text red.
If you want to leave one of the attributes as it was, use a '-'.
Example: ~&1-- changes the text to bold without changing the color.
Syntax: ~&<Attribute><Foreground Color><Background Color>

Attributes: 
        0 = Normal        5 = Blinking
        1 = Bold          7 = Hidden
        2 = Invert        8 = Invert

Colors for Foreground and Background:
        0 - Black         4 - Blue
        1 - Red           5 - Magenta/Purple
        2 - Green         6 - Cyan
        3 - Yellow        7 - Grey/White

See: STANDARD ANSI, NEON ANSI, MUSH ANSI
~~~
STANDARDANSI|STANDARD ANSI|STANDARD COLORS

STANDARD ANSI color tags are created by: 
\[[ followed by a series of number instructions seperated by ;
followed by an 'm'.

\[[0 resets the color to normal.
\[[1 is to make the text bold.
\[[2 is to set the colors to the darker set.
\[[3 is to define a forground color, and must be followed by a number
     between 0 - 7 immediately following it.
\[[4 is to define a background color if followed by a number
     between 0 - 7.
\[[4 followed by no other number sets the text as being underlined.
\[[5 sets the text as being flash.
\[[7 is to invert the text colors.

Both \[[3 and \[[4 need to be followed by a second number to indicate
the color they are defining. The choices are as follows:

0 - Black        4 - Blue
1 - Red          5 - Magenta/Purple
2 - Green        6 - Cyan
3 - Yellow       7 - Grey/White

More than one instruction can follow the initial \[[, for example:
\[[1;37;4;41m = Bold, underline, white text over red background.

See: NEON ANSI, MUSH ANSI, TILDE ANSI
~~~~
NEON ANSI|NEONANSI|NEON COLORS|ANSI

NeonANSI is done by putting a color code between two ^ signs.
Example: ^RED^ would turn all the following text red.
The following colors are recognized by ProtoMUCK:

Normal colors |  Darker or Non-Bold colors | Background Colors
RED              CRIMSON or CRED             BRED
GREEN            FOREST  or CGREEN           BGREEN
YELLOW           BROWN   or CYELLOW          BYELLOW
BLUE             NAVY    or CBLUE            BBLUE
PURPLE           VIOLET  or CPURPLE          BPURPLE
CYAN             AQUA    or CCYAN            BCYAN
WHITE            GRAY    or CWHITE           BWHITE
BLACK            GLOOM   or CBLACK           BBLACK

In addition, the following ANSI tokens can be used:
    ^CFAIL^ -- Color defined for when commands fail. 
    ^CSUCC^ -- Color defined for when commands work.
    ^CINFO^ -- A color used in various info outputs.
    ^CNOTE^ -- Another info output color.
    ^CMOVE^ -- The color defined for the arrive/depart messages.

The actual color these tags represent may vary from place to place as well
as character to character, depending on settings made both at compile time, 
as well as in the muck. These can all be customized in-muck with:
    _/colors/fail          _/colors/succ          _/colors/info
    _/colors/note          _/colors/move

See: MUSH ANSI, STANDARD ANSI, TILDE ANSI, NEON ANSI2, and ANSI PRIMS
~~~
MATH OPERATORS|+|-|*|/|%|MODULO|ADD|SUBTRACT|MULTIPLY|DIVIDE

+ - * / % ( n1 n2 -- n3 )
-------------------------
Level: M1 Apprentice
n1 and n2 = Any integer or float.
n3 = If n1 and n2 are both ints, n3 is an int, otherwise is a float.

These words perform arithmetic operations on numbers. `+' = addition
(n1 + n2); `-' = subtraction (n1 - n2); `*' = multiplication (n1 times
n2, or n1 * n2); `/' = division (n1 divided by n2, or n1 / n2) with
integer division truncation of fractions; `%' = modulo (remainder of
n1 / n2, or n1 % n2) Please note: all these operations may also be
performed where n1 is a variable type.  This is mainly useful in
calculating an offset for a variable array. + and - may also be
performed on dbrefs.
~
LOGICAL OPERATORS|<|>|<=|>=|=|LESS THAN|GREATER THAN|EQUALS

< > = <= >= ( n1 n2 -- i )
--------------------------
Level: M1 Apprentice
n1 and n2 = Any float or integer.
i = integer result of comparison. Always 1 or 0.

Performs relational operations on integers i1 and i2. These return i
as 1 if the expression is true, and i as 0 otherwise.
~
ADDPENNIES

addpennies ( d i -- )
---------------------
Level: M2 -> W2 Apprentice to Wizard
d = dbref of a PLAYER or THING
i = integer representing the number of pennies to add
d must be a player or thing. 

For M2 and M3, can only add or subtract pennies to players, up to
the MAX_PENNIES system parameter, or down to 0.
W1's may also add and subtract pennies to objects of type THING
but are still limited by MAX_PENNIES.
W2's and up work the same as W1's, except are not limited by 
MAX_PENNIES.
~
ADDPROP

addprop ( d s1 s2 i -- )
------------------------
Level: M1 Apprentice.
d  = Any valid dbref.
s1 = string representing the prop name.
s2 = Contents of prop if storing a string.
i  = Contents of prop if storing an integer.
*Note* This prim is pretty much outdated, the 'setprop' prim is far
easier to use and accomplishes the same thing with more data types.
Addprop has been left in for backwards compatability, more than anything.

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.  If you store values, you must
ensure that it they are never zero.  Otherwise, when the user stores a
non-zero number into the string field, (users may only access string
fields) the next time TinyMUCK is dumped and loaded up again, the
value field will be replaced with atoi(string field).  If it is
necessary to store zero, it is safer to just add 1 to everything.

See: SETPROP
~
AND

and ( x y -- i )
----------------
Level: M1 Apprentice
x and y can be anything on the stack
i = integer 1 if true, 0 otherwise.

Performs the boolean `and' operation on x and y, returning i as 1 if
both i1 and i2 are TRUE, and returning i as 0 otherwise.
~
ANSI_NOTIFY

ansi_notify ( d s -- )
----------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string to notify to dbref d.

Works just like notify, but parsed for ANSI strings. If d is a player 
set = C, or a PUPPET owned by a player set = C, then the message will
be sent with ANSI tags for showing color. If the player is not set = C
the message will be sent, stripped of ANSI tags, for normal message 
displaying.

See: ANSI
~
ATOI

atoi ( s -- i )
---------------
Level: M1 Apprentice
s = Any string.
i = integer representing the string converted to an int.

Turns string s into integer i.  If s is not a valid number, or is an
empty string, then 0 is pushed onto the stack.
~
CALL

call ( d -- ? ) or ( d s -- ? )
-------------------------------
Level: M1 and W1 Apprentice and Mage
d = Valid program dbref.
s = Optional string to call a public function.
? = The contents of the stack when the called program finishes.

Calls another program d.  d must have been compiled already. d will
inherit the values of ME, LOC, TRIGGER, and all other variables.
If s is included, and there is a function marked as PUBLIC in 
program d. Call is subject to the following permissions restrictions:
If the function is not declared public, it can't be directly called.
If the program is not set = L, only W1 or higher can call it.
If the program is set = L, any M-Level can call it.
~
CONTENTS

contents ( d -- d' )
--------------------
Level: M1 Apprentice
d = any room, player, or thing.

Given a dbref of a player, room, or thing, it returns the dbref of 
the first thing found within that object. After this, using the
'next' prim on d' will return the next thing in the list. If there 
are no contents, it will return #-1. M1's cannot list anything set
DARK via this prim.

See: EXITS, NEXT
~
COPYOBJ

copyobj ( d1 -- d2 )
--------------------
Level: M1 -> W2 Apprentice to Wizard
d1 = dbref of anything of type THING.
d2 = dbref of new object.

For levels M1 -> M3, copyobj will create one copy of a THING owned
by that player per run of the program. Attempts to create more than
one THING per program call will cause the program to abort.
For W1, they can create as many copies per program call as they want
but only of THINGS they own.
For W2 and up, any number of copies can be made of any object of type
THING on the MUCK.
~
DBCMP

dbcmp ( d1 d2 -- i )
--------------------
Level: M1 Apprentice
d1 and d2 = any dbref, valid or not
i = 1 if the two dbrefs are the same, otherwise 0

Performs comparison of database objects d1 and d2. If they are the
same object, then i is 1, otherwise i is 0.
~
DBREF

dbref ( i -- d )
----------------
Level: M1 Apprentice
i = any integer
d = any dbref

Converts integer i to object reference d.
~
DESC|IDESC|HTMLDESC|IHTMLDESC|ANSIDESC|IANSIDESC

desc ansidesc iansidesc idesc htmldesc ihtmldesc( d -- s )
------------------------------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = Contents of the appropriate prop. 

Takes object d and returns the contents of the appropriate
description field. It is an inserver definition for:
"<prop>" getpropstr
desc      = The description to be shown non-Pueblo users for an object.
ansidesc  = The description to be shown with color support.
htmldesc  = The description to be shown to Pueblo users, supports 
            HTML scripting.
idesc     = The description to be shown non-Pueblo users when on the
            inside of an object. Ideal for vehicles.
iansidesc = The color description to be shown users on inside of object.
            Ideal for vehicles.
ihtmldesc = The description to be shown users on a Pueblo supported
            client when on the inside of an object. Ideal for vehicles.

See: SUCC, SETSUCC
~
DUP

dup ( x -- x x )
----------------
Level: M1 Apprentice
x = Anything on the top of the stack may be duplicated.

Duplicates the item at the top of the stack.
~
EXECUTE

execute ( a -- ?? )
-------------------
Level: M1 Apprentice
a = address of a function on the stack.

Executes the function pointed to by the address a on the stack.

See: ADDRESS?, ADDRESS
~
EXIT

exit ( -- )
-----------
Level: M1 Apprentice

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

exit? ( d -- i )
----------------
Level: M1 Apprentice
d = Any dbref.
i = integer representing a true or false result.

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

See also PLAYER?, PROGRAM?, ROOM?, THING?, OK?.
~
EXITS

exits ( d -- d' )
-----------------
Level: M1 Apprentice
d = any room, player, or thing.

Given a dbref of a player, room, or thing, it returns the dbref of 
the first exit attached to that object. After this, using the
'next' prim on d' will return the next exit in the list. If there 
are no exits, it will return #-1. M1's cannot list anything set
DARK via this prim.

See: CONTENTS, NEXT
~
EXPLODE

explode ( s1 s2 -- ... i )
--------------------------
Level: M1 Apprentice
s1 = string to break up.
s2 = string indicating the mark to break s1 apart as.
... = strings returned to the stack after s1 is exploded.
i  = integer representing the number of strings put on the stack.

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".)  s2 may be any length.  
But "" (null string) is not an acceptable string for parameter s2.
If s2 is not found anywhere in s1, then s1 is pushed back on the stack
followed by an integer of 1.
~
FLAG?

flag? ( d s -- i )
------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the flag to check for.
i = 1 if true, 0 if false.


Reads the flag of object d, specified by s, and returns its state: 1 =
on; 0 = off.  Different flags may be supported in different
installations.  The program will abort if given unsupport, or unknown
flags.

See: FLAGLIST for a list of the flags that can be checked for.
~
FLAGLIST
Names and aliases of flags:

Settable Flags:
ABODE/AUTOSTART/ABATE   (A)     BUILDER/BOUND           (B)
CHOWN_OK/COLOR_ON/ANSI  (C)     DARK/DEBUG              (D)
GUEST                   (G)     HAVEN/HARDUID/HIDE      (H)
IDLE                    (I)     JUMP_OK                 (J)
ANTIPROTECT             (K)     LINK_OK                 (L)
NO_COMMAND              (N)     LIGHT                   (O)
QUELL                   (Q)     SILENT/SETUID/STICKY    (S)
VEHICLE/VIEWABLE        (V)     XFORCIBLE               (X)
EXAMINE_OK              (Y)     ZOMBIE/PUPPET           (Z)
LOGWALL                 (!)     MUFCOUNT                (+)
PROTECT                 (*)     PARENT/PROG_DEBUG       (%)
HIDDEN                  (#)     MOBILE                  (?)
CONTROLS                (~)     IMMOBILE                (|)

Non-Settable Flags:
EXIT                    (E)     FORTH PROGRAM           (F)
TRUEIDLE                        PLAYER                  (P)
ROOM                    (R)     THING                   (T)
UNLINKED                (U)     LISTENER
COMMAND                 (N/A)   PUEBLO                  ($)
HTML                    (&)     UNUSED/OLD              (@)
INTERNAL                

Permissions Bits:
MEEPER                  (M)     MUCKER1                 (M1)
MUCKER2                 (M2)    MUCKER3                 (M3)
WIZARD1/MAGE            (W1)    WIZARD2/WIZARD          (W2)
WIZARD3/ARCHWIZARD      (W3)    WIZARD4/BOY             (W4)
WIZARD5/MAN             (W5)

Type 'help <flag>' to get more help on a flag.

~
GETLINK

getlink ( d -- d' )
-------------------
Level: M1 Apprentice
d  = Any valid dbref.
d' = dbref representing result depending on what d was.

If d is an exit, it returns whatever the exit is linked to.
If d is a player, program, or thing, it returns its 'home'.
If d is a room, it returns the room's drop-to.
If there is no link set for d, it returns #-1.
~
GETPROPSTR

getpropstr ( d s1 -- s2 )
-------------------------
Level: M1 Apprentice
d  = Any valid dbref.
s1 = string representing prop to retrieve.
s2 = string representing contents of the prop.

s must be a string. Retrieves string associated with property s in
object d.  If the property is cleared, or is of any type other than
string, "" (null string) is returned. Users below M3 level cannot 
read . props, and users below W3 level cannot read @ props.
~
GETPROPVAL

getpropval ( d s -- i )
-----------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the name of the prop to retrieve.
i = integer representing the value stored on the prop.

Retrieves the integer value i associated with property s in object d. 
If the property is cleared, 0 is returned. If the property is not an
integer, it returns 0. Users below M3 level cannot read . props, and
users below W3 level cannot read @ props.

See: GETPROP, GETPROPFVAL, GETPROPSTR
~
GETPROPFVAL

getpropfval ( d s -- f )
------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string represeting the name of the prop to retrieve.
f = float representing the value of that prop.

Retrieves the float value f associated with property s in object d. 
If the property is cleared, 0 is returned. If the property is not a
float, it returns 0.0. Users below M3 level cannot read . props, and
users below W3 level cannot read @ props.

See: GETPROP, GETPROPVAL, GETPROPSTR
~
IF|ELSE|THEN|TRUE|FALSE

if ... [ else ... ] then ( x -- )
---------------------------------
Level: M1 Apprentice
x = Any data object on the stack.

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.
In MUF, the following are FALSE:
Empty strings.
A dbref of #-1. (All other negative dbrefs are TRUE).
0 integers.
0.00000 float points.
The { stack marker.
MUF arrays with nothing in them. ( empty arrays )
Locks that always pass. ( True bools )
All other data types and conditions are TRUE.

See: IF2 for a summary. See CASES for a similiar structure.
~
IF2|ELSE2|THEN2

IF - THEN: Executes everything between the IF and the THEN if the
           top of the stack is true, otherwise skips to what comes
           after the THEN.
   <anything on the stack> IF <code> THEN

IF - ELSE - THEN: Executes everything between the IF and the ELSE
                  if the top of the stack is true. If the top of 
                  the stack is false, it executes everything 
                  between the ELSE and the THEN, skipping what
                  comes between the IF and the ELSE.
   <anything on the stack> IF <code> ELSE <code> THEN
~
CASES|CASE|WHEN|END|DEFAULT|ENDCASE

Cases: As seen in the popular MUF library lib-cases.muf

The following in-server definitions have been included in order
to allow one to make case structures with MUF quite easily:

case    = begin dup       
when    = if pop          
end     = break then dup  
default = pop 1 if        
endcase = pop pop 1 until 

These definitions make it possible to create CASE structures in MUF:
 <data> case
   <test> when <effect> end
   <test> when <effect> end
   <test> when <effect> end
   <test> when <effect> end
  default <otherwise> end
endcase

See: CASE2 for an example in MUF.
~
CASE2|CASES2

As taken from $lib/cases:

read case
  "#help" over stringcmp not swap "#h" stringcmp not or when do-help end
  "#help2" over stringcmp not swap "#h2" stringcmp not or when do-help2 end
  "#list" stringcmp not when do-list end
  default pop give-error end
endcase

~
TRUENAME

truename ( d -- s )
-------------------
Level: M1 Apprentice
d = Any valid dbref.
s = String representing the name of the dbref.

Takes object d and returns its true name string field.

As of Proto1.6 and newer, the TRUENAME prim behaves as follows:
If the dbref is a thing or player, it returns the %n alias of that
object. If it is an exit, it will return the name of that exit up to
the first ';' mark. Any other object will just return that object's
full name. Also, if the alias matches to the name of an existing 
player on the MUCK, the normal name of the player or puppet is 
returned instead of the alias.

See: NAME
~
INSTR

instr ( s1 s2 -- i )
-------------------
Level: M1 Apprentice
s1 = string to be scanned.
s2 = string to check for in s1.
i  = integer representing the result.

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

See also RINSTR, INSTRING, RINSTRING.
~
INT

int ( x -- i )
--------------
Level: M1
x = Any dbref, float or variable that is a dbref or float to an int.
i = integer result.

Converts variable or object x to integer i.
~
INTOSTR

intostr ( x -- s )
------------------
Level: M1 Apprentice
x = Either a dbref or an int.
s = string representing the dbref or integer.

x must be an integer or a dbref. Converts x into string s. If
x is a dbref, the string will be the dbref number, without the
# symbol.

See: DTOS
~
LOCATION

location ( d -- d' )
--------------------
Level: M1 Apprentice
d  = Any valid dbref.
d' = dbref representing the location of d.

Returns location of object d as object d'.
~
MATCH

match ( s -- d )
----------------
Level: M1 -> W1 Apprentice to Mage
s = string to try and match.
d = dbref representing result of match attempt.

Given string s, it tries to match this against different objects around
the player in the priority order:
1. Checks to see if the string is 'home'.
2. Checks to see if the string is 'here'.
3. Checks to see if the string is 'me'.
4. Checks the player's inventory.
5. Checks all the objects in the current room.
6. Checks all the exits that the player may use from current location.
If being used by a Mage or higher, it will check the following two
as well, before the above six:
1. Full PLAYER names prepended with '*'.
2. Checking to see if the string is a dbref# and matching it if so.

If nothing is found that matches, the result will be #-1.
If more than one thing could be matched at any point along the list,
it returns #-2. 
If the match is HOME, it returns #-3.
~
MOVETO

moveto ( d1 d2 -- )
-------------------
Level: M1 -> W2 Apprentice to Wizard
d1 = dbref of PLAYER, THING, EXIT, PROGRAM, or ROOM
d2 = dbref of PLAYER, THING, ROOM

Moves object d1 to object d2.
Levels under M3 cannot do the following:
  Move -any- object not set = J
  Move exits at all.
  Move players or things to things that are not marked = V
  Move players to or from rooms not marked = J
  Move players into vehicles that are not in the same room
  Move vehicles to rooms set = V
  Move puppets to rooms set = Z
If the object being moved is a room or an exit, then only
the owner and W2's or higher can move it.
ROOMS can only be moved to ROOMS.
PLAYERS can be moved to ROOMS or THINGS.
THINGS, PROGRAMS, and EXITS can be moved to ROOMS, PLAYERS, and THINGS.
Note that when exits are moved, their permission level is reset to 0.
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.
~
ANSI_NAME

ansi_name ( d -- s )
--------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string containing the colorized name.

Given any valid dbref number, it will return a colorized version of
that object's name as a string. Uses standard (FB6-style) ANSI.

The colors are:
  PLAYER  = GREEN
  THING   = PURPLE
  EXIT    = BLUE
  PROGRAM = RED
  ROOM    = CYAN

See: NAME, STANDARD ANSI
~
NAME

name ( d -- s )
---------------
Level: M1 Apprentice
d = Any valid dbref.
s = string containing the name.

Given any valid dbref number, it will return the name of that object
as a string. If the dbref is of a recycled object, the name returned
will be '<garbage>'.

See: SETNAME
~
NEXT

next ( d -- d' )
----------------
Level: M1 Apprentice
d = any exit or thing

Given a dbref of a thing or exit, it returns the dbref of the next 
exit or thing attached to or held by that player, room, or thing.
If there are no exits or contents to report, it returns #-1. M1's
cannot list anything set DARK using this prim.

See: CONTENTS, EXITS
~
NOT

not ( x -- i )
--------------
Level: M1 Apprentice
x = Anything on the stack.
i = integer result of not operation.

Performs the boolean `not' operation on x. It returns 1 if x was false,
otherwise puts 0 onto the stack.
~
NOTIFY

notify ( d s -- )
-----------------
Level: M1 Apprentice
d = Any valid dbref.
s = string to notify to that dbref.

Tells object d the contents of string s. If s is null it will print 
nothing.  This primitive will trigger listen properties on the object 
the message is sent to, unless the program that would be run is the 
same as one one currently running.
~
NOTIFY_EXCEPT|ANSI_NOTIFY_EXCEPT|NOTIFY_HTML_EXCEPT|HTML_NOCR_EXCEPT

notify_except ( d1 d2 s -- )
----------------------------
Level: M1 Apprentice
d1 = Any valid dbref.
d2 = Any dbref.
s  = Message to be displayed.

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' at compile time. 

ANSI_NOTIFY_EXCEPT, NOTIFY_HTML_EXCEPT, and HTML_NOCR_EXCEPT work
the same, except with the different properties that they are intended
for.

See: NOTIFY_EXCLUDE, NOTIFY_HTML_EXCLUDE, DIRECTIVES
~
NOTIFY_HTML|NOTIFY_HTML_EXCLUDE|NOTIFY_HTML_NOCR|NOTIFY_HTML_EXCLUDE_NOCR

notify_html         ( d s -- )
notify_html_exclude ( d dn ... d1 n s -- )
------------------------------------------
Level: M1 Apprentice
For details, see NOTIFY, and NOTIFY_EXCLUDE

These work like their normal counterparts, only they are only sent to
Pueblo users and any HTML code in the string will be executed by the
Pueblo client.

notify_html_nocr         ( d s -- )
notify_html_nocr_exclude ( d s -- )
-----------------------------------
Level: M1 Apprentice
For details, see NOTIFY, and NOTIFY_EXCLUDE
These work the same as above, but they do not append a normal carriage
return to the end.  These are used for basically 'transparent' Pueblo
commands.
~
NUMBER?

number? ( s -- i )
------------------
Level: M1 Apprentice
s = A string to check for holding a number.
i = integer representing true or false result.

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

ok? ( x -- i )
--------------
Level: M1 Apprentice
x = Anything on the stack.
i = integer result indicating true or false result.

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.

See also EXIT?, PLAYER?, PROGRAM?, THING?.
~
OR

or ( x y -- i )
---------------
Level: M1 Apprentice
x and y can be anything on the stack.
i = If x or y is true, returns 1, otherwise 0.

Performs the boolean `or' operation on x and y. Returns i as 1 if
either x or y is TRUE, returns i as 0 otherwise.
~
OVER

over ( x y -- x y x )
---------------------
Level: M1 Apprentice
x and y = Any two objects on the top of the stack.

Duplicates the second-to-top thing on the stack.  This is the same as 2 pick.
If there are fewer than two objects on the stack, the program will abort.
~
OWNER

owner ( d -- d' )
-----------------
Level: M1 Apprentice
d  = Any valid dbref.
d' = dbref representing the owner of d.

d is any database object. Returns d', the player object that owns d.
If d is a player, d' will be the same as d.
~
PENNIES

pennies ( d -- i )
------------------
Level: M1 Apprentice
d = dbref of a player or thing.
i = integer representing number of pennies.

Returns the number of pennies that the given player has, or the value
of the given object.
~
PICK

pick ( xi ... x1 i -- xi ... x1 xi )
------------------------------------
x = Any data object on the stack.
i = integer representing how deep in the stack to pick from.

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.
~
PLAYER?

player? ( d -- i )
------------------
Level: M1 Apprentice
d = Any dbref.
i = integer representing true or false.

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.

See also PROGRAM?, ROOM?, THING?, EXIT?, OK?.
~
POP

pop ( x -- )
------------
Level: M1 Apprentice
x = Anything that is on the top of the stack.

Pops the top of the stack into oblivion.

See also POPN.
~
POPN

popn ( xi ... x1 i -- )
-----------------------
Level: M1 Apprentice
x = Any objects on the stack.
i = integer representing the number of objects to pop from the stack.

Pops the top i items of the stack into oblivion.
This is useful for popping a {s} string list off of the stack.

See also POP.
~
PROG

prog ( -- d)
------------
Level: M1 Apprentice
d = dbref of currently running program.

Returns the dbref of the currently running program.
~
PROGRAM?

program? ( d -- i )
-------------------
Level: M1 Apprentice
d = Any dbref.
i = integer representing true or false result.

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

See also PLAYER?, ROOM?, THING?, EXIT?, OK?.
~
PRONOUN_SUB

pronoun_sub ( d s1 -- s2 )
--------------------------
Level: M1 Apprentice
d  = Any valid dbref object.
s1 = Original string with substitution tokens.
s2 = string returned after the substitutions have been done.

Takes database object d and substitutes string s according to o-message
rules.  'd' does not have to be a player for the substitutions to work.

Substitutions:
 %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.
~
RANDOM

random ( -- i )
---------------
Level: M1 Apprentice
i = Any random integer.

Returns a random integer from 0 to the MAXINT of the system running the MUCK.
In general this number is (2^31)-1 or 2,147,483,647 (2.1 billion).
~
READ

read ( -- s )
-------------
Level: M1 Apprentice
s = String representing the input from the user.

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. A program
running in background mode cannot use the read prim. 

As of Proto 1.7, READ can work with descriptors that are not yet connected
to players. This is useful for programs called via @logincommand/ props, as
well as programs run via the MUF port. In both of these cases, the READ prim
can be used in the same way it is used in in-MUCK programs. The running the
program will be blocked, and the next input from the descriptor will be pushed
onto the stack. 
See: BACKGROUND, TREAD, READ_WANTS_BLANKS
~
REMOVE_PROP

remove_prop ( d s -- )
----------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the name of the prop to remove.

Removes property s from object d.  The following restrictions apply:
Up to W1 May not remove _, ., ~, or @ props on objects they do not own
  nor ~ and @ props on objects they do own.
W2 can remove ~ props from anything, but not @ props.
W3 and above can remove @ props from anything.
~
RINSTR

rinstr ( s1 s2 -- i )
---------------------
Level: M1 Apprentice
s1 = string to scan for the last location of s2.
s2 = string to find in s1.
i  = integer indicating true or false result.

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

See also INSTR.
~
RMATCH

rmatch ( d s -- d' )
--------------------
Level: M1 Apprentice
d  = Any valid dbref.
s  = string to match against.
d' = Result.

Given string s, and object d, it matches s against anything associated
with object d. Associated objects are exits attached to the object, or
anything contained within the object. 
For example, if d is a player, rmatch will check that player's inventory,
and any actions attached to that player.
If nothing is found, d' = #-1.  If ambiguous, d' = #-2. If HOME, d' = #-3.
See: MATCH
~
ROOM?

room? ( d -- i )
----------------
Level: M1 Apprentice
d = Any dbref.
i = integer representing true or false result.

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.

See also PLAYER?, PROGRAM?, THING?, EXIT?, and OK?.
~
ROT

rot ( x y z -- y z x )
----------------------
Level: M1 Apprentice
x, y, and z = Any 3 data objects on the stack.

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

rotate ( xi ... x1 i -- x(i-1) ... x1 xi )
------------------------------------------
Level: M1 Apprentice
xi ... x1 = A number of objects on the stack of any type.
i = integer representing how many objects need to be shifted.

Rotates the top i things on the stack.   '"a" "b" "c" "d" 4 rotate' would
leave "b" "c" "d" "a" on the stack.  Using a negative rotational value rotates
backwards.  ie: '"a" "b" "c" "d" -4 rotate'  would leave "d" "a" "b" "c" on
the stack.
~
SORT

sort ( si ... s1 i im -- si ... s1 i ) (Modes 0-3)
sort ( di ... d1 i im -- di ... s1 i ) (Modes 4-5)
--------------------------------------------------
Level: M1 Apprentice
si ... s1 = Several strings on the stack, with nothing between them.
di ... d1 = Several dbrefs on the stack, with nothing between them.
i  = integer representing the number of objects to be sorted.
im = integer representing the mode of sort desired.

Sorts a string list on the top of the stack using a given sort criteria
specified by value im. Possible sort modes are:

0 - string list, case sensitive, A-Z, where A is on the top of the stack
1 - string list, case sensitive, Z-A, where Z is on the top of the stack
2 - string list, case insensitive, A-Z, A on top
3 - string list, case insensitive, Z-A, Z on top

4 - dbref list, by object name, A-Z, A on top (as dbref)
5 - dbref list, by object name, A-Z, Z on top (as dbref)

See also ROTATE, POPN.
~
SET

set ( d s -- )
--------------
Level: M1 to W3 Apprentice to Arch Wizard
d = Any valid dbref.
s = A string representing a flag.

Sets flag s to object d. To remove a flag, place a ! before the flag's
name. Only W2's and up can set flags on objects they do not own. 
DARK = "debug" or "dark"
ABODE = "abode" or "autostart" or "abate"
CHOWN_OK = "chown_ok" or "color_on" or "ansi"
HAVEN = "haven"
JUMP_OK = "jump_ok" 
LINK_OK = "link_ok" or "light"
BUILDER = "builder"
STICKY = "sticky" or "silent"
ZOMBIE = "zombie" or "puppet" 
VEHICLE = "vehicle" or "viewable"
HIDDEN = "hidden" 
GUEST = "guest"
LOGWALL = "logwall"
PUEBLO = "pueblo"
HTML = "html"
PARENT = "parent"
PROTECT = "protect"
MEEPER = "m"
See SET2 for special notes about some of the flags.
See also SETNAME, SETDESC, and FLAG?.
~
SET2

Only W3 or higher can set the DARK flag on players.
There may be more restrictions on the DARK flag depending on @tune
settings.
Only W4 can set the PROTECT flag.
Only W3 or higher can set the BUILDER flag using set.
Only W3 or higher can set the ZOMBIE flag on players.
Only W3 or higher can set the HIDDEN flag.
Only W3 or higher can set the LOGWALL flag.
Only W1 or higher can set the GUEST flag.
Only W1 or higher can set the PUEBLO flag.
Only W1 or higher can set the HTML flag.
If a player is set = Z, they cannot use set to set Z flags.
Set cannot be used to set a program = AUTOSTART
Set cannot be used to set X flags, or M or W bits.
~
SETDESC|SETSUCC|SETFAIL|SETDROP|SETOSUCC|SETOFAIL|SETODROP|SETANSIDESC|SETIANSIDESC

setdesc setsucc setfail setdrop setosucc setofail setodrop
setidesc sethtmldesc setihtmldesc (d s -- )
-------------------------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string to set on the appropriate prop.

Takes object d, and sets the string field specified to s. A program
may only set string fields of objects that are owned by the effective
user of the program, or any object if the program is Wizard.  These are
all actually $defines to addprop with the apporpriate property name.
They are effectively defined as:
$define setdesc      "_/de"  swap 0 addprop $enddef
$define setidesc     "_/ide" swap 0 addprop $enddef
$define setansidesc  "_/
$define sethtmldesc  "_/htmlde" swap 0 addprop $enddef
$define setihtmldesc "_/ihtmlde" swap 0 addprop $enddef
$define setsucc      "_/sc"  swap 0 addprop $enddef
$define setfail      "_/fl"  swap 0 addprop $enddef
$define setdrop      "_/dr"  swap 0 addprop $enddef
$define setosucc     "_/osc" swap 0 addprop $enddef
$define setofail     "_/ofl" swap 0 addprop $enddef
$define setodrop     "_/odr" swap 0 addprop $enddef

See: SETNAME, SET, ADDPROP, GETPROPSTR, REMOVE_PROP, DESC, SUCC.
~
SETNAME

setname  ( d s -- )
-------------------
Level: M1 and W2 Apprentice and Wizard
d = Any valid dbref number.
s = string containing the object's new name.


Takes object d, and sets the name to s. For all levels below W2, the
program can only be used for changing the names of objects owned by 
the program owner. Wizards can use it to set the name of any object on
the MUCK. To use setname on players (Wizard only), the string must end
with the word 'yes'. For example: s = "NewName yes"

See also SET, NAME, and SETDESC.
~
STRCAT

strcat ( s1 s2 -- s3 )
----------------------
Level: M1 Apprentice
s1 and s2 = Two strings to combine.
s3 = Result of s1 and s2 being combined to one string.

Concatenates two strings s1 and s2 and pushes the result s = s1s2
onto the stack. If adding s2 to s1 will exceed the buffer limit, the
program will abort.
~
STRCMP

strcmp ( s1 s2 -- i )
---------------------
Level: M1 Apprentice
s1 and s2 = Two strings to compare.
i = integer representing the result. 0 means they are the same.

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

See: STRNCMP, STRINGCMP
~
STRCUT

strcut ( s1 i -- s2 s3 )
------------------------
Level: M1 Apprentice
s1 = string to cut.
i  = integer representing the point at which to cut s1.
s2 and s3 = The results of s1 after the strcut.

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.
~
STRINGCMP

stringcmp ( s1 s2 -- i )
------------------------
Level: M1 Apprentice
s1 and s2 = Two strings to compare.
i = integer representing the result. 

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

See: STRCMP, STRNCMP
~
STRLEN

strlen ( s -- i )
-----------------
Level: M1 Apprentice
s = Any string.
i = integer representing the length of that string.

Returns the length of string s as an integer.
~
STRNCMP

strncmp ( s1 s2 i1 -- i2 )
--------------------------
Level: M1 Apprentice
s1 and s2 = Two strings to compare.
i1 = integer representing how many initial characters to compare.
i2 = integer representing the result. 0 indicates they're the same.

Compares the first i characters in strings s1 and s2.
Return value is like strcmp, in that 0 indicates they are exactly
the same, and any other integer indicates they are different.
This prim IS case sensitive.

See also STRINGCMP, STRCMP.
~
SUBST

subst ( s1 s2 s3 -- s )
-----------------------
Level: M1 Apprentice
s1 = string to do the substitutions in.
s2 = string to change to.
s3 = string to replace.

s1 is the string to operate on, s2 is the string to change all occurences
of s3 into, and s is resultant string.  For example:
    "HEY_YOU_THIS_IS" " " "_" subst
results in
    "HEY YOU THIS IS"
s2 and s3 may be of any length.
~
SUCC|FAIL|DROP|OSUCC|OFAIL|ODROP

succ fail drop osucc ofail odrop ( d -- s )
-------------------------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = The contents of the appropriate prop.

Takes object d and returns the contents of the appropriate message
prop. It is an inserver definition of: 
"<prop>" getpropstr
See: SETSUCC, etc.
~
SWAP

swap ( x y -- y x )
-------------------
Level: M1 Apprentice
x and y = Any two objects on the top of the stack.

Takes objects x and y on the stack and reverses their order.
If there are fewer than two objects on the stack, the program
will abort.
~
THING?

thing? ( d -- i )
-----------------
Level: M1 Apprentice
d = Any dbref.
i = integer representing true or false.

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

See also PLAYER?, PROGRAM?, ROOM?, EXIT?, OK?.
~
TIME

time ( -- s m h )
-----------------
Level: M1 Apprentice
s m h = integers representing seconds, minutes, hours.

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

var <name>
----------
Level: M1 Apprentice

When used outside of a MUF word, the var declares a variable as being
useable in all words sequentially defined after teh var declaration. In
otherwords, placing a variable declaration at the top of the program code
essentially makes it a true global for the course of the program.

When used within a MUF word, the variable is declared as a variable that's
local to that MUF proceedure only. This, in affect, creates scoped variables
that last for only as long as the proceedure does, and are not usable by
any other proceedures during the course of the program. For example:
: part-two 
  var test 2 test ! test @ ( 'test' is declared again, given a value of 2 )
; ( part-two exits, this 'test' variable is destroyed )
: main 
  var test 3 test ! ( 'test' is declared, given a value of 3 )
  part-two ( part-two is called, but does not inherit the 'test' variable)
  test @ ( 'test' in main still has the value of 3 )
;


See also @, VARIABLE, and LOCALVAR.
~
VARIABLE

variable ( i -- v )
-------------------
Level: M1 Apprentice
i = Any valid integer.
v = variable reference that can then be used like a normal variable.

Converts integer i to variable reference v. Of the pre-defined variables,
`me' corresponds to integer 0, `loc' to 1, and `trigger' to 2. Thus:
     me @
and
     0 variable @
will do the same thing (returning the user's dbref). User-defined variables
are numbered sequentially starting at 3 by the compiler. Note that these
variable numbers can be used even if variables have not been formally
declared, making implementation of such things as arrays conveniently easy.
See @, !, and VAR.
~
VARIABLE OPERATORS|@|!|AT|BANG

@ ( v -- x )
------------
Level: M1 Apprentice
v = Declared variable.
x = Any data type that was stored in the variable. Variables are 
declared as containing 0, so if a variable's value is not changed
before @ is used, it will return 0.

Retrieves variable v's value x.

! ( x v -- )
------------
Level: M1 Apprentice
x = Any data type on the stack.
v = Declared variable.

Sets variable v's value to x, removing x from the stack to be retrieved
later.

See also VARIABLE, VAR, LVAR, LOCALVAR, VARIABLE?, and MISCELLANEOUS.
~
VARIABLE?

variable? ( x -- i )
--------------------
Level: M1 Apprentice
x = Any data type on the stack.
i = integer indicating true or false result.

If object x is a variable, returns 1, otherwise 0.
~
AWAKE?

awake? ( d -- i )
-----------------
Level: M1 Apprentice
d = dbref# of puppet or player
i = Number of connections

Given a player or puppet's dbref#, it will return the number of 
connections that player (or owner in the case of a puppet) has to the
MUCK. 0 indicates they are not connected.
~
ONLINE

online ( -- d ... i )  
---------------------
Level: M3 Master
d = dbref# of players connected
i = integer represending the number of current connections

Returns a dbref for every connection to the game, and lastly the number
of connections. Note that a single character may have more than one 
connection open, in which case, their dbref# will be included more than
once in the return.
~
SYSTIME

systime ( -- i )
----------------
Level: M1
i = integer representing seconds.


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

dbref? ( x -- i )
-----------------
Level: M1 Apprentice
x = Any object on the stack.
i = integer representing true or false result.

Returns true if x is a dbref.
~
DEPTH

depth ( -- i )
--------------
Level: M1 Apprentice
i = integer representing the number of items on the stack.

Returns the number of items on the stack. A return of 0 indicates
an empty stack.
~
TIMESTAMPS

timestamps ( d -- i i2 i3 i4 )
------------------------------
Level: M2 Journeyman
d  = Any valid dbref.
i  = Time created.
i2 = Last time modified.
i3 = Last time used.
i4 = Number of uses.

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. For players, the number of uses represents the number of times
they have connected to the MUCK.
~
REFSTAMPS

refstamps ( d -- d1 d2 d3 )
------------------------------
Level: M2 Journeyman
d  = Any valid dbref.
d1 = Creator of object.
d2 = Last object that edited this object.
d3 = Last object that used or touched the object.

Returns the following for a program, the object creator (d1), the last modifying
object (d2), and the last user of an object (d3).
~
TOUCH

touch ( d -- )
--------------
Level: M3 Master
d  = A valid dbref.

Updates the 'last used' timestamp and refstamp on the object (d).
~
USE

use ( d -- )
--------------
Level: W2 wizard
d  = A valid dbref.

Updates the 'last used' timestamp and refstamp on the object (d), and
also increments the usecount on the object.
~

INT?

int? ( x -- i )
---------------
Level: M1 Apprentice
x = Any data type on the stack.
i = integer representing true or false.

Returns true if x is a int.
~
SETLINK

setlink ( d1 d2 -- )
--------------------
Level: M1 and W2 Apprentice and Wizard
d1 = dbref that represents object to link.
d2 = dbref that represents the object to be linked to.

Takes object d1 and links it to location d2. 
If an exit is already linked, it will have to be unlinked by setting its
link as #-1, before it can be linked again.
For any levels lower than W2, the following rules apply: 
If trying to link an exit, the destination can be a player, thing, room,
or program, but must be set = L, or owned by the player who owns the
program.
If trying to link a player, destination must be a room, and either owned
by the program owner, or set = L or = A.
If trying to link a room, destination must be a room, and either owned
by the program owner, or set = L, = A, or = PARENT.
If trying to link a thing, destination must be a room or a player. If it
is a room, the room must be set = L. If it is a player, it must be the same
player as who owns the program.
~
STRING?

string? ( x -- i )
------------------
Level: M1 Apprentice
x = Any object on the stack.
i = integer representing true or false result.

Returns true if x is a string.
~
TIMESPLIT

timesplit ( i -- is im ih id im iy iw iyd )
-------------------------------------------
Level: M1 Apprentice
i = integer representing systime.
is im ih id im iy iw iyd = integers representing parts of the date.

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

newroom (d1 s -- d2)
--------------------
Level: M2 to W2 Journeyman to Wizard
d1 = dbref representing a valid room.
s  = string containing the name of the new room.
d2 = dbref representing the new room after it is made.

Given a parent room d1, and name s, it creates a new room and returns its
dbref to the stack. The owner of the new room is always the person
running the program. 
For M2 and M3 users, the program can only generate one new ROOM per run.
For W1, the program can generate more than one ROOM per run.
For levels lower than W2, the player must own the parent room the new 
room is being created in.

See also: NEWOBJECT, NEWEXIT
~
NEWOBJECT

newobject (d1 s -- d2)
----------------------
Level: M2 to W2 Journeyman to Wizard
d1 = dbref representing a player or thing.
s  = string containing the name of the new object.
d2 = dbref of new object when it is made.

Given location d1, and name s, it creates a new object and returns its
dbref to the stack. The owner of the new object is always the person
running the program. 
For M2 and M3 users, the program can only generate one new THING per run.
For W1, the program can generate more than one THING per run.
For levels lower than W2, the player must own the location the new object
is being created in.

See also: NEWEXIT, NEWROOM
~
NEWEXIT

newexit (d1 s -- d2)
--------------------
Level: W1 Mage
d1 = dbref representing any valid player, room, or thing.
s  = string containing the name of the new exit.
d2 = dbref representing the dbref of the new exit.

Given a location in d1, and a name in string s, it creates a new action
on that location and returns the dbref to the stack. 
~
STATS

stats ( d -- total rooms exits things programs players garbage )
----------------------------------------------------------------
Level: Level: M3
d  = Any valid player dbref, or #-1 for system wide info.

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

PUBLIC <functionname>
---------------------
Level: M1 Apprentice

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
~
LVAR

LVAR <varname>
--------------
Level: M1 Apprentice

This declares a variable as a local variable, that is local to a specific
program.  If another program calls this program, the values of the local
variables will not be changed in the calling program, even if the called
program changes them.
~
LOCALVAR

localvar (i -- x)
-----------------
Level: M1 Apprentice
i = integer that currently represents a variable.
x = The contents of that variable.

Takes an integer and returns the respective local variable.  Similar to
the 'variable' primitive.
~
SETOWN

setown (d1 d2 -- )
----------------
Level: M1 to W2 Apprentice to Wizard
d1 = Any valid dbref except for player dbrefs.
d2 = Any valid player dbref.

setown makes player d2 the owner of object d1. Naturally, players may not 
be owned by other players. For all levels below W2, it works with the
following restrictions:
No one can setown an object to another player.
No one can setown an object that has a higher permissions level than
themself.
No one can use setown on an object that is not set = C, unless they pass
the @chlock on the object.
Anyone below W1 must be holding a THING to setown THINGS, and be in the
ROOM to setown ROOMS.
~
RECYCLE

recycle (d -- )
---------------
Level: M3 and W2 Master and Wizard
d = A valid dbref.

Recycles the given object d.  Will not recycle players, the global
environment, the player starting room, or any currently running program.
M3 users can recycle any objects they own. W2 and above can recycle any
objects.
~
CONCOUNT

concount ( -- i)
----------------
Level: M1 Apprentice
i = integer representing the number of open connections.

Returns how many connections to the server there are.
~
CONDBREF

condbref (i -- d)
-----------------
Level: M3 Master
i = integer representing connection number.
d = dbref# of player using that connection number.

Given a connection number, i, it returns the dbref# of the player
connected to that number.
~
CONTIME

contime (i1 -- i2)
------------------
Level: M2 Journeyman
i1 = integer representing a connection number.
i2 = number of seconds that connection has been open.

Given a connection number it returns the number of seconds that
connection has been open to the MUCK.
~
CONIDLE

conidle (i1 -- i2)
------------------
Level: M2 Journeyman
i1 = integer representing a connection number.
i2 = integer representing numbers of seconds.

Given a connection number, it returns how many seconds that 
connetion has been idle. Note that a player may have more than
one connection open to the MUCK and may be idle with one 
connection and not with another.
~
CONDESCR

condescr ( i1 -- i2 )
---------------------
Level: M3 Master
i1 = integer representing a connection number.
i2 = the descriptor number for that particular connection.

Takes a connection number and returns the descriptor number associated
with it.

See DESCRIPTORS, DESCRCON.
~
CONHOST

conhost (i -- s)
----------------
Level: W1 Mage
i = integer representing a connection number.
s = string representing that connection's IP host.

Given a connection number, it returns a string containing the 
IP address of that connection.
~
CONBOOT

conboot (i -- )
---------------
Level: W2 Wizard
i = integer representing a connection number.

Given an open connection number, this will boot that connection
from the MUCK. Note that if a player is connected through more
than one connection, they will still be connected through their
other connections. 
~
CONNOTIFY

connotify (i s -- )
-------------------
Level: M3 Master
i = integer representing a connection number.
s = Any string.

Will display the contents of string s to the player connected to
connection number i.
~
CONUSER

conuser (i -- s)
----------------
Level: W3 Arch Wizard
i = integer representing a connection number.
s = string representing user name.

Given a connection number, it returns the user name for that 
connection's IP address.
~
CONIPNUM

conipnum (i -- s)
-----------------
Level: W1 Mage
i = integer representing a connection number.
s = string representing the numerical IP address.

Given a connection number, it returns the host of the connection as
a numerical TCP/IP address.
~
CONPORT

conport (i -- s)
----------------
Level: Arch Wizard
i = integer representing connection number.
s = string representing the port number for that connection.

Given a connection number, returns the port number for that 
user's IP address.
~
DESCRCON

descrcon (i1 -- i2)
-------------------
Level: M3 Master
i1 = integer representing a descriptor number.
i2 = integer representing a connection number.

Takes a descriptor and returns the associated connection number,
or 0 if no match was found.  

See DESCRIPTORS, CONDESCR.
~
NEXTDESCR

nextdescr (i1 -- i2)
--------------------
Level: W1 Mage
i1 = integer representing a descriptor number.
i2 = integer representing a descriptor number.

Given a descriptor number, it returns the next connected descriptor
number on the WHO list. To get the first descriptor, use '1 condescr'.
Then nextdescr can be used to step through the rest of the connections.
Returns 0 when given an invalid descriptor or reaches the end of the
WHO list.

See also: DESCRIPTORS, CONDESCR, DESCRCON
~
DESCRIPTORS

descriptors (d -- ix...i1 i) 
----------------------------
Level: M3 Master
d = dbref# of a player.
ix...i1 = A list of integers, each representing a descriptor number.
i = integer representing the total.

Given a player's dbref#, it returns all of the descriptors associated
with that player, with that player's total on the top of the stack.
Given #-1, it puts all of the descriptors currently connected onto the
stack, with the total for the MUCK on the top of the stack.

Descriptors are numbers assigned to a player when they connect and do
not change for the life of that connection. A connection number is the
relative possition of a connection in the WHO list.

As of Proto1.5 and newer, this prim will also include descriptors that
are not yet connected to a character when given #-1. This would be 
connections that are still at the login screen.

See DESCRCON, CONDESCR.
~
PID

pid ( -- i)
-----------
Level: M1 Apprentice
i = integer representing the PID of currently running process.

Returns the process ID of the program that is currently running.
~
ISPID?

ispid? (i1 -- i2)
-----------------
Level: M1 Apprentice
i1 = integer representing PID to check.
i2 = integer representing true or false.

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.
~
NEXTPROP

nextprop (d s1 -- s2)
-------------------
Level: M2 Journeyman
d  = Any valid dbref.
s1 = string representing a prop on d.
s2 = string representing the next prop on d.

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.
~
PROPDIR?

propdir? (d s -- i)
-------------------
Level: M2 Journeyman
d = Any valid dbref.
s = string representing a prop to check.
i = integer represeting true or false result.

Takes a dbref and a property name, and returns a boolean integer that
tells if that property is a propdir that contains other props.
~
ENVPROP

envprop ( d1 s1 -- d2 x )
-------------------------
Level: M1 Apprentice
d1 = Any valid dbref.
s1 = string representing the name of the prop to search for.
d2 = dbref where prop was found, or #-1 if not found.
x  = The type will vary depending on the contents of the prop once found.

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

See: ENVPROPSTR
~
ENVPROPSTR

envpropstr (d1 s1 -- d2 s2 )
----------------------------
Level: M1 Apprentice
d1 = Any valid dbref.
s1 = string representing the prop to search for.
d2 = dbref where prop was found, or #-1 if not found.
s2 = string representing the contents of the prop if found.

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.

See: ENVPROP
~
NOTIFY_EXCLUDE|ANSI_NOTIFY_EXCLUDE

notify_exclude notify_ansi_exclude (d dn ... d1 n s -- )
------------------------------------
Level: M1 Apprentice
d  = dbref of location to display the message.
dn ... d1 = A list of dbrefs to exclude from the notification.
n  = The number of dbrefs being excluded from notification.
s  = string to notify to the room.

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_ansi_exclude works the same, except handles the ANSI parsing.
~
TIMEFMT

timefmt (s1 i -- s2)
--------------------
Level: M1
s1 = string indicating how the time should be formatted.
i  = integer representing the systime in seconds.
s2 = string representing the formatted time.

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:

  %% -- "%"                               %I -- hour, "01" - "12"
  %a -- abbreviated weekday name.         %j -- year day, "001" - "366"
  %A -- full weekday name.                %k -- hour, " 0" - "23"
  %b -- abbreviated month name.           %l -- hour, " 1" - "12"
  %B -- full month name.                  %M -- minute, "00" - "59"
  %C -- "%A %B %e, %Y"                    %m -- month, "01" - "12"
  %c -- "%x %X"                           %p -- "AM" or "PM"
  %D -- "%m/%d/%y"                        %R -- "%H:%M"
  %d -- month day, "01" - "31"            %r -- "%I:%M:%S %p"
  %e -- month day, " 1" - "31"            %S -- seconds, "00" - "59"
  %h -- "%b"                              %T -- "%H:%M:%S"
  %H -- hour, "00" - "23"

Type 'man timefmt2' for more formats.
~
TIMEFMT2

  %U -- week number of the year. "00" - "52"
  %w -- week day number, "0" - "6"
  %W -- week# of year, starting on a monday, "00" - "52"
  %X -- "%H:%M:%S"
  %x -- "%m/%d/%y"
  %y -- year, "00" - "99"
  %Y -- year, "1900" - "2155"
  %Z -- Time zone.  "GMT", "EDT", "PST", etc.
~
SLEEP

sleep (i -- )
-------------
Level: M1 Apprentice
i = integer representing the number of seconds the program is to pause.

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.

See: MULTITASKING, BACKGROUND, READ
~
QUEUE

queue (i1 d s -- i2)
--------------------
Level: M3 Master
i1 = integer representing a time in seconds.
d  = dbref of a program.
s  = string representing the initial arguement to be given to the program.
i2 = int representing either the pid of new program, or 0.

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.
~
ENQUEUE

enqueue (d1 i1/s1 d2 s -- i2)
--------------------------
Level: W3 Archwizard
d1 = dbref of a player or thing.
i1 = integer representing a time in seconds. OR
s1 = string indicating an argument for command @
d2 = dbref of a program.
s  = string representing the initial arguement to be given to the program.
i2 = int representing either the pid of new program, or 0.

Takes a player or thing's dbref to be the target of the queued program,
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.

If a string is given instead of a delay integer at that particular argument,
the delay is assumed to be 0, and instead, the string you give here will
replace "Queued event." as the command @ argument passed to the MUF program
that gets queued.

See also: QUEUE.
~
FORK

fork ( -- i)
------------
Level: W1 Mage
i = integer representing the PID of the new process, or failed result.

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.
~
KILL

kill (i1 -- i2)
-------------
Level: M1 and W1 Apprentice and Mage
i1 = integer representing a program's PID.
i2 = integer representing success or failure in killing it.

Attempts to kill the process referred to by the given process ID.
Returns 1 if the process existed, and 0 if it didn't. Mages and
up can use it to kill processes they don't own. Lower than W1 can
use it on their own processes.
~
TOUPPER

toupper (s1 -- s2) 
------------------
Level: M1 Apprentice
s1 = Any string.
s2 = s1 with all the characters changed to uppercase.

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

tolower (s1 -- s2)
------------------
Level: M1 Apprentice
s1 = Any string.
s2 = s1 with all the characters changed to lowercase.

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

striplead (s1 -- s2)
--------------------
Level: M1 Apprentice
s1 = Original string.
s2 = Original string returned without any spaces before it.

Strips leading spaces from the given string.
~
STRIPTAIL

striptail (s1 -- s2)
--------------------
Level: M1 Apprentice
s1 = Original string.
s2 = Original string returned without any spaces after it.

Strips trailing spaces from the given string.
~
STRIP

strip (s1 -- s2)
----------------
Level: M1 Apprentice
s1 = Original string.
s2 = string with no space on the front or end.

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

smatch ( s1 s2 -- i )
---------------------
Level: M1 Apprentice
s1 = string to check for a pattern in.
s2 = string representing the pattern to check for.
i  = integer representing true or false result.

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.

Type 'man smatch2' for more info.
~
SMATCH2

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

Type 'man smatch3' for examples.
~
SMATCH3

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 '?'.
~
SETLOCKSTR

setlockstr (d s -- i)
---------------------
Level: M1 and W2 Apprentice and Wizard
d = A valid dbref.
s = string containing the lockstring to set.
i = integer indicating successful or unsuccessful lock.

Given object d, tries to set the lock contained in string s. If it is able
to set the lock, it returns 1, if there was something wrong with the 
lock string, it returns 0. W2 and above can set locks on any object. To
unlock an object, use a null string for the lock string.
~
GETLOCKSTR

getlockstr ( d -- s )
---------------------
Level: M1 Apprentice
d = Any valid dbref.
s = Contents of lockstring on object d.

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.
~
LOCKED?

locked? (d1 d2 -- i)
--------------------
Level: M1 Apprentice
d1 = dbref representing player or thing ( for checking puppets ).
d2 = dbref representing any valid object the lock is to be checked on.
i  = integer result indicating pass or fail. ( 0 indicates pass, 1 fail )

Given a player or things dbref, and the object to check the lock on, it
checks to see if the player would pass the lock on the object or not.
This includes parsing any MPI needed to check, searching for props on the
player or object, checking for a key object in the player's inventory, or
even running MUFs called from the @lock on the object. If the player can
pass the lock, 0 is returned, otherwise 1.
Note, it is a special challenge to write MUFs that are going to be called
from the @lock on an object, because many look programs will use the
locked? prim to see if an exit should be displayed as being locked or not.

See: TESTLOCK, ISLOCKED?
~
UNPARSEOBJ

unparseobj ( d -- s )
---------------------
Level: M1 Apprentice
d = Any dbref.
s = That dbref after being unparsed.

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(#1PW5)"
If d is #-1, will return "*NOTHING*" to the stack. If d is #-3, will return "*HOME*" to the stack. If d is #-4, will return "*NIL*" to the stack. If d is any other negative dbref, or any dbref higher than DBTOP, will return "*INVALID(#???)*" with the question marks replaced by the dbref in question.

See: ANSI_UNPARSEOJB
~
ANSI_UNPARSEOBJ

ansi_unparseobj ( d -- s )
Level: M1 Apprentice
d = Any dbref.
s = That dbref after being unparsed.

This function is identical to UNPARSEOBJ, with the distinction that the
resultant string is colorized with FB ANSI escape codes according to
the following convention:

The name of the object is colorized as follows:
  Player        green
  Room          cyan
  Thing         purple
  Exit/Action   blue
  Program       red
  #-1           normal
  #-2           purple
  #-3           white
  #-4           cyan
  Invalid       red

The dbref section immediately following the name (for valid objects) will
be colored yellow.

See: UNPARSEOBJ
~
DBTOP

dbtop ( -- d)
-------------
Level: M1 Apprentice
d = dbref representing first value past the top of the dbref.

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

version ( -- s)
---------------
Level: M1 Apprentice
s = string representing the current version of the server code.

Returns the version of this code in a string. 
For example: ProtoMuck 1.00 (Muck2.2fb5.55 -- NeonMuck 2.17)
~
TRIG

trig ( -- d)
------------
Level: M1 Apprentice
d = dbref of the trigger that called the program.

Returns the dbref of the original trigger. This can be a couple of 
different things, below are some examples:
If the program was called by an action, the trigger is the action.
If the program was called by a propqueue, like _listen, or _arrive,
  the trigger is the object that has the propqueue.
~
CALLER

caller ( -- d)
--------------
Level: M1 Apprentice
d = dbref representing the program that called the current one.

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

bitor (n1 n2 -- n3)
-------------------
Level: M1 Apprentice
n1 and n2 = Any float or int.
n3 = If n1 and n2 are both ints, n3 will be an int, otherwise is float.

Does a mathematical bitwise or.
~
BITXOR

bitxor (i i -- i)
-----------------
Level: M1 Apprentice
n1 and n2 = Any float or int.
n3 = If n1 and n2 are both ints, n3 will be an int, otherwise is float.

Does a mathematical bitwise exclusive or.
~
BITAND

bitand (i i -- i)
-----------------
Level: M1 Apprentice
n1 and n2 = Any float or int.
n3 = If n1 and n2 are both ints, n3 will be an int, otherwise is float.

Does a mathematical bitwise and.
~
BITSHIFT

bitshift (i i -- i)
-------------------
Level: M1 Apprentice
n1 and n2 = Any float or int.
n3 = If n1 and n2 are both ints, n3 will be an int, otherwise is float.

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 >>.
~
FORCE

force (d s -- )
---------------
Level: W3 ArchWizard
d = Valid dbref of player or thing.
s = string containing the command to force the player to do.

Forces player d to do action s as if they were @forced. Cannot be used 
on #1. 
~                    
PREEMPT

preempt ( -- )
--------------
Level: M1 Apprentice

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

See also MULTITASKING.
~
FOREGROUND

foreground ( -- )
-----------------
Level: M1 Apprentice

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.
See also MULTITASKING.
~
BACKGROUND

background ( -- )
-----------------
Level: M1 Apprentice

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.

See also MULTITASKING.
~
BEGIN

begin ( -- )
------------
Level: M1 Apprentice

Marks the beginning of begin-until or begin-repeat loops.

See also LOOPS.
~
UNTIL

until (x -- )
-------------
Level: M1 Apprentice
x = Can be anything on the stack.

If the value on top of the stack is false, then it jumps execution
back to the instruction after the matching BEGIN statement.  (BEGIN-UNTIL,
BEGIN-REPEAT, and IF-ELSE-THEN's can all be nested as much as you want.)
If the value is true, it exits the loop, and executes the next instruction,
following the UNTIL.  Marks the end of the current loop.

See also LOOPS.
~
REPEAT

repeat ( -- )
-------------
Level: M1 Apprentice

Jumps execution to the instruction after the BEGIN in a BEGIN-REPEAT loop.
Marks the end of the current loop.

See also LOOPS.
~
WHILE

while (x -- )
-------------
Level: M1 Apprentice
x = Any value on the stack.

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.

See also LOOPS.
~
BREAK

break ( -- )
------------
Level: M1 Apprentice

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

See also LOOPS.
~
CONTINUE

continue ( -- )
---------------
Level: M1 Apprentice

Jumps execution to the beginning of the current loop.

See also LOOPS.
~
INSTRING

instring ( s1 s2 -- i )
-----------------------
Level: M1 Apprentice
s1 = string to check for s2 in.
s2 = string to find within s1.
i  = integer representing first location of s2 in s1.

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

See also RINSTRING, INSTR, and RINSTR.
~
RINSTRING

rinstring ( s1 s2 -- i )
------------------------
Level: M1 Apprentice
s1 = string to check for s2 in.
s2 = string to find within s1.
i  = integer representing last location of s2 in s1.

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

See also INSTRING, INSTR, and RINSTR.
~
MUCKER LEVELS|LEVELS|MUCKER BITS

Mucker Levels:
  There are 8 permissions levels in ProtoMUCK. Level zero is a non-bitted
player, and has no ability to use any code on the MUCK, be it MPI or MUF.
A player set = M is a MEEPER, and may use MPI, but no MUF. Levels M1 to
W4 have access to the MUF editor, and may program MUF code.  

The MUCKER level permissions that a program runs at is its owner's 
level. If it is owned by a player who is M2, the MUF runs at a M2 level.
Programs owned by W2's and higher are considered W-bitted MUFs, and will
run at that permission level, regardless the bit set on the program itself.

The mucker levels available with the man command are: (ie, type man M1)
   M1   M2   M3   W1   W2   W3   W4 (Mucker 1-3 and Wizard 1-4)
Note that the manual entries deal only with how a M/W bit affects MUF, not
other in-server restrictions.
~
M1|MUCKER1|M1 BIT|APPRENTICE
MUCKER1 - Apprentice

  Level one MUCKER's are apprentices, and although the M1 bit is
considered a 'Learner's Bit', there is still a lot that can be done
with them, so their distribution should still be done with some 
consideration. M1 programs always run as if they are SETUID. Any 
notifying prim, like NOTIFY and NOTIFY_EXCEPT will automatically
prepend the M1 user's name to the beginning of the message, though
this can be toggled as an @tune parameter. M1 programs have an 
absolute instruction level that is equal to the @tuned PREEMPT
instruction limit, typically around 20k instructions. 
M1s may use any non-restricted prim (prims that have no minimum level),
though other prims may have additional restrictions.

See: M2, MUCKER LEVELS
~
M2|MUCKER2|M2 BIT|JOURNEYMAN
MUCKER2-Journeyman

  M2 programmers have access to a whole new level of prims, and are 
given a much higher instruction count limit, roughly 4 times the
@tune PREEMPT limit, or around 80k instructions. 
It is recommended that only trusted players be given M2, and only 
if they are able to demonstrate some competence in MUF.

See: M2 PRIMS, M3
~
M3|MUCKER3|M3 BIT|MASTER
MUCKER3-Master

  M3s can use some of the connection related prims, and have fewer
restrictions with other prims as well, such as moveto. Refer to the
documentation on individual prims to see what M3's are able to do
that an M1 or M2 cannot. Their instruction count limit is roughly
twelve times the @tuned PREEMPT limit, typically around 320k.
M3's do have quite a bit of flexability and power with their use of MUF.
It is important to only give M3s to non-staff members who are highly
trusted.

See: M3 PRIMS, W1
~
W1|WIZARD1|W1 BIT|W BIT|MAGE
WIZARD1-MAGE

  W1 is given more power over information retrieving prims, such as 
conhost, and others. They also have way fewer restrictions with the prims,
such as the building prims. They still cannot write to restricted props
on objects they do not own, nor use setown to change ownership of objects
to other players. W1s have no instruction count limit. W1s can also 
delete macro definitions, set their programs to run AUTOSTART, 
and set programs = S & H to run with caller privleges.
It is recommended that W1 bits be given to coders of a MUCK's staff. 
They should not be generally given to non-staff members.

See: W1 PRIMS, W2
~
W2|WIZARD2|WIZ BIT|W2BIT
WIZARD2-Wizard

  W2 is technically the first 'wizbit' level, in terms of MUF. At
this level, almost all prim restrictions are ignored, programs
can change restricted props on objects they do not own except for
@ props, use setown, and many other higher level prims. There are
no limits on instruction counts, not even with programs running
in PREEMPT mode.
It is recommended that W2 be given to admin level coders, as the 
lack of restrictions on W2 programs make them very powerful.

See: W2 PRIMS, W3
~
W3|WIZARD3|W3 BIT|ARCHWIZARD
WIZARD3-ArchWizard

  W3 level programs have almost no restrictions whatsoever. Only
the file prims are unavailable to W3s. No instruction limits on
any program, and the ability to read/write @ props, which are
unavailable to W2s.
It is recommended that W3s be given to only the MUCK's MUF wiz
or wizzes, as the lack of any restrictions requires that players
who have W3 permissions be highly trustworthy.

See: W3 PRIMS, W4
~
W4|WIZARD4|W4 BIT|BOY
WIZARD4-Boy

  W4 is almost the same as W3 in terms of permissions, the only 
noteable difference being the access to the file prims that W3's
do not have.
Under most conditions, there is little need for any coder to have
a W4, unless the file prims are specifically required.

See: W4 PRIMS
~
M2PRIMS|M2 PRIMS|M2_PRIMS|M2-PRIMS
The following prims become available at the level of M2, though
they still may have some uses reserved for higher permission levels:

addpennies          ( d i -- )
movepennies         ( d1 d2 i -- )
timestamps          ( d -- i i2 i3 i4 )
newroom             (d1 s -- d2)
newobject           (d1 s -- d2)
contime             (i1 -- i2)
conidle             (i1 -- i2)
nextprop            (d s1 -- s2)
propdir?            (d s -- i)
descridle           ( i -- i )
descrtime           ( i -- i )
findnext            ( d1 d2 s1 s2 -- d3 )

See: M2, MUCKER LEVELS, invididual prim entries for more details
~
M3PRIMS|M3 PRIMS|M3_PRIMS|M3-PRIMS
The following prims become available at the level of M3, though
they still may have some uses reserved for higher permission levels:

online              ( -- d ... i )  
condbref            (i -- d)
connotify           (i s -- )
stats ( d -- total rooms exits things programs players garbage )
recycle             (d -- )
condescr            ( i -- i )
descrcon            ( i -- i )
descriptors         ( d -- ix...i1 i ) 
queue               ( i d s -- i )
parseprop           ( d s s i -- s )
parsepropex         ( d s1 dict i -- dict s )
nextplayer          ( d -- d' )
descr_array         ( d -- a )
online_array        (   -- a )
descrflush          ( i --   )
descr_html?         ( i -- i )
descr_pueblo?       ( i -- i )
descr_welcome_user  ( i --   )
descr?              ( i -- i )
event_send          ( i s ? -- )
motd_notify         ( d -- )
nextprogram         ( d -- d )
nextexit            ( d -- d )
nextroom            ( d -- d )
nextthing           ( d -- d )
descrdbref          ( i -- d )
watchpid            ( i -- )
getobjinfo          ( d -- dict )
descrbufsize        ( d -- i )

See: M3, MUCKER LEVELS, individual prim entries for more details
~~~~~
M3 PRIMS2|M3PRIMS2

~~~
W1PRIMS|W1 PRIMS|W1_PRIMS|W1-PRIMS
The following prims become available at the level of W1, though
they still may have some uses reserved for higher permission levels:

newexit                (d1 s -- d2)
conhost                (i -- s)
conipnum               (i -- s)
nextdescr              (i1 -- i2)
fork                   ( -- i)
nextowned              ( d -- d' )
notify_descriptor      ( i s -- )
ansi_notify_descriptor ( i s -- )
setpassword            ( d s1 s2 -- )
next_flag              ( d s -- d )
nextowned_flag         ( d s -- d )
nextplayer_flag        ( d s -- d )
nextthing_flag         ( d s -- d )
nextplayer_power       ( d s -- d )
nextentrance           ( d d -- d )
descrhost              ( i -- s )
descripnum             ( i -- s )
firstdescr             ( d -- i )
lastdescr              ( d -- i )
descr_flag?            ( i s -- i )
notify_descriptor_char ( i i -- )
bandwidth              ( -- i i i )
get_macros_array       ( -- dict )

See: W1, MUCKER LEVELS, individual prim entries for more details
~~~~
W2PRIMS|W2_PRIMS|W2 PRIMS|W2-PRIMS

The following prims become available at the level of W2, in 
addition, W2's are no longer restricted by having to own an 
object in order to make changes to it. There is little a W3
can do with these prims that a W2 cannot do.

conboot             (i -- )
parsempi            ( d s1 s2 i -- s3 )
descr_setuser       ( i1 d s -- i2 )
program_getlines    ( d i i -- arr )
program_linecount   ( d -- i )
insert_macro        ( s s -- i )
kill_macro          ( s -- i )

See: W2, MUCKER LEVELS, individual prim entries for more details
~
W3PRIMS|W3_PRIMS|W3 PRIMS|W3-PRIMS

The following prims become available at the level of W3, in
addition W3's are able to manipulate the @ props that W2 and
below are unable to. There is almost nothing a W4 can do with
these prims that a W3 cannot do.

conuser             (i -- s)
conport             (i -- s)
force               (d s -- )
setsysparm          ( s1 s2 -- )
checkpassword       ( d s -- i )
newplayer           ( s1 s2 -- d )
copyplayer          ( d1 s1 s2 -- d2 )
toadplayer          ( d1 d2 -- )
logstatus           ( s -- )
sockopen            ( s1 i -- socket s2 ) 
socksend            ( socket s -- i ) 
sockrecv            ( socket -- s )
sockclose           ( socket -- i )
nbsockopen          ( s1 i -- socket s2 )
get_sockinfo        ( socket -- dict )
sockcheck           ( socket -- i )
socket_setuser      ( socket d s -- i )
set_sockopt         ( socket i -- i )
socktodescr         ( socket -- i )
propqueue           ( d1 s1 d2 s2 -- )
envpropqueue        ( d1 s1 d2 s2 -- )
newpassword         ( d s -- )
descr_logout        ( i -- )
descruser           ( i -- s )
descrport           ( i -- s )
descrconport        ( i -- i )
getpids             ( d -- arr )
getpidinfo          ( i -- dict )
getdescrinfo        ( i -- dict )
descrboot           ( i -- )
descr_set           ( i s -- )
dump                ( -- )
delta               ( -- )
sqlclose            ( sql -- )
sqlping             ( sql -- i )
sqlquery            ( sql s -- dict ... dictn n arr )
sqlconnect          ( s s s s i -- sql i )
copyprops           ( d s d s i -- i )
sockshutdown        ( socket i -- i )

See: W3, MUCKER LEVELS, individual prim entries for details
~
W4PRIMS|W4 PRIMS|W4-PRIMS|W4_PRIMS
Every prim in MUF can be used by W4, with every permissions check
cleared. In addition, they have access to the file prims listed
below:

fwrite              ( s1 s2 i1 -- i2 )
fappend             ( s1 s2 -- i )
fread               ( s1 i -- s2 )
freadn              ( s1 i1 i2 -- s2 )
freadto             ( s1 i1 s2 -- i2 s3 )
fpublish            ( s -- i )
fcr                 ( s -- i )
bread               ( s1 i1 -- i2 )
bwrite              ( i1 s i2 -- i3 )
bappend             ( i1 s -- i2 )
fsinfo              ( -- i1 .. i8 )
curid               ( -- i1 i2 )
fstats              ( s -- i1 ... i6 )
fsize               ( s -- i )
frm                 ( s -- i )
fren                ( s1 s2 -- i )
getdir              ( s -- arr )
mkdir               ( s -- i )
rmdir               ( s -- i )
newprogram          ( s -- d )
compile             ( d i -- i )
uncompile           ( d -- )
lsockopen           ( i i -- lsocket s )
sockaccept          ( lsocket -- socket )
armageddon          ( s -- )
shutdown            ( s -- )
restart             ( s -- )
program_insertlines ( d i1 arr -- i2 )
program_deletelines ( d i1 i2 -- i3 )

See: W4, MUCKER LEVELS, individual prim entries for more details.
~
MLEVEL

mlevel (d -- i)
---------------
Level: M1 Apprentice
d = Any valid dbref.
i = integer representing the priority level of that object.

Given a valid dbref, returns an integer representing that object's 
permission or priority level. The integers represent the following:
0 - No bit set                   5 - W1 Mage  
1 - M  Meeper                    6 - W2 Wizard
2 - M1 Apprentice                7 - W3 Arch Wizard
3 - M2 Journeyman                8 - W4 Boy
4 - M3 Master                    9 - W5 Man (#1)


Also see MUCKER LEVELS.
~
MULTITASKING
------------
There are now 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)
  
See also FOREGROUND, BACKGROUND, PREEMPT, FORK, QUEUE, KILL, and SLEEP.
~
DIRECTIVES|DIR|$DEFINE|DEFINE|$DEF|DEF|$UNDEF|UNDEF|$ECHO|ECHO

$define <defname> <definition> $enddef
  Basically the same as C's #define <defname> <definition>. Used to create
  definitions that can be used later in the program.

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

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

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

Type 'man dir2' for more directives and 'man dir list' for a listing.
~
DIR2|DIRECTIVES2|DIRECTIVE2|$IFDEF|$IFNDEF|IFDEF|IFNDEF|VERSION|__VERSION

__version
  A pre$defined macro that contains the current server version.
  Contains the same string that the VERSION primitive returns.

__neon
  A pre$defined macro that contains the most recent version of
  NeonMUCK in the MUCK's code.

__proto
  A pre$defined macro that contains the most recent version of
  ProtoMUCK in the MUCK's code.

$ifdef <condition> <compile this if true> $else <compile if false> $endif

$ifndef <condition> <compile this if true> $else <compile this if false> $endif

Where <condition> is either a $defined name, or a test that consists of
a $defined name, a comparator (=,<, or > ) and a test value, all in one
word without space.  The $else clause is optional.  Compiler directives
are nestable also.  Some examples:

  $ifndef __version>Muck2.2fb3.5 $define envprop .envprop $enddef $endif
  $define ploc $ifdef proplocs .proploc $else $endif $enddef

Type 'man dir3' for more directives and 'man dir list' for a listing.
~
DIR3|DIRECTIVES3|DIRECTIVE3|$INCLUDE|INCLUDE

$include <dbref|progreg|integer>

Sets a bunch of $defines from the properties in the /_defs/ propdir.
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. ie:
'desc' would be replaced throughout the program with '"_/de" getpropstr'

If the following integers are passed, then one can control which _defs
and macros get loaded into the program as well:
0 = Macros and MUF owner _defs and #0 _defs
1 = #0 _defs and MUF owner _defs but not macros.
2 = macros only.

Note that for non-wizards, #0 _defs/ are always loaded no matter what.

Type 'man dir4' for more directives and 'man dir list' for a listing.
~~~~
DIR4|DIRECTIVES4|DIRECTIVE4|$BETA|$ALPHA|$VERSION|$LIB-VERSION
$beta <integer>
    Sets an integer prop on the program under a _Beta prop. Note that
    the _Beta prop is cleared at compile time, so if this directive is
    not in the code, that prop will not have a value.

$alpha <integer>
    Sets an integer prop on the program under a _Alpha prop. The _Alpha
    prop is cleared at compile time, so without this directive, there
    will be no value under the prop.

$version <float>
    Sets a string prop on the program under a _Version prop.

$lib-version <float>
    Sets a string prop on the program under _Lib-Version.

See 'man dir5' for more directives and 'man dir list' for a listing.
~~~~~
DIR5|DIRECTIVES5|$AUTHOR|$NOTE|$ANSI|$ABORT|$LOG_STATUS|$SHOW_STATUS
$author <string>
    Sets a string prop on the program under _Author.

$note <string>
    Sets a string (up to the end of the line in the code) under a
    _note prop.

$ansi <message>
    Same as $echo, except that it accepts Neon ANSI tags (^RED^).

$abort [<message>]
    Aborts compiling and prints out the error message.

$log_status <message>
    Adds a line to the status log. Also gets shown to LOGWALL W3s.

$show_status <message>
    Walls the message to LOGWALL W3s without logging it to the status log.

See 'man dir6' for more directives and 'man dir list' for a listing.
~~~~
DIR6|DIRECTIVES6|$PUBDEF|$NOMACROS|$CLEARDEFS|$LIBDEF
$pubdef 
    By using this directive, the _defs/ directory on a MUF program can
    be set at compile time. 
    $pubdef :   = Removes the _defs/ directory on the program object.
    $pubdef <def name> = Removes only that _def/ from program object.
    $pubdef <def name> <definition> = Sets that public _def/
    $pubdef \<def name> <definition> = Only sets _def/ if not already set.
    E.g.: $pubdef tell me @ swap notify
       would put a _defs/tell:me @ swap notify prop on the program object.
    Def names cannot have ':' nor '/' in them.

$libdef 
    This directive allows one to simply name the function to be added
    to the _defs/ directory and the rest will be handled automatically
    at compile time.
    E.g.: $libdef somefunction
        would put a _defs/somefunction:<ref> "somefunction" call 
        prop on the program object.

$nomacros 
    Ignore all macros during compiling.

$cleardefs [ALL]
    Ignores program _defs/ when compiling the program. Wizards 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.

See 'man dir7' for more directives and 'man dir list' for a listing.
~~~~~
|DIR7|DIRECTIVES7|$ifbeta|$ifalpha|$ifver|$iflibver|$ifauthor|$iflib|$ifcancall
Note: In all cases, you can replace <library/prog dbref> with the word: this
      to indicate the program being compiled. These are all $if $else $endif
      constructions. Refer to $ifdef $else $endif for details on usage.

$ifbeta    <library/dbref> <integer>   $ifnbeta    <library/dbref> <integer>
$ifalpha   <library/dbref> <integer>   $ifnalpha   <library/dbref> <integer>  
$ifver     <library/dbref> <float>     $ifnver     <library/dbref> <float>  
$iflibver  <library/dbref> <float>     $ifnlibver  <library/dbref> <float>  
$ifauthor  <library/dbref> <smatch>    $ifnauthor  <library/dbref> <smatch>  
$iflib     <library to check for>      $ifnlib     <library to check for>    
$ifcancall <library/dbref> <function>  $ifncancall <library/dbref> <function>

Some special defines that can be checked via $ifdef:
    HAVE_SQL            - If $ifdef'd, means SQL support was compiled in.
    HAVE_FILE_PRIMS     - If $ifdef'd, means File prims are compiled in.
    HAVE_SOCKET_PRIMS   - If $ifdef'd, means Socket prims are compiled in.
    HAVE_MUF_EDIT_PRIMS - If $ifdef'd, means the MUF editing prims are compiled.

See 'man dir8' for more information on directives.

~~~~
DIR8|DIRECTIVES8|DIRECTIVE8

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.

See 'man dir list' for a list of all directives.
~~~~~
DIR LIST|DIRLIST|ALL DIRECTIVES|DIRS
 
Working with props:
$alpha      $pubdef    $note      $lib-version
$beta       $author    $version

Working with macros and definitions:
$define     $enddef    $def       $undef
$cleardefs  $include   $nomacros  

Notification:
$echo       $ansi      $abort     $show_status
$log_status

Compilier Variables:
__version  __neon      __proto    __muckname

Conditionals:
$ifdef     $ifalpha    $ifbeta    $ifver       $iflibver
$ifndef    $ifnalpha   $ifnbeta   $ifnver      $ifnlibver
$ifauthor  $iflib      $ifcancall
$ifnauthor $ifnlib     $ifncancall

See 'man dirs' for more infomation on directives.
~~~~
LIBRARIES|LIBS|LIB1|LIBS1|LIBRARIES1

How to use a library:
    1) Use "@register lib" to list what libraries exist.
    2) Use "@view $lib/<library name>" 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/<library name>
        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.

Type 'man lib2' for more help with libraries.
~
LIB2|LIBS2|LIBRARIES2|LIBRARY2

How to make a library:
    1) create a program with several useful generic subroutines.
    2) DOCUMENT those subroutines in a commented out header in the prog.
    3) @set <program>=_docs:<command to list those docs you made>
    4) make sure that all the functions are declared PUBLIC.
    5) Make sure the program is set LINK_OK.
    6) Globally register the program with the @register command with a
        prefix of "lib/".  ie: @reg lib-strings=lib/strings
    7) Set up the interface for each function on the program. To do this,
        you will need to set properties on the program in the form
          _defs/<callname>:"$" match "" call
        where  is the name that you want to have people use to
        invoke it in their programs, <libname> is the registered name you
        gave it (ie: lib/strings), and <funcname> is the actual name of
        the function in the program.  Example:
          @set lib-strings=_defs/.split:"$lib/strings" match "split" call
    8) You're done!
~
LOOPS|LOOP|LOOP1

The BEGIN or FOR/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 to the statement after the BEGIN
    or FOR/FOREACH statement.

  UNTIL checks to see if the value on the stack is false.  If it is, it
    jumps execution to the statement after the BEGIN or FOR/FOREACH 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.

See: LOOP2 for additional loop instructions.
~
LOOP2|LOOPS2

  A WHILE statement checks to see if the value on the stack is false.
    If it is, execution jumps to the first statement after the end of
    the loop.  If the value was true, execution falls through to the
    statement after the WHILE.

  The CONTINUE statement forces execution to jump to the beginning of
    the loop, after the BEGIN or FOR/FOREACH statement.

  The BREAK statement forces execution to jump to the end of the loop,
    at the statement after the REPEAT or UNTIL, effectively exiting the
    loop.

Note: You can nest loops complexly, but WHILE, BREAK, and CONTINUE
  statements only refer to the innermost loop structure.

See: LOOP3 for a summary of loop instructions
~
LOOP3|LOOPS3

To start a loop:
BEGIN - Takes no arguements, mostly just a marker.
FOR   - Takes 3 integer arguements, ideal for counter loops.
FOREACH - Takes an array as an arguement, returns each element contents.

To repeat a loop:
UNTIL - If top of stack is false, repeats the loop. (end of loop)
CONTINUE - Unconditional return to 'BEGIN' marker.
REPEAT - Unconditional return to 'BEGIN' marker. (end of loop)

To end a loop early: 
BREAK - Unconditional exit from the loop.
EXIT - To exit the word which contained the loop.
WHILE - If top of stack is false, exits loop.

To mark the end of the loop:
UNTIL - Repeats until top of stack is true.
REPEAT - Unconditional repeat.

The minimum instructions to write a loop in MUF are either:
BEGIN - UNTIL or BEGIN - REPEAT

See: LOOP4 for an example program using complicated loops.
~
LOOP4|LOOPS4

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 then (this WHILE refer to the outer loop)
    dup intostr me @ swap notify
  dup 1 = until pop               (This UNTIL ends the outer loop)

See: LOOP5 for an example of FOR loops.
~~~
LOOPS5|LOOP5

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 complex FOR loop:
  -10 10 1 for
    me @ over intostr notify
    not
  until
Example of a FOREACH loop:
  "index1" "value1" "index2" "value2" 2 array_make_dict
  foreach
    " - " swap strcat strcat me @ swap notify
  repeat
~
CREDITS

This version of the MUF manual has been edited, and rewritten for use with
  ProtoMUCK by Akari (Nakoruru08@hotmail.com). 
  Generally a cleaned up format, more accurate permissions levels to 
  reflect the changes in ProtoMUCK, the addition of undocumented prims
  in NeonMUCK, as well as several new prims added in ProtoMUCK. Many of
  the old entries were cleaned up and clarified as well. 

  It is based on the work done by:
  Foxen (foxen@netcom.netcom.com), who wrote the original docs.
  WhiteFire (kinomon@glia.biostr.washington.edu), who cleaned them up a lot.

  ProtoMUCK is the result of the combined efforts of programmers: 
                           Moose and Akari
       and is based initially on NeonMUCK version 2.17 and FB6.

See: CREDITS2 for a list of contributors
~~
CREDITS2

The following names are known for contributing to the MUF support in MUCK:

Lachesis  - Wrote the MUF compiler, introduced MUF to MUCKS.
Foxen     - A lot of the original work on the FB and FB6 code base and docs.
Whitefire - Some of the older MUF prims.
Points    - Author of the float support for FB6.
Loki      - Many bug fixes and new prims added in NeonMUCK
Nodaitsu  - Contributed file prims from MakoMUCK.
Moose     - Author of several of the ProtoMUCK exclusive prims.
Akari     - Author of some ProtoMUCK prims, debugger, tester.

No doubt many others have added their own contributions to MUF over
the years. Sending a message to Nakoruru08@hotmail.com with the name
of those left out of this list, and what they contributed, will result
in a more accurate list with time.
~~~~~~~~~~~~~
FLAGS|FLAG1|FLAGS1|DEBUG|ZOMBIE|DEBUG-EDITOR|DARK|PARENT|PROG_DEBUG
The following flags have a certain affect on MUF when set on the 
program object itself:

DEBUG (D) = When when a program set = D is run by anyone who
            has control over it ( owner and wizzes ), it prints
            out the contents of the stack each step of the way 
            as the program is ran. By setting a player = PROG_DEBUG, 
            they will see the DEBUG trace of every program set = D
            that they run, even if they do not have control over the
            program.

DEBUG-EDITOR (Z) = When a program set = Z is run by anyone who has
            control over it ( owner and wizzes ), the player is put
            in an interactive debug editor that gives them a lot of
            options to test different cases as the program is run.
            Type 'help' when in debug-editor mode to see a list of the
            options available.

PROG_DEBUG (%) = This is the same as the PARENT flag. Programs set both
            DEBUG and PROG_DEBUG will direct all of the debug information
            to the owner of the program instead of the user if the user is
            unable to see the debug info themselves. Useful for debugging
            programs called from the webserver or login screen. In the case
            where the user is a wiz, the wiz will have to set themself = Q
            in order for the owner to be given the debug info. Note that the
            stack backtrace will always be shown to the owner with this flag.

See: FLAGS2
~
FLAGS2|FLAG2|AUTOSTART|ABODE|BOUND|BUILDER|EXPANDED_DEBUG|XFORCIBLE

AUTOSTART (A) = On dbload, if a program is set AUTOSTART *AND* is
            owned by a wizard, then it will be placed in the timequeue
            with a delay of 0 and a string arguement of "Startup".
            Autostart programs run with the location NOTHING (#-1). They
            will also run automatically after a successful compile.

BOUND (B) = Programs set BOUND run in preempt mode, regardless of the 
            mode the program would normally run in, ignoring all attempts
            to change the mode during the run of the program.

EXPANDED_DEBUG (X) = Programs set with EXPANDED_DEBUG will display much
            longer string data, and will also display the contents of 
            MUF arrays, up to the size allowed by the buffer. Removing
            this flag makes it so that debug output is sent in the 
            traditional manner of shorter strings and no contents of the
            arrays being seen.

See: FLAGS3
~~~
FLAGS3|FLAG3|VEHICLE|VIEWABLE|LINK_OK|O|OLDCOMMENT

VIEWABLE (V) = A program set VIEWABLE can be @listed by any player 
            expect for guests.

LINK_OK (L) = Setting a program linkable makes it available for use by
            other players on the MUCK. Anyone can @link actions to 
            programs set L, and in order for programs in propqueues
            to work for players other than their owner, they need to be
            set = L. If an action not owned by the program owner is
            already linked to the program when the L flag is removed, then
            the action will no longer work.

OLDCOMMENT (O) = Setting a program with OLDCOMMENT makes it so that the
            comments in it are parsed using the traditional comment 
            parser. Comments are handled using Proto's comment parser
            by default and this should only be used if an older program
            fails to compile due to it's comments not complying with the
            new method.

See: FLAGS4
~~~
FLAGS4|FLAG4|HARDUID|HAVEN|STICKY|SETUID|QUELL

HARDUID (H) = If a program has the HARDUID flag set on it, 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 #-1, then it will run with the permissions and uid
            of the owner of the program.

SETUID (S) = If a program is set both SETUID and HARDUID, and it is owned
            by a wizard, it inherits the uid and mucker level of the 
            program or trigger that calls it, ignoring other permissions 
            settings on the program. If the program was not called by 
            another program it runs at the normal permissions level of the 
            program owner.
            Note: MUF in Neon, Glow, and Proto run SETUID by default, which
                  means they run at the level of the program's owner.

QUELL (Q) = As of Proto1.6 and newer, if a program is set both HARDUID and 
            QUELL, then it will run at the permission level of the bit on 
            that program object itself.
         
See: FLAGS5   
~~~~~
FLAGS5|FLAG5|NO_OPTIMIZE|NO_COMMENT

NO_OPTIMIZIE (N) = Setting this flag on a MUF object will keep that 
            program from being optimized during compile time if the
            MUF optimizer is @tuned to yes. See MUF OPTIMING.

WIZARD/MUCKER (M1 - W4 ) = The limit of what a program can and cannot do
            is influenced by the M/W bit of the owner of the program. 
            Under FuzzBall MUCK servers, the M/W bit on the program also
            determined the permission level of the MUF, but this is
            no longer the case in Neon, Glow, or Proto, with two 
            exceptions: 
            Any MUF that parses MPI at any point will be affected by its
            M/W bit. And a MUF without at least a M1 bit will not run.
            Note: Under NO circumstances can a program ever run at a 
                  higher permission level than its owner, regardless of
                  H, S, Q, M, and W flags set on the program object or
                  calling objects. 

See: MUCKER LEVELS
~
COMMAND|TRIGGER|ME|LOC

There are four variables that are included with every program
automatically when it is run. They are:
me @ - Returns the dbref# of whatever is using the program.
       If a player triggered the program, it is that player. If a
       puppet triggered the program, then it is the dbref of the puppet

trigger @ - Returns the dbref# of the trigger. If the program was 
            called by an action, this is the dbref of the action. If the
            program was called by a propqueue, this is the dbref on which
            the propqueue is.

loc @ - Returns the dbref of the location of the trigger that called the
        program. Programs called during AUTOSTART have a loc @ of #-1.

command @ - Returns a string that represents what the player typed
            to activate the program. If the program was called by 
            a prop directory, then it returns "Queued event.". If the
            program was called by another program, it inherits the
            command @ value from the calling program.

Note that these are normal variables, and can be given new values
via the normal means.

See: VARIABLE, VAR, LVAR.
~
PROPQUEUES|PROPQUEUES1
MUF may be called from properties on objects, with the following
guidelines:
A program not set = L will only run when called by a propqueue by
something that its owner does.

All propqueues can take the form of _, ~, or @ props.

Propqueue props can be of type dbref or string. If of type string, they
need to be a number that looks like an int or a dbref, or be MPI code. If 
they are to be MPI that is to be parsed, they must start with a & mark at
the beginning.

Programs called from propqueues run in BACKGROUND mode by default, and
therefore cannot use the READ prim.

Propqueues are called all the way down the environment tree. This 
means that a _arrive prop on a parent room would be called when someone
arrives in any room parented to that parent room. Setting propqueues on
#0 makes that program call happen everytime that event happens on the 
MUCK. A _connect prop on #0 would be called anytime someone connects
on the MUCK.

Propqueues are ran in the order they appear in the directory
(alphabetical). The actual name of the prop is not important, other than
in determining the order. 

For every propqueue there is also a o-propqueue. For example: 
  _disconnect/ and _odisconnect/            _idle/ and _oidle/
This only matters if the prop contains MPI to be parsed. The o-propqueues
make the MPI public as opposed to private to just the player.

See: PROPQUEUES2 for types of queues.
~
PROPQUEUE2|PROPQUEUES2|LISTEN|CONNECT|DISCONNECT|ALISTEN

_listen/ = Listen props are limited to a certain level of 
       permissions, depending on an @tuned setting. Typically M3
       due to the risks associated with listen props. These are
       triggered anytime anything is notified to object, be it
       an in-server message, a @succ, a NOTIFY_EXCLUDE, or even
       a NOTIFY directly to the object. The contents of the stack
       is whatever string was heard that triggered the program. The
       command @ for listen-prop called programs is "(_Listen)"

_alisten/ = Exactly like the _listen/ propqueue, except that strings
       retain their Neon ANSI tags.

_connect/ = Connect props are called when a player connects.
       They can be on the room the player connects in, or on the 
       player itself. The program starts with "Connect" on the
       stack, the command @ is "Queued event." and the trigger @
       is #-1.

_disconnect/ = Works just like the connect props, except is run
       when a player disconnects. The starting arguement is
       "Disconnect", the rest is the same.

See PROPQUEUES3 for additional queues.
~
PROPQUEUES3|PROPQUEUE3|ARRIVE|DEPART|_ARRIVE|_DEPART

_arrive/ = Runs programs whenever something arrives in a 
        room. The object that triggers it can be a player or a
        thing. The arguement on the stack is "Arrive", the
        command @ is "Queued event.", and the loc @ is the location 
        where the player is when the program is called. The trigger
        is the MUF that used moveto to get the player there, the
        exit to get the player there, or, if the player gets there
        by using 'home', the trigger is the dbref of the room they
        left.

_depart/ = Runs programs whenever something departs from a room. The
        object that triggers it can be a player or a thing. The
        arguement on the stack is "Depart", the command @ is
        "Queued event.", the loc @ is the room that was left. The
        trigger varies just like with the arrive prop calls, even
        when 'home' is used, the dbref given is the room that was left.

See: PROPQUEUES4 for additional propqueues.
~~~~~
PROPQUEUES4|PROPQUEUE4|IDLE|UNIDLE|LOOK

_idle/  = This propqueue is called when a player reaches a certain
        amount of time idle. The idle time is determined by the
        idletime @tuneable option. The starting arguement is "Idle",
        the me @ is the player that became idle, the trig will be #-1,
        the loc @ will be the location of the player, and command @
        will be "Queued event."

_unidle/ = This propqueue is called when a player unidles after reaching
        the idletime @tuneable option. All of the information will be the
        same as the _idle/ propqueue, except the starting arguement will
        be "Unidle".

_look/  = This propqueue tends to be handled by MUF look front ends, and
        has no automatic in-server function. However, since it is @tuneable,
        and most look programs support the _look/ propqueue, it is mentioned
        here.

See: PROPQUEUES5 for additional propqueues.
~~~~
PROPQUEUES5|PROPQUEUE5|LOGIN|DISCLOGIN|DUMPWARN|@DUMPWARN|DUMP|@DUMP

@login = Called when a connection is made to the login screen. The initial
        argument is 'Login', command @ is 'Queued event.', trig is #0, 
        me @ is #0, loc @ is #0. This propqueue can only be set on #0.

@disclogin = Called when a connection is dropped from the login screen.
        The initial conditions are the same as _login/, except that the initial
        arguement is 'Disclogin'.

@dumpwarn = Called right before the periodic Save warning message would be
        shown. The trigger is #-1, the player triggering is #1, the loc @ 
        is #0. This propqueue can only be set on #0.

@dump = Called right before a data base save. Trigger is #-1, player 
        triggering is #1, the loc @ is #0. This propqueue can only be
        set on #0.

~~~~~
PUT

put ( xn...x1 xi i -- xn...xi...x1 )
------------------------------------
Level: M1 Apprentice
x = Any data type on the stack.
i = integer representing where in the stack to put xi

Replaces the i'th thing from the top of the stack with the value of xi.
Note that put does not insert into the stack, it actually replaces
the element at the depth given by integer i.
1 put is equivalent to swap pop

Example:
  "a" "b" "c" "d" "e" 3 put
would return on the stack:
  "a", "e", "c", "d"
~~~~~
ABORT

abort ( s -- )
--------------
Level: M1 Apprentice
s = string containing the message to be included in the abort error.

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|CHECKARGS1|CA1

checkargs (??? s -- )
---------------------
Level: M1 Apprentice
??? = Whatever is on the stack before the definition string.
s = string that defines what -should- be on the stack.

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.

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

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.

Type 'man checkargs2' for more help and a list of tests.
~
CHECKARGS2|CA2

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

Type 'man checkargs3' for more help and hints.
~
CHECKARGS3|CA3

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.

Type 'man checkargs4' for more help and hints.
~
CHECKARGS4|CA4

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.

Type 'man checkargs5' for more help and hints.
~
CHECKARGS5|CA5

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.
~
DATE

date ( -- d m y )
-----------------
Level: M1 Apprentice
d m y = integer values of the day of the month, the month, and the year.

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.
~
GMTOFFSET

gmtoffset ( -- i)
-----------------
Level: M1 Apprentice
i = integer representing seconds.

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

stringpfx (s1 s2 -- i)
----------------------
Level: M1 Apprentice
s1 = string to check the prefix of.
s2 = string to compare to the prefix of s1.
i  = integer indicating a true or false result.

Returns 1 if string s2 is a prefix of string s1.  If s2 is NOT a 
prefix of s1, then it returns 0.  Case insensitive. NOTE that if 
s1 is an empty string, stringpfx will return a negative number
which will check as being TRUE. So it is best to check for 
empty strings before using stringpfx on them, or the result will
be inaccurate.
~
PART_PMATCH

part_pmatch (s -- d)
--------------------
Level: M1 Apprentice
s = string to match against player names.
d = dbref representing either player, or failed match.

Given string s, tries to match it against the names of all players 
currently online. If the given string is a prefix to the name of a player
who is online, it returns their dbref. If more than one player matches that
prefix, it returns #-2, and if there are no matches, it returns #-1.
~
MODE

mode ( -- i)
------------
Level: M1 Apprentice
i = integer indicating the mode the program is running in.

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.
These are defined as:
0 being preempt mode
1 being foreground mode
2 being background mode

Also see PR_MODE.
~
SETMODE

setmode (i -- )
---------------
Level: M1 Apprentice
i = integer indicating the mode to set the program to.

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.  
The modes to set are:
0 for preempt
1 for foreground
2 for background

Also see PR_MODE, MODE.
~
PR_MODE|FG_MODE|BG_MODE

pr_mode fg_mode bg_mode ( -- i)
-------------------------------
Level: M1 Apprentice
i = integer representing that mode. 

These are all standard built in defines.  They are 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 defined as 0, fg_mode is defined as 1,
and bg_mode is defined as 2.
~
ADDRESS?

address? (x -- i)
-----------------
Level: M1 Apprentice
x = Any object on the stack.
i = integer representing true or false result.

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

See: EXECUTE, ADDRESS
~
ADDRESS

Function names can be placed on the stack and treated just like 
any other data type by entering them in the code as '<function_name>.
The function name can then be manipulated around the stack just
like any other data object in MUF. It can be called by the
EXECUTE prim. Other than functions such as DUP, ROT, etc, that handle
stack manipulation, there is not much else in the way of prims that
will interact with the address, other than EXECUTE and ADDRESS?.

See: ADDRESS?, EXECUTE
~
SOCKET?

socket? ( x -- i )
------------------
Level: M1 Apprentice
x = Any object on the stack.
i = integer representing true or false result.

Given x, returns 1 if x is a normal socket descriptor, or -1 if x is
a listening socket descriptor, otherwise it returns 0. 
~
LOCK?

lock? (x -- i)
--------------
Level: M1 Apprentice
x = Any object on the stack.
i = integer representing true or false result.

Returns true if the top stack item is a lock.

See GETPROP, SETPROP, PARSELOCK, UNPARSELOCK, PRETTYLOCK, and TESTLOCK.
~~~~~
GETPROP

getprop (d s -- x)
------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the name of the prop to get.
x = Can be any data type depending on the type of property retrieved.

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, or float
depending on the type of the property. This primitive returns 0 if 
no such property exists, of if it is a valueless propdir. Users below 
M3 level cannot read . props, and users below W3 level cannot read @ 
props.

See SETPROP, ADDPROP, REMOVE_PROP, GETPROPSTR, GETPROPVAL, INT?, DBREF?,
STRING?, and LOCK?.
~
SETPROP

setprop (d s x -- )
-------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the name of the prop to store on.
x = Can be any valid data type on the stack.

Stores a lock, dbref, integer, or string into the named property on the
given object.  
M2 through W1 cannot set _, ., ~, or @ props on objects they do not own,
  nor ~ and @ on objects they do own.
W2 can set ~ props on anything, but not @ props.
W3 and up can set any prop on anything.

See SETPROP, ADDPROP, REMOVE_PROP, GETPROPSTR, and GETPROPVAL.
~~~~
PARSELOCK

parselock (s -- l)
------------------
Level: M1 Apprentice
s = string representing the attempted lockstring.
l = A valid lock returned to the stack, or a 'false' indicator.

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.
The result, l, can then be used with 'setprop' to set locks other than the
default '_/lok' @lock.

See UNPARSELOCK, LOCK?, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR,
    LOCKED? and ISLOCKED?.
~
UNPARSELOCK

unparselock (l -- s)
--------------------
Level: M1 Apprentice
l = Any lock type.
s = string representing the lock.

Unparses a lock into a string fit for program editing.

See LOCK?, PARSELOCK, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR,
and LOCKED?.
~
PRETTYLOCK

prettylock (l -- s)
-------------------
Level: M1 Apprentice
l = Any lock type.
s = string representing the lock.

Unparses a lock into a string fit for players to see. I.e, unparses
player names, etc.

See LOCK?, PARSELOCK, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR,
and LOCKED?.
~
TESTLOCK

testlock (d l -- i)
-------------------
Level: M1 Apprentice
d = Any valid player or thing dbref.
l = lock to be tested.
i = integer representing result of test. 1 if passed, 0 if failed.

Tests the player against the given lock.  If the test was successful,
then this returns a 1.  If the test failed, then this returns a 0.
Note that testlock does -not- check for props on the exit itself, nor
calls MUF programs that are called by the @lock. This has the 
advantage of not triggering MUF that is not supposed to be triggered
until the lock is tried, but has the disadvantage that it may return
an incorrect value. For a prop on the exit itself or the MUF called
from the @lock may allow the player to pass, but testlock will still
return 0 for failed.

See LOCK?, PARSELOCK, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR,
    LOCKED? and ISLOCKED?.
~
PARSEPROP

parseprop (d s1 s2 i -- s3)
---------------------------
Level: M3 Master
d  = Any valid dbref.
s1 = string containing the name of the prop to get the MPI from.
s2 = string containing the &how variable's contents.
i  = integer indicating choice on whether {delay} messages are sent to
     the player only, or to the room.
s3 = string result of parsed contents of the prop.

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.

See: PARSEMPI, PARSEPROPEX
~
PARSEMPI

parsempi ( d s1 s2 i -- s3 )
----------------------------
Level: W2 Wizard
d  = Any valid dbref.
s1 = string to parse.
s2 = the &how variable for the MPI
i  = integer indicating choice on whether {delay} messages are sent to
     the player only, or to the room.
s3 = The results of the parsed MPI.

Returns the string output of the MPI Parser, given an object, a string of
MPI 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. 

See: PARSEPROP
~
CONTROLS

controls ( d1 d2 -- i )
-----------------------
Level: M1 Apprentice
d1 = Any player dbref.
d2 = Any valid dbref.
Takes a player dbref d1 and an object dbref d2, and returns true if the
player has control over the given object. This works differently than
the OWNER prim, because any character W2 or over will have 'control'
over any valid dbref, unless the MUCK was configured otherwise at
compile time.
~
SYSPARM

sysparm ( s1 -- s2 )
--------------------
Level: Varies depending on the parameter being looked up.
s1 = string representing the paramter to check.
s2 = Varies depending on the value type of that paramter.

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 with higher permissions then
the program has will return an empty string.
~
SETSYSPARM

setsysparm ( s1 s2 -- )
-----------------------
Level: W3 ArchWizard
s1 = string representing the @tune parameter to set.
s2 = the value to set to the @tune parameter.

Given a valid system paramter in s1, and a legitimate value for that 
paramter in s2, will set the sysparm to that value. Will abort if there
is a problem with either the value or the parameter name.
~
DESCR_SETUSER

descr_setuser ( i1 d s -- i2 )
------------------------------
Level: W2 Wizard
i1 = integer representing a descriptor number.
d  = dbref of a player.
s  = string containing the password of that player.
i2 = Returns 1 if successful, 0 if unsuccessful.

Given descriptor i1, a player's dbref d, and that player's password in
string s, that player will be connected to that descriptor number, without
dropping the connection to the MUCK. From the MUCK's perspective, it first
disconnects that descriptor from the old dbref, then connects the new one,
as if QUIT was used for the original player, and the second player then
connected. It returns 1 if the descriptor was found and reassigned, 
or 0 in case of password failure.
~
DESCR_SETUSER_NOPASS

descr_setuser_nopass ( i1 d -- i2 )
-------------------------------------
Level: W4 BOY
i1 = integer representing a descriptor number.
d  = dbref of a player.
i2 = Returns 1 if successful, 0 if unsuccessful.

Given descriptor i1, a player's dbref d, that player will be connected 
to that descriptor number, without dropping the connection to the MUCK.
From the MUCK's perspective, it first disconnects that descriptor from 
the old dbref, then connects the new one, as if QUIT was used for the 
original player, and the second player then connected. It returns 1 if 
the descriptor was found and reassigned, or 0 in case of failure.

This primitive is usable only by W4's and requires no password to use.
~
INTERP

interp ( d1 d2 s -- ? )
-----------------------
Level: M1 Apprentice
d1 = dbref of program to run.
d2 = dbref of trigger to use to run the program.
s  = string to pass to the program as the arguement.

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.
Return value is the top item off the stack. For players lower than W2, can
only be used to run programs they own. For W2 and up, can only be used
to run programs that have an equal or lower level of permission as the wiz
trying to run it.
~
CHECKPASSWORD

checkpassword ( d s -- i )
--------------------------
Level: W3 Archwizard
d = dbref representing a player.
s = string containing possible password.
i = integer representing result. 1 indicates a match.

Given a player's dbref, checks to see if that players password is the
same as the contents of string s. If it is, 1 is returned, otherwise 0
is returned.
~
PMATCH

pmatch ( s -- d )
-----------------
Level: M1 Apprentice
s = string to match against player names.
d = dbref indicating player if matched, otherwise a failure code.

Given string s, first matches it as a full name. If it finds any player
who's name is a complete match to s, then it returns that player. If not,
it then checks the players online. If it finds a player whos name has
string s as a prefix, it returns their dbref. #-1 indicates no match found,
#-2 indicates more than one player online matches string s.

See: PART_PMATCH
~
NEXTOWNED

nextowned ( d -- d' )
---------------------
Level: W1 Mage
d  = Any valid dbref.
d' = A dbref of any kind except for players.

Given a player's dbref, nextowned returns the first object owned by that
player. Given any other valid dbref, nextowned returns the next in a list
of objects owned by that player. By using nextowned in a loop, it is 
possible to list all of the objects owned by that player.
~
NEXTPLAYER

nextplayer ( d -- d' )
----------------------
Level: M3 Master
d  = Any valid dbref.
d' = dbref representing next player found in the data base.

Given dbref d, nextplayer returns the first player found that is higher
in the database. d can be any valid dbref, but d' will always return
a valid player dbref until it reaches the top of the stack, in which case
it will return #-1.
#0 nextplayer would return #1. 
~
NEWPLAYER

newplayer ( s1 s2 -- d )
------------------------
Level: W3 ArchWizard
s1 = string containing the name of the new player.
s2 = string containing the password of the new player.
d  = dbref of the new player that was created.

Given a name, s1, and that player's password, s2, it creates a new player
and returns the dbref of the new player to the stack.
~
COPYPLAYER

copyplayer ( d1 s1 s2 -- d2 )
-----------------------------
Level: W3 ArchWizard
d1 = Valid player dbref.
s1 = string containing new player's name.
s2 = string containing new player's password.
d2 = dbref of the new player that is created.

Given an existing player's dbref d1, a new character name s1, new character's
password s2, copy player creates a perfect copy of player d1 and returns
the dbref of the new character to the stack.
~
TOADPLAYER

toadplayer ( d1 d2 -- )
-----------------------
Level: W3 ArchWizard
d1 = Valid player dbref to chown all the objects to.
d2 = Valid player dbref to remove from the MUCK.

Given two valid player dbrefs, toadplayer will first move ownership of all
of player d2's object to player d1, and then remove player d2 from the MUCK.
It follows the same restrictions as the inserver @frob/@toad, such as
not being able to frob wiz-bitted characters, etc.
~
STOPMIDI

stopmidi ( d -- s )
-------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string containing the instructions to do a stopmidi for a player.

Given a player dbref, d, checks to see if that player has a PUEBLO flag
or not. If not, returns an empty string. If the PUEBLO flag is found, 
returns the HTML instructions for doing a stopmidi. It would still have
to be notified out to that player.
~
PLAYMIDI

playmidi ( d s1 i -- s2 ) 
-------------------------
Level: M1
d  = Any valid dbref.
s1 = string containing URL for the MIDI.
i  = integer representing the volume to play the MIDI at.
s2 = HTML instructions that will play that midi.

Given a dbref of a player, checks to see if that player has a PUEBLO
flag. If it does, playmidi returns the HTML instructions to play
a MIDI located at URL s, at volume i. If the dbref is not a player, 
or that player does not have a PUEBLO flag, it returns an empty string.
Either result could then be notified out to the player.
~
COMMANDTEXT

commandtext ( d s1 s2 -- s3 )
-----------------------------
Level: M1 Apprentice
d  = Any valid dbref.
s1 = string containing the destination or action of the hotlink.
s2 = string containing the text to be displayed in-MUCK.
s3 = string containing the formatted HTML instruction.

Checks if d is a player with a PUEBLO flag set. If so, returns the
hotlink to perform action S1, with the MUCK displayed in the MUCK
being the contents of S2. S3 is the formatted string that could then
be notified to be used.
~
LOGSTATUS

logstatus ( s -- )
------------------
Level: W3 ArchWizard
s = Any string.

Given string s, it adds that string to the status log on the server.
~
SOCKETS|SOCKET PRIMS
NeonMUCK included a set of MUF prims that allowed for powerful
things to be done by opening data transfer sockets to other servers
and ports, but there were issues of instability that plagued their use.

In ProtoMUCK, these have been cleaned up, and are safe to use, but the
level of permissions required to use them has been increased from W1 to
W3. Socket descriptors appear on the stack as (SOCKET), but while a MUF
may have more than one socket open at a time, they will appear the same
on the stack while debugging, so it is important to keep track of which
is which while working on a program. 

When a program aborts or ends with any sockets still open, all open 
sockets are closed. 


NOTE: Socket prims are a compile time option and may not be present.
SOCKOPEN is included strictly for backwards compatability, though now
returns a non-blocking socket as well.

Socket related prims:
     SOCKOPEN, SOCKCLOSE, SOCKSEND, SOCKRECV, NBSOCKOPEN, SOCKCHECK,
     SOCKET?, SOCKDESCR, NBSOCKRECV, LSOCKOPEN, SOCKACCEPT, GET_SOCKINFO,
     SOCKET_SETUSER, SET_SOCKOPT, SOCKTODESCR, SOCKSHUTDOWN, DNS

SSL related prims (--enable-ssl):
     SOCKSECURE, SOCKUNSECURE, SSL_SOCKACCEPT

UDP related prims:
     UDPSEND, UDPOPEN, UDPCLOSE

New IPv6 related prims (--enable-ipv6):
     SOCK6OPEN, NBSOCK6OPEN, LSOCK6OPEN, UDP6SEND

See: SOCKETS2
~
SOCKETS2|SOCKET PRIMS 2
More notes on sockets:

If IPv6 is enabled, UDPOPEN opens a listener on both ipv4 and ipv6.

The IPv6 prims have the exact same function and format as the IPv4
prims, but they take IPv6 addresses and hosts.  IPv6 prims will only
attempt to seek IPv6 hosts.
~
SOCKOPEN|SOCK6OPEN

sockopen/sock6open ( s1 i -- socket s2 ) 
----------------------------------------
Level: W3 ArchWizard
s1 = string representing the host to connect to.
i  = integer representing the port number to connect to.
socket = A special data type, represented as (SOCKET) on the stack.
s2 = string indicating result of attempted socket opening.

Given the host and port number, attempts to open a connection with
another site. If the host name is not recognized by DNS, the program
will abort, otherwise will attempt to open a connection. If the 
connection is successful, a socket variable and string containing
"noerr" are returned to the stack. Any other result than "noerr" 
should be treated as a failed connection, and the socket return should
be discarded. The code on this has been changed to create safer
non-blocking sockets instead, and the timeout is 10 seconds.

SOCK6OPEN performs the same function as SOCKOPEN, but it takes
IPv6 hosts and IPs, and connects via IPv6.

See: SOCKETS
~
SOCKSEND

socksend ( socket s -- i ) 
--------------------------
Level: W3 ArchWizard
socket = socket descriptor to send the string to.
s = string to send to socket descriptor.
i = integer indicating success.

Given a socket descriptor and a string, socksend will attempt to send
the string to the given descriptor. If the string is successfully sent,
it will return a true integer value to the stack, otherwise it will
return 0, indicating that the connection has been closed.

See: SOCKETS
~
NBSOCKRECV|SOCKRECV

nbsockrecv ( socket -- i s )
----------------------------
Level: W3 ArchWizard
socket = socket descriptor to check for a string at.
i = integer representing connection status.
s = string representing what was received, or an empty string if nothing.

Given a socket descriptor, will attempt to receive an incoming string.
If a string is recieved, it puts the string out onto the stack. If there
is nothing that has come in on that socket since the last check, an 
empty string is pushed. This prim needs to be used in some kind of loop
to be particularlly useful, otherwise it may always seem to just return
empty strings.

The integer returned will be 0 if the connection has been dropped.

SOCKRECV is still supported, but it is now an inserver #define of:
nbsockrecv swap pop

See: SOCKETS
~~~
SOCKDESCR
sockdescr ( socket -- i )
-------------------------
Level: W3 ArchWizard
socket = MUF socket descriptor.
i = socket number

When sockets are created, they are assigned a unique socket number that
is valid through the life of the socket. This prim will return that number
to the stack. This prim cannot be used as an indicator of a socket being open
or closed, as sockets retain their socket number even if the connection is
closed.

~~
SOCKCLOSE

sockclose ( socket -- i )
-------------------------
Level: W3 ArchWizard
socket = socket descriptor to close.
i = integer representing success or failure.

Given the socket descriptor, sockclose will close it to prevent any
further information to come in via the socket, or be sent out through
it. When a MUF program ends, either by crashing, or ending normally, 
any open socket connections are automatically closed. Still, it is a 
good practice to close them manually when they are no longer needed.

This prim is depricated as of 1.80 and newer. Starting with Proto 1.9,
it will be replaced by an in-server define of:
2 SOCKSHUTDOWN

See: SOCKETS, SOCKSHUTDOWN
~
SPLIT

split ( s1 s2 -- s3 s4 )
------------------------
Level: M1 Apprentice
s1 = string to split.
s2 = string representing the point at which to split s1.
s3 and s4 = The result of s1 being split at s2.

Given a string, s1, and another string, s2, will split s1 
just after the first instance of s2 in s1. Note that the 
s2 is not included in either string after it the split
is done, so
"Some String" " " split will produce "Some" "String"
If s2 is not found, it returns the original string, plus
an empty string to the stack.

See: RSPLIT
~
RSPLIT

rsplit ( s1 s2 -- s3 s4 )
-------------------------
Level: M1 Apprentice
s1 = string to split.
s2 = string representing the point at which to split s1.
s3 and s4 = The result of s1 being split at s2.

Given a string, s1, and another string, s2, will split s1 
just after the last instance of s2 in s1. Note that the 
s2 is not included in either string after it the split
is done, so
"Some Sample String" " " split will produce "Some Sample" "String"
If s2 is not found, it returns the original string, plus
an empty string to the stack.

See: SPLIT
~
CTOI

ctoi ( s -- i )
---------------
Level: M1 Apprentice
s = string containing character to convert.
i = integer representing the ASCII number of the first character in s.

Given a character in string s, will return that character's ASCII
number to the stack. If there are more than just one characters in s,
only converts the first character.

See: ITOC
~
ITOC

itoc ( i -- c )
---------------
Level: M1 Apprentice
i = integer reprenting an ASCII number.
s = string representing a single character.

Given an integer, returns the ASCII character that integer i 
represents. i cannot be negative. If i is out of range for valid
ASCII characters, an empty string is returned to the stack.

See: CTOI
~
STOD

stod ( s -- d )
---------------
Level: M1 Apprentice
s = string representing a dbref.
d = Result of converting s to a dbref.

Given a string representing a dbref, will return that dbref to the stack.
The string may be all integers, or may start with a '#'. If the string
is empty, or contains any other characters, will return #-1 to the stack.
~
DTOS

dtos ( d -- s )
---------------
Level: M1 Apprentice
d = Any possible dbref.
s = string representing that dbref.

Given a data object of type dbref, returns that dbref as a string, including
the # sign. So #50 dtos will return "#50".
~
MIDSTR

midstr ( s1 i1 i2 -- s2 )
-------------------------
Level: M1 Apprentice
s1 = Original string.
i1 = integer representing the start point.
i2 = integer representing the length.
s2 = string representing the contents of s1 from i1 to i2.

Returns a sub-string of s1, starting at position i1, of length 
i2. The first character is considered position 1, so that:
"testing" 2 3 midstr will return the value "est"

If s1 is shorter than the range given by i2, then the maximum number
of character that could be returned will still be put on the stack.
If s1 is an empty string, returns an empty string no matter what.
If i1 is a point that is beyond the range of s1, returns a null string.
~
NOTIFY_DESCRIPTOR|DESCRNOTIFY|ANSI_NOTIFY_DESCRIPTOR

notify_descriptor or ansi_notify_descriptor or descrnotify ( i s -- )
---------------------------------------------------------------------
Level: W1 Mage
i = integer representing a descriptor number.
s = string to notify to that descriptor.

Given a string i, and a descriptor number, will notify to that
descriptor directly.
descrnotify is an alias to notify_descriptor. Both of these will 
strip out any standad ANSI when notifying to descriptors that are not 
connected to a player, since there is no C flag to check for.

ansi_notify_descriptor works the same, except that it parses Neon ANSI,
just like ansi_notify.

~
STRENCRYPT

strencrypt ( s1 s2 -- s3 )
--------------------------
Level: M1 Apprentice
s1 = string containing message to encrypt.
s2 = string containing a 'key' to encrypt by.
s3 = Encrypted version of s1.

Given a string, and another string to act as the encoding key, 
will return an encoded string of jibberish.

See: STRDECRYPT
~
STRDECRYPT

strdecrypt ( s1 s2 -- s3 )
--------------------------
Level: M1 Apprentice
s1 = An encrypted string.
s2 = string containing the 'key' to decrypt by.
s3 = Decrypted version of s1 if the 'key' was valid.

Given an encoded string, will attempt to decide using the key given in 
s2. If the key is the same key that was used to encrypt the message
originally, will return the original, decoded message to the stack. If
the key is not the same key used to encrypt s1 originally, returns 
an inaccurate message to the stack.

See: STRENCRYPT
~
FILE PRIMS|FILE_PRIMS|FILEPRIMS

ProtoMUCK includes several MUF prims for working with files on the 
server. Due to the inherint risks associated with having this access
to the server, they should only be used with W4 level permissions.
In addition, by default, files may only be written to/read from the
directory set in config.h, or to certain files for which there are
shortcut tokens given. See SHORTCUTS for a list of the files and 
directories that can be accessed. Note that when file prims are used
in the secure mode, they will only work if the directories and location
of the MUCK are in the default arrangement that the MUCK comes in.

Note: File prims are a compile time option and may not actually be 
      present.

A list of the file prims:
FWRITE, FREAD, FREADN, FREADTO, FAPPEND, FCR - For use with characters.
BWRITE, BREAD, BAPPEND - For use with integer values for ASCII.
FPUBLISH, FSINFO, FSTATS, CURID, FSIZE, FNAME-OK? - Getting file/host information.
FRM, FREN - For moving/removing files.
GETDIR, MKDIR, RMDIR - For working with directories.
See: SHORTCUTS
~~~~~~
SHORTCUTS|FILE SHORTCUTS|FILESHORTCUTS|SHORTCUT|FILE SHORTCUT

The following tokens, when used in the file name for file prims, will
allow on to access otherwise secured directories and files:

$WELCOME.TXT      = data/welcome.txt
$WELCOME.HTML     = data/welcome.html
$NEWS.TXT         = data/news.txt
$MOTD.TXT         = data/motd.txt
$CONNECT.TXT      = data/connect.txt
$HELP.TXT         = data/help.txt
$MAN.TXT          = data/man.txt
$MPIHELP.TXT      = data/mpihelp.txt
$SYSPARMS.TXT     = data/sysparms.txt
$NEWS/            = data/news/
$HELP/            = data/help/
$INFO/            = data/info/
$MAN/             = data/man/
$MPIHELP/         = data/mpihelp/
$MUF/             = muf/
$WELCOME/         = data/welcome/
$PUBLIC_HTML/     = ../../public_html/
$WWW/             = ../../www/
$LOGS/            = logs/
See: FILE PRIMS
~
FWRITE

fwrite ( s1 s2 i1 -- i2 )
-------------------------
Level: W4 Boy
s1 = string to add to file.
s2 = string containing name of file to write to.
i1 = integer representing the offset.
i2 = integer representing successful write or not.
Writes contents of s1 to the file specified in s2, truncating the file 
to 0 bytes if it already exists, or creating it if it didn't.  The byte 
will be written at file offset i. Returns 1 on success, or 0 on a failure.

See FILE PRIMS, SHORTCUTS
~
FAPPEND

fappend ( s1 s2 -- i )
----------------------
Level: W4 Boy
s1 = string to add to end of a file.
s2 = string representing the name of the file to append to.
i  = integer representing a successful write or not.

  Writes the character specified in s1 to the file pointed to in
s2.  Unlike fwrite and bwrite, the byte is added to the end of the file, 
rather than truncating the file to 0, if it previously existed.  The 
offset is automatically set to the end of the file. Returns 1 on success, 
0 on failure.

See FILE PRIMS, SHORTCUTS
~
FREAD

fread ( s1 i -- s2 )
--------------------
Level: W4 Boy
s1 = string representing file name to read from.
i  = integer representing the offset from which to read in the character.
s2 = string containing a single character read in from the file.

  Reads in a single character from the file name pointed to by s1 at
an offset from the begining of the file of i. If the file does not exist, 
or the offset is out of range of the file, an empty string is returned
to the stack.

See: FILE PRIMS, SHORTCUTS
~
FREADN

freadn ( s1 i1 i2 -- s2 )
-------------------------
Level: W4 Boy
s1 = string representing file name to read from.
i1 = integer representing offset to start the read-in from.
i2 = integer representing the number of characters to read-in.
s2 = string containing the characters read in from s1.

Given a file in s1, an offset to start from i1, and a possitive
number of characters to read in from the file, i2, returns those
characters to the stack. If the file does not exist, or there is
a permissions error to read from it, it returns an empty string.
If the range of characters to be read in exceed the length of the
file, then it will read in characters up to the end of the file.

See: FILE PRIMS, SHORTCUTS
~~~
FPUBLISH

fpublish ( s -- i )
-----------------
Level: W4 Boy
s = string representing file name to change the mode on.
i = integer representing success or failure of file mode change.

Changes the mode on the given file to 744. This is the ideal mode
for publishing something on the web.
~
FCR

fcr ( s -- i )
--------------
Level: W4 Boy
s = string representing file name to append a '\r' character to.
i = integer representing a successful write.

Appends a '\r' character to the end of the given file name. Returns
a 1 if the write was successful, a 0 if unable to append the '\r'.
Reasons for failure to write include invalid directory, or restricted
directory permissions.

See: FILE PRIMS, SHORTCUTS
~
BREAD

bread ( s1 i1 -- i2 )
---------------------
Level: W4 Boy
s1 = string representing name of file to read from.
i1 = integer representing the offset to read from.
i2 = integer represeting result.

Given a filename in s1, and an offset in i1, returns the integer
value of the ASCII character at that location in the file. If the
character read in is the end of the file, EOF, -2 is returned. If
the file does not exist, or the offset is out of range of the file,
-1 is returned.

See: FILE PRIMS, SHORTCUTS
~
BWRITE

bwrite ( i1 s i2 -- i3 )
-----------------------
Level: W4 Boy
i1 = integer representing character to write.
s  = string representing filename to write to.
i2 = integer representing the offset to write at.
i3 = integer representing success or failure.

  Takes integers i1 and i2 and string s, whereas i1 is equal to an 
integer between 0 and 255 to be written tofile/path s at byte 
offset i2.  If the file does notexist, and no permissions errors 
occur, then the filewill be created.  Otherwise, an existing file 
will beedited.  Returns an integer that evaluates true if successful, 
false if not.

See: FILE PRIMS, SHORTCUTS
~
BAPPEND

bappend ( i1 s -- i2 )
----------------------
Level: W4 Boy
i1 = integer representing character to append.
s  = string representing name of file to append to.
i2 = integer representing success or failure.

  Takes integer i1 and string s, whereas i1 is an integer
of a value between 0 and 255 to be written to file/path s.
The value is written automatically to the end of s, and
subsequent calls will continue this effect.  It returns
an integer which evaluates true if the operation is
successful, otherwise false on an error.

See: FILE PRIMS, SHORTCUTS
~
FSINFO

fsinfo ( -- i1 .. i8 )
----------------------
Level: W4 Boy
i1 .. i8 = integers representing stats on the host system.

  Returns eight integers, whereas the integers contain the
following information about the host file system.
* i1 -- File System Magic Number
* i2 -- Total Blocks on File System
* i3 -- Total Blocks Free on File System
* i4 -- Total Blocks Available (to non super-user) on FS
* i5 -- Total Files/Inodes on File System
* i6 -- Total Files/Inodes Free on File System
* i7 -- Block Size of File System (in bytes)
* i8 -- Maximum Filename Length

See: FILE PRIMS
~
CURID

curid ( -- i1 i2 )
------------------
Level: W4 Boy
i1 and i2 = integers indicating group/user IDs.

  Returns two integers, whereas i1 is equal to the technical
group id (gid) of the MUCK, and i2 is equal to the user id
(uid) of the MUCK.

See: FILE PRIMS
~
FSTATS

fstats ( s -- i1 ... i6 )
-------------------------
Level: W4 Boy
s = string representing a file name.
i1 .. i6 = integers representing certain file stats.

  Takes a filename (optionally, with a path) as string s,
and returns six integers containing different pieces of
information about it.
* i1 -- Group id permissions of the file.
* i2 -- User id permissions of the file.
* i3 -- Time of the last recorded change.
* i4 -- Time of the last recorded access.
* i5 -- Time of the last recorded modification.
* i6 -- Inode number.
( i3, i4, and i5 are compatible with the timefmt prim. )

See: FILE PRIMS, SHORTCUTS
~
FSIZE

fsize ( s -- i )
----------------
Level: W4 Boy
s = string representing file name.
i = integer representing the size in bytes.

  Takes a file/pathname as string s, and returns i, which
is equal to the last byte position in the file.  (ie; It
is equal to the file size of s.) Returns -1 if the file
does not exist.

See: FILE PRIMS, SHORTCUTS
~
FRM

frm ( s -- i )
--------------
Level: W4 Boy
s = string representing file name to remove.
i = integer representing success or failure. 0 indicates success.

Given a filename on the server, removes that file. If the file was
removed fine, then a 0 is returned to the stack. If the file did 
not exist, or there was some other error, then -1 is returned to the
stack. If there is another link to that file, then the file will still 
exist and be accesible through that link. If no other link exists to 
the file, then the file will be removed as well. In addition, if another 
program or process is accessing the file, then deletion is postponed
until that other process stops working with the file. 

See: FILE PRIMS, SHORTCUTS
~
FREN

fren ( s1 s2 -- i )
-------------------
Level: W4 Boy
s1 = string representing original file name.
s2 = string representing the new file name.
i  = integer representing success or failure.

Given a file name in s1, renames it to s2. This includes moving it to
other directories on the same volume. If a file already exists at 
location s2, it will be overwritten. If the rename attempt is 
finished successfully, 0 is returned to the stack, otherwise -1.

See: FILE PRIMS, SHORTCUTS
~~~~
FNAME-OK?

fname-ok? ( s -- i )
--------------------
Level: W4 Boy
s = Any non-empty string.
i = integer indicating if the string is a valid file prim shortcut or not.

Given a string, checks to see if the string forms a valid file shortcut
to use with the file prims. If not, returns 0, if it is, it returns a 1.

See: FILE PRIMS, SHORTCUTS
~~~~
++|--

++ and -- ( x -- x' )
---------------------
Level: M1 Apprentice
x  = dbref, int, float, or variable containing such.
x' = Value of x, incremented or decremented by one

Given a float, integer, dbref, or a variable that contains 
any of those three data types, ++ will increment it by one, and 
-- will decrement it by one. If the value is stored in a 
variable, the result is returned to the variable, replacing the
old value.
~
CEIL

ceil ( f1  -- f2 )
------------------
Level: M1 Apprentice
f1 = Any float.
f2 = float representing the next highest integer after f1.

Given a float value, f1, rounds up to the next highest integer 
value and returns it as a floating point type.

See: FLOAT PRIMS
~
FLOOR

floor ( f1 -- f2 )
------------------
f1 = Any float.
f2 = float representing the next lowest integer under f1.

Given a float value, f1, rounds down to the next lowest integer
value and returns it as a floating point type.

See: FLOAT PRIMS
~
SQRT

sqrt ( n -- f )
---------------
Level: M1 Apprentice
n = Any possitive, non-zero integer or float.
f = The square root of n2 returned as a float.

Given a possitive number, returns that number's square root.

See: FLOAT PRIMS
~
PI

pi ( -- f )
-----------
Level: M1 Apprentice
f = float representing the value of pi.

Returns the value of PI.

See: FLOAT PRIMS
~
ROUND

round ( f1 i -- f2 )
--------------------
Level: M1 Apprentice
f1 = Any float.
i  = integer indicating how precise the rounded number is to be.
f2 = The rounded result of f1 returned as a float.

Given a floating point value in f1, and an integer, i, that is 
greater than zero, it returns the value of f1 rounded to the 
decimal place indicated by integer i.

See: FLOAT PRIMS
~
SIN|COS|TAN

sin cos tan ( n -- f )
----------------------
Level: M1 Apprentice
n = Any number between -PI/4 and PI/4
f = The sine, cosine, or tangent of that number.

Given a number, returns the sine, cosine, or tangent of that 
number. Only operates within the ranges of -PI/4 and PI/4.

See: FLOAT PRIMS
~
ASIN|ACOS|ATAN

asin acos atan ( n -- f )
-------------------------
Level: M1 Apprentice
n = Any number between -PI/4 and PI/4
f = The inverse sine, inverse cosine, or inverse tangent of n.

Given a number, returns the inverse sine, inverse cosine, or
inverse tangent of that number. Only operates within the ranges
of -PI/4 and PI/4.

See: FLOAT PRIMS, ATAN2
~
ATAN2

atan2 ( ny nx -- f )
--------------------
Level: M1 Apprentice
ny and nx = Numbers.
f = float representing the result.

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

See: FLOAT PRIMS
~~~~
KAERU

kaeru ( d i s1 -- i ) 
--------------------- 
Level: W6 Frog

Takes dbref, integer, and string and will return 0 if Kaeru is idle. 
It theoretically returns 1 if Kaeru is unidle, but that has yet to 
happen.
~~~~
DIST3D

dist3D ( nx ny nz -- f )
------------------------
nx ny nz = 3 numbers representing a 3d coordinate.
f = float representing those coordinate's distance from the origin.

Returns the distance of the XYZ coordinate (fx,fy,fz) from the origin.

See: FLOAT PRIMS
~
XYZ_TO_POLAR

xyz_to_polar ( nx ny nz -- fr ft fp )
-------------------------------------
Level: M1 Apprentice
nx ny nz = Any 3 numbers representing a 3d coordinate.
fr ft fp = float polar coordinates.

Converts the XYZ coordinate (nx, ny, nz) 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)

See: FLOAT PRIMS
~
POLAR_TO_XYZ

polar_to_xyz ( nr nt np -- fx fy fz )
-------------------------------------
Level: M1 Apprentice
nr nt np = Numbers representing polar coordinates.
fx fy fz = floats representing 3d coordinate positions.

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)

See: FLOAT PRIMS
~
EXP
exp ( n -- f )
--------------
Level: M1 Apprentice
n = A number.
f = float representing the result.

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

See: FLOAT PRIMS
~
LOG

log ( n -- f )
--------------
Level: M1 Apprentice
n = A possitive number.
f = float representing result.

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

See: FLOAT PRIMS
~
LOG10

log10 ( n -- f )
----------------
Level: M1 Apprentice
n = A possitve number.
f = float representing the result.

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

See: FLOAT PRIMS
~
FABS

fabs ( n -- f )
---------------
Level: M1 Apprentice
n = Any number.
f = float representing the result.

Returns the absolute value of the number n.

See: FLOAT PRIMS
~
FLOAT

float ( i -- f )
----------------
Level: M1 Apprentice
i = Any integer.
f = float representing the float value of integer i.

Converts integer to floating point type.

See: FLOAT PRIMS
~
POW

pow ( n1 n2 -- f )
------------------
Level: M1 Apprentice
n1 = Number representing the base.
n2 = Number representing the exponent.
f  = float representing the result. 

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

See: FLOAT PRIMS
~
FRAND

frand ( -- f )
--------------
Level: M1 Apprentice
f = Random float.

Returns a random floating point number between 0 and 1.

See: FLOAT PRIMS
~
FMOD
fmod ( n1 n2 -- f )
-------------------
Level: M1 Apprentice
n1 and n2 = Any numbers.
f = float representing the result.

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

See: FLOAT PRIMS
~~~~
MODF

modf ( f1 -- f1' f2' )
----------------------
Level: M1 Apprentice
n1 = Any number.
f1 = integer part of n1.
f2 = fractional part of n1.

Returns the integral and fractional parts of f1, both as floats. 

See: FLOAT PRIMS
~
STRTOF

strtof ( s - f )
----------------
Level: M1 Apprentice
s = string to convert to a float.
f = float result.

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.

See: FLOAT PRIMS, FTOSTR
~
FTOSTR

ftostr ( f -- s )
-----------------
f = A float.
s = string containing the float.

Converts a floating point number into a string.  Always includes the decimal
point.  FTOSTR can return either the xxx.yyy form or the x.yyyEzz form of
a float, depending on which would give the shortest string length.

See FLOAT PRIMS, FMTSTRING
~
FLOAT?

float? ( x -- i )
-----------------
Level: M1 Apprentice
x = Anything on the stack.
i = integer indicating true or false.

Returns 1 if the object at the top of the stack is a float, otherwise 
returns 0.
~~~~~
ERROR DEFS|ERR_DIVZERO?|ERR_NAN?|ERR_IMAGINARY?|ERR_FBOUNDS?|ERR_IBOUNDS

err_divzero? err_nan? err_imaginary? err_fbounds? err_ibounds? ( -- i )
-----------------------------------------------------------------------
Level: M1 Apprentice
i = integer representing true or false result.
Convenience macros defined as the following:

Added an ERR_DIVZERO?    = 0 is_set?
Added an ERR_NAN?        = 1 is_set?
Added an ERR_IMAGINARY?  = 2 is_set?
Added an ERR_FBOUNDS?    = 3 is_set?
Added an ERR_IBOUNDS?    = 4 is_set?

See: FLOAT PRIMS
~~~~~
FLOAT PRIMS|FLOAT-PRIMS|FLOAT_PRIMS

ProtoMUCK includes the ability to handle floating point (decimal) math.
It is derived from the float point support of FB6. This powerful tool
allows programs to handle numbers that may not be whole integers.

The math prims, + - * etc., have been modified to work with float
numbers just as well as the integers they have always worked with. Also,
the float prims have been modified to accept, where appropriate, integers
as arguements. 

Below is a list of float prims supported by ProtoMUCK:

INF, CEIL, FLOOR, SQRT, PI, ROUND, SIN, COS, TAN, ASIN, ACOS, ATAN, ATAN2
DIST3D, XYZ_TO_POLAR, POLAR_TO_XYZ, EXP, LOG, LOG10, FABS, FLOAT, POW
FRAND, FMOD, MODF, STRTOF, FTOSTR, FLOAT?

FLOAT ERRORS PRIMS: CLEAR, ERROR_NUM, CLEAR_ERROR, SET_ERROR, IS_SET?
                    ERROR_STR, ERROR_NAME, ERROR_BIT, ERROR?

See: Individual entries for more details. ERROR? for float error help.
~~~~~
ARRAY PRIMS|ARRAYS|ARRAY

First appearing in FB6, array support in MUF provides the user with 
a number of shortcuts when it comes to filtering through data, 
notifying dbrefs, and a number of other time saving techniques. 

Each array is a series of elements (referred to as 'items' in some
of the man entries). Each element contains an 'index' and a 'value'.
The index is the name or number by which each element is referred, and
value is the actual contents of the element. 

There are two types of arrays, each serving a specific purpose:
List Arrays: Often referred to as simply 'arrays' in the manual entries.
             The index values are server defined (a sequence of numbers
             starting from 0), and the element values are what are 
             manipulated by the user. Certain array prims will only 
             work with list arrays.

Dictionary Arrays: Often referred to simply as 'dictionarys' in the manual
             entries. With these, both the index values and element values
             are user defined. Index values may be an integer or a string.
             Certain array prims will only work with dictionary arrays.

See: ARRAYS2
~~~~
ARRAYS2|ARRAY2

The following ARRAY prims are available:
ARRAY_MAKE           ARRAY_MAKE_DICT      }DICT              }LIST
ARRAY_EXPLODE        ARRAY_VALS           ARRAY_KEYS         ARRAY_COUNT  
ARRAY_FIRST          ARRAY_LAST           ARRAY_PREV         ARRAY_NEXT
ARRAY_GETITEM        ARRAY_SETITEM        ARRAY_APPENDITEM   ARRAY_SORT
ARRAY_GETRANGE       ARRAY_SETRANGE       ARRAY_INSERTRANGE  ARRAY?
ARRAY_DELITEM        ARRAY_DELRANGE       ARRAY_NUNION       ARRAY_UNION
ARRAY_NINTERSECT     ARRAY_INTERSECT      ARRAY_NDIFF        ARRAY_DIFF
ARRAY_NOTIFY         ARRAY_REVERSE        DESCR_ARRAY        DICTIONARY?
ARRAY_GET_PROPDIRS   ARRAY_GET_PROPVALS   ARRAY_PUT_PROPVALS }JOIN
ARRAY_GET_PROPLIST   ARRAY_PUT_PROPLIST   ARRAY_INSERTITEM
ARRAY_GET_REFLIST    ARRAY_PUT_REFLIST    ARRAY_FINDVAL
ARRAY_INSERTITEM     ONLINE_ARRAY         ARRAY_EXCLUDEVAL
ARRAY_ANSI_NOTIFY    ARRAY_NOTIFY_HTML    ARRAY_JOIN         ARRAY_MATCHKEY
ARRAY_MATCHVAL       ARRAY_EXTRACT        ARRAY_FILTER_PROP  CONTENTS_ARRAY
EXITS_ARRAY          GETOBJINFO           GETDESCRINFO       FIND_ARRAY
ARRAY_CUT            ARRAY_COMPARE        ARRAY_SORT_INDEXED
ARRAY_SUM            ARRAY_STRING_FRAGMENT

See: Individual entries for more information.
~~~~~~
STACKRANGE|STACKCOUNT

Stackrange:  {?} or {@ ?}
With reference to the array prims, a stackrange is defined as any number
of objects on the stack, with their count at the top of the stack. For
example:

"a" "b" "c" "d" "e" 5   

would be a valid stackrange of 5 objects. The objects on the stack do not
all have to be of the same data type:

"a" 5.3 #532 3

would be a valid stackrange of 3 objects. However, some of the array
prims require that the array contain all of a certain kind of data type.
The integer on the top of the stack is referred to as the stackcount, and
must not be negative, nor a higher number than the current depth of the 
stack.

See: STACKRANGE2, ARRAY PRIMS
~
STACKRANGE2

Stackranges represented as {?} in the MUF manual indicate that 
everything in the stack is an element value, and the stackcount is
an accurate count of the number of objects in the stack. 

{?} = "a" "b" "c" "d" 4

Stackranges represented as {@ ?} in the MUF manual indicate that
the stack consists of pairs of index values and element values, so
the stackcount is actually half the depth of the actual portion of
the stack in question.

{@ ?} "a" 4.0 "b" 3.0 "c" 2.0 "d" 1.0 4

Where the strings are the values assigned to the index values, and
the floats would be assigned to the element values. Again, the index
values and element values can be of any data type. 

See: STACKRANGES3, ARRAY PRIMS
~
STACKRANGE3|MARK|}|{

ProtoMUCK includes two important tools for making it easy to form valid
stackranges. The first is the MARK. This is written into MUF as a {, and
appears on the stack in debug mode as MARK and can be manipulated like
any other data type. 

The second is an actual prim that closes the stackrange, }. This searches
down the depth of the stack until it finds a MARK, removes the MARK from
the stack, and returns the total number of data objects between the two 
points. For example:
{ "a" "b" "c" "d" "e" "f" } would return "a" "b" "c" "d" "e" "f" 6

Something like:
{ #1 #3 #5 #6 #7 } array_make
would be an example of how to make a quick array that contains those
dbref numbers.

See: ARRAY PRIMS
~
}DICT|}LIST|}JOIN|}ARRAY
------------
}dict ( { x1 x2 x3 ... xn -- dict )
}list ( { x1 x2 x3 ... xn -- array )
}join ( { s1 s2 s3 ... xn -- s4 )
--------------------------------------
Level: M1 Apprentice
{  = The opening stack marker.
x1 ... xn = A range of items on the stack.
dict = A dictionary array.
array = A list array.
s4 = A string of the concated values s1 through sn

These are all in-server $defines for:
} array_make
} 2 / array_make_dict
} array_make "" array_join

}array is another name for }list.

See: ARRAY PRIMS
~~~
ARRAY_MAKE

array_make ( {?} -- a )
-----------------------
Level: M1 apprentice
{?} = Any stackrange.
a   = array representing the contents of the stackrange.

Given a valid stackrange, returns an array containing the contents of
the stackrange. 

See: ARRAY PRIMS, STACKRANGE
~
ARRAY_MAKE_DICT

array_make_dict ( {@ ?} -- a )
------------------------------
Level: M1 Apprentice
{@ ? } = stackrange of index values and element values.
a      = Dictionary style array.

Given a stack range of index values and element values, creates
an array consisting of those. For more on the difference between
arrays and dictionary form arrays, see ARRAY PRIMS.

See: ARRAY PRIMS, STACKRANGE
~
ARRAY_EXPLODE

array_explode ( a -- {@ ?} )
----------------------------
Level: M1 Apprentice
{@ ?} = stackrange of index values and element values.
a     = Any array.

Explodes an array into a stackrange of its index/value pairs.
    Example:  "idx0" "val0" "idx1" "val1" 2


See: ARRAY PRIMS, STACKRANGE, ARRAY_VALS, ARRAY_KEYS
~
ARRAY_VALS

array_vals ( a -- {?} )
-----------------------
Level: M1 Apprentice
a   = Any array.
{?} = stackrange representing the element values of the array.

Returns the values of an array in a stackrange.
    Example: "val0" "val1" 2

See: ARRAY PRIMS, STACKRANGE, ARRAY_EXPLODE, ARRAY_KEYS
~
ARRAY_KEYS

array_keys ( a -- {@} )
-----------------------
Level: M1 Apprentice
a   = Any array.
{@} = strackrange representing the index values of the array.

Returns the keys of an array in a stackrange.
    Example:  "idx0" "idx1" 2 

See: ARRAY PRIMS, STACKRANGE, ARRAY_VALS, ARRAY_EXPLODE
~
ARRAY_COUNT

array_count( a -- i )
---------------------
Level: M1 Apprentice
a = An array.
i = integer representing the size of the array.

Returns an integer representing the number of items in an
array. Note that an item includes an index value and an
element value.
~
ARRAY_FIRST
array_first ( a -- @ i )
------------------------
Level: M1 Apprentice
a = An array.
@ = Index value for the first item in the array.
i = integer representing empty or not.

Returns the first index value in array, and an integer which is 0
if there are no items are in the array, otherwise 1.

See: ARRAY PRIMS, ARRAY_NEXT, ARRAY_PREV, ARRAY_LAST
~
ARRAY_LAST

array_last ( a -- @ i )
-----------------------
Level: M1 Apprentice
a = An array.
@ = Index value for the last item in the array.
i = integer representing empty or not.

Returns the last index value in the array, and an integer which is 0
if there are no items in the array, otherwise is 1.

See: ARRAY PRIMS, ARRAY_PREV, ARRAY_FIRST, ARRAY_NEXT
~
ARRAY_PREV

array_prev( a @ -- @' i )
-------------------------
Level: M1 Apprentice
a  = An array.
@  = An index marker in that array.
@' = The previous index marker from @.
i  = integer indicating beginning of array or not.

Given an array, and an index value of that array, returns the
index marker of the previous item in the array and an integer.
If @ was the beginning of the array, or the array is empty, the
integer will be 0, otherwise will be 1.

See: ARRAY PRIMS, ARRAY_PREV, ARRAY_FIRST, ARRAY_NEXT
~~~~
ARRAY_NEXT

array_next( a @ -- @' i )
-------------------------
Level: M1 Apprentice
a  = An array.
@  = An index marker in that array.
@' = The next index marker after @.
i  = integer indicating beginning of array or not.

Given an array, and an index value of that array, returns the
index marker of the next item in the array and an integer.
If @ was the end of the array, or the array is empty, the
integer and index marker will be 0, otherwise will be 1. 

See: ARRAY PRIMS, ARRAY_PREV, ARRAY_FIRST, ARRAY_NEXT
~~~~
ARRAY_GETITEM|[]

array_getitem( a @ -- x )	[]
-------------------------
Level: M1 Apprentice
a = An array.
@ = An index marker in that array.
x = The contents of that item in the array.

Given an array, and an index marker in that array, returns
the contents of that item pointed to by the index marker. 
If the index marker is out of range for the array, 0 is returned.

array_getitem can be shortcutted to []

See: ARRAY PRIMS, ARRAY_SETITEM
~
ARRAY_SETITEM|->[]

array_setitem( x a @ -- a' )	->[]
----------------------------
Level: M1 Apprentice
x  = Any data type on the stack.
a  = An array.
@  = An index marker.
a' = An array with a new item value, x, at location @.

Given an item on the stack, an array, and an index marker that
points to a location in the array, will set the value to the 
element indicated by the index marker to x. The program will
abort if the index marker is out of range of array a.

array_setitem can be shortcutted to ->[]

See: ARRAY PRIMS, ARRAY_GETITEM
~
ARRAY_APPENDITEM|[]<-

array_appenditem( x a -- a' )	[]<-
-----------------------------
Level: M1 Apprentice
x  = Any data type on the stack.
a  = An array.
a' = Changed array.

Given an array, and a data object on the stack, appends a new
element onto the end of the array containing object x.

array_appenditem can be shortcutted to []<-

See: ARRAY PRIMS
~
ARRAY_INSERTITEM

array_insertitem ( x a @ -- a' )	[^]
--------------------------------
Level: M1 Apprentice
x  = Any data type on the stack.
a  = An array.
@  = Index marker within range for array a.
a' = Changed array.

Given an item (x) on the stack, an array and an index number in
the range 0 through array_count + 1, inserts the contents of x
into the array before the index marker given. Program aborts if
the index marker is out of range.

array_insertitem can be shortcutted to [^]

See: ARRAY PRIMS
~
ARRAY_GETRANGE

array_getrange( a @ @2 -- a2 )	[..]
------------------------------
Level: M1 Apprentice
a  = An array.
@  = An index marker indicating where to start the new array.
@2 = An index marker indicating where to end the new array.
a2 = A new array.

Given an array, and two valid index markers for the array, returns
an array consisting of the elements of array a that were between
@ and @2, as well as elements @ and @2 themselves. 

array_getrange can be shorcutted to [..]

See: ARRAY PRIMS
~
ARRAY_SETRANGE

array_setrange( a1 @ a2 -- a3 )
-------------------------------
a1 = An array.
@  = Index marker for array a1.
a2 = Array to copy into array a1.
a3 = Array a1 with changed contents.

Given an array, a1, a valid index marker for a1, and a second array, a2,
copies the contents of a2 into a1, starting at the element pointed to
by the index marker, overwritting the existing values of the items in
a1. If a2 extends past the end boundary of a1, then array_setrange will 
append the rest of a2 to the end of a1.

See: ARRAY PRIMS
~
ARRAY_INSERTRANGE

array_insertrange( a1 @ a2 -- a3 )
----------------------------------
Level: M1 apprentice
a1 = An array.
@  = A valid index marker for a1.
a2 = A second array to insert into a1.
a3 = Array a1 with a2 inserted at @.

Given an array, a1, a valid index marker for a1, and a second array, a2,
inserts the contents of a2 into a1 beginning after the index marker. 

See: ARRAY PRIMS
~
ARRAY_DELITEM

array_delitem( a @ -- a' )
--------------------------
Level: M1 Apprentice
a  = An array.
@  = A valid index marker for array a1.
a' = array a1, minus the deleted item.

Given an array, a1, and a valid index marker for a1, will remove the
element pointed to by the index marker and return the array. The program
will abort if the index marker is out of range for a1.

See: ARRAY PRIMS, ARRAY_DELRANGE
~
ARRAY_DELRANGE

array_delrange( a @1 @2 -- a' )
-------------------------------
Level: M1 Apprentice
a  = An array.
@1 = Index marker indicating starting position to delete from.
@2 = Index marker indicating ending position to delete to.
a' = array a1, minus the range of elements deleted.

Given an array, and two valid index markers, will remove all of
the elements between the two markers, and the elements they point
to as well. 

See: ARRAY PRIMS, ARRAY_DELITEM
~
ARRAY_NUNION

array_nunion( {a} -- a )
------------------------
Level: M1 Apprentice
{a} = A stackrange of all arrays
a   = An array containing a union of all the arrays in the stackrange.

Given a stackrange of strictly arrays, it returns an array that 
contains a union of all of the arrays. A union is a set of data where
every element in any of the seperate arrays can appear once, and only
once. For example:
{"a" "b" } { "b" "c" "d" } { "d" "e" "f" } -> { "a" "b" "c" "d" "e" "f" }

See: ARRAY PRIMS, STACKRANGE, ARRAY_NINTERSECT, ARRAY_NDIFF
     ARRAY_UNION
~
ARRAY_NINTERSECT

array_nintersect( {a} -- a )
----------------------------
Level: M1 Apprentice
{a} = A stackrange of all arrays
a   = An array containing an intersection of all the arrays in stackrange.

Given a stackrange of strictly arrays, it returns an array that 
contains an intersection of all the arrays. An intersection is a set
of data that represents which elements were common to all of the arrays
checked. For example:
{"a" "b" "c"} { "b" "c" "d" } { "d" "e"} -> { "b" "c" }

See: ARRAY PRIMS, STACKRANGE, ARRAY_NUNION, ARRAY_NDIFF
     ARRAY_INTERSECT
~
ARRAY_NDIFF

array_ndiff( {a} -- a )
-----------------------
Level: M1 Apprentice
{a} = A stackrange of all arrays.
a   = An array containing the differences of all the arrays in stackrange.

Given a stackrange of strictly arrays, it returns an array that 
contains all of the elements that were different from array to the 
next. Multiple arrays are processed against the results of the
previous difference from the top of the stack down.

{ "a" "b" "c" } { "c" "e" "f" } -> { "e" "f" }

See: ARRAY PRIMS, STACKRANGE, ARRAY_NUNION, ARRAY_NINTERSECT
     ARRAY_DIFF
~
ARRAY_NOTIFY|ARRAY_ANSI_NOTIFY|ARRAY_NOTIFY_HTML

array_notify( a1 a2 -- )
array_ansi_notify( a1 a2 -- )
array_notify_html( a1 a2 -- )
-----------------------------
Level: M1 Apprentice
a1 = An array of all strings.
a2 = An array of all dbref numbers.

Notifies all of the dbref objects in a2 the entire contents of
a1. Will notify to rooms and players, and can be picked up by
listen props. However, ZOMBIE objects do not seem to get notified.
Will still name append messages for M1 if the @tune is set to 
require that. The ANSI and HTML versions work just the same, except
for handling ANSI and HTML sending as well.

See: ARRAY PRIMS
~
ARRAY_REVERSE

array_reverse( a -- a' )
------------------------
Level: M1 Apprentice
a  =An array.
a' =Same array, contents reversed.

Given an array, reverses the order of the elements, and returns it.
For example:
{ "a" "b" "c" } -> ( "c" "b" "a" }

See: ARRAY PRIMS
~
ARRAY_GET_PROPDIRS

array_get_propdirs( d s -- a )
------------------------------
Level: M3 Master
d = Any valid dbref.
s = string representing where to start reading in propdirs.
a = array with strings representing every propdir at that level.

Given a valid dbref, and a string representing the point at which to
start, it reads in all the propdirs at that level into an array, in
alphabetical order. It skips props that are not prop dirs, only storing
the name of the propdir from that level. For example, given the following
props to read:
prop:TestProp
_prop/prop2:TestProp
prop3/prop4/prop5:testProp
Using the string "/" would return { "_prop" "prop3" }
Using the string "prop/" would return an empty array.
Using the string "prop3/" would return { "prop4" }

See: ARRAY PRIMS
~
ARRAY_GET_PROPVALS

array_get_propvals( d s -- a )
------------------------------
Level: M3 Master
d = Any valid dbref.
s = String representing directory to read from.
a = array containing the propvals for all the props under that propdir.

Given a valid dbref, and a string that represents the directory from
which to read the property values in from, it will read the value of
every property under that directory into an array, regardless of
property type. The index markers will all be set to strings that are
the immediate prop that the value was stored on. For example:

For a prop that was _prefs/logintime?:yes when read in by this prim
would be saved to an element in the array with the index marker of
"logintime?" and a value of "yes".

See: ARRAY PRIMS, ARRAY_GET_PROPLIST
~
ARRAY_GET_PROPLIST

array_get_proplist( d s -- a )
------------------------------
d = Any valid dbref.
s = string representing the lsedit list to read from.
a = array containing the propvals for all the props under that propdir.

Given a valid dbref, and a string that represents the property list to
read from, this prim will read the lsedit list into a string array.
The lsedit list name, s, need not end with the # mark. Thus
"somelist" 
and 
"somelist#" 
will both be able to retrieve the lsedit list under 'somelist#'. 

See: ARRAY PRIMS, ARRAY_GET_PROPVALS, ARRAY_PUT_PROPLIST
~
ARRAY_PUT_PROPVALS

array_put_propvals( d s a -- )
------------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the directory to save to.
a = array to save to props.

Given a valid dbref, and a string to use as the directory to write to,
will write out the contents of the array. The properties will be named
according to the value of each index marker, and the property value
will be whatever was stored in the element pointed to by the index marker.
If the index markers are integers, they will be converted to ints for
the purpose of naming the prop. For example:
If an element has an index marker of "prefs" and a value of "off", and are
being stored to a directory  called "config/" the prop will be written out
as:
config/prefs:off

See: ARRAY PRIMS, ARRAY_PUT_PROPLIST
~~
ARRAY_PUT_REFLIST

array_put_reflist( d s a -- )
-----------------------------
Level: M1 Apprentice
d = dbref of object to put the list on.
s = string representing the name of the prop to put list on.
a = list style array containing dbrefs as the values.

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

See: ARRAY PRIMS, ARRAY_GET_REFLIST
~~~
ARRAY_GET_REFLIST

array_get_reflist ( d s -- a )
------------------------------
Level: M1 Apprentice
d = dbref of object to get list from.
s = string representing the name of the prop to get list from.
a = List style array containing dbrefs as the values.

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

See: ARRAY_PUT_REFLIST 
~~~~~
OBJMEM

objmem ( d -- i )
-----------------
Level: M1 Apprentice
d = Any dbref between #0 and dbtop.
i = integer represeting size of that object in the data base.

Used to return how much memory a dbref entry is taking up.
~~
LDUP

ldup ( {?} -- {?} {?} )
-----------------------
Level: M1 Apprentice
{?} = Any stackrange.

Given a valid stackrange, duplicates the stackrange on the stack.

See: STACKRANGE
~
DUPN

dupn(xn...x1 i -- xn...x1 xn...xi )
-----------------------------------
Level: M1 Apprentice
xn...x1 = Any range of objects on the stack.
i = integer representing the number of items to dup.

Given a count, duplicates that many objects on the top of the stack. 
If i exceeds the depth of the stack, the program will abort.
~~~
LREVERSE

lreverse(xn...x1 i -- x1...xn i )
---------------------------------
Level: M1 Apprentice
xn...x1 = Any range of objects on the stack.
i = integer representing the number of objects to reverse.

Reverses the top i objects on the stack, leaving the stackcount on
the stack afterwards. 

See: REVERSE
~~~
REVERSE

reverse(xn...x1 i -- x1...xn )
------------------------------
Level: M1 Apprentice
xn...x1 = Any range of objects on the stack.
i = integer representing the number of objects to reverse.

Reverses the top i objects on the stack.

See: LREVERSE
~
ARRAY?

array?( x -- i )
----------------
Level: M1 Apprentice
x = Any data object on the stack.
i = integer representing true or false.

Returns 1 if the item on the top of the stack is an array.

See: DICTIONARY?
~~
DICTIONARY?

dictionary?( x -- i )
---------------------
Level: M1 Apprentice
x = Any data object on the stack.
i = integer representing true or false.

Returns 1 if the item on the top of the stack is a
dictionary style array.

See: ARRAY PRIMS, ARRAY?
}DICT

}dict ( mark @n ?n ... @1 ?1 -- dict )
--------------------------------------
Level: M1 Apprentice
mark = A stack marker.
@n ?n ... @1 ?i = A set of index values and array values.
dict = A dictionary style array.

This takes all the pairs of names (@s) and values (?s) between the
top of the stack and the topmost stack marker, and makes them into
a dictionary, a la the array_make_dict primitive.  In fact, this is
implemented as an inserver macro with a definition of
 '} 2 / array_make_dict'.

See: ARRAY PRIMS
~
}LIST

}list ( mark ?n ... ?i -- array )
---------------------------------
Level: M1 Apprentice
mark = A stack marker
?n ... ?i -- A range of objects on the stack to make into an array.
array = A list style array.

This takes all the stack items above the topmost stack marker, and 
makes a list from them, a la array_make.  In fact, this is
implemented as an inserver macro with a definition of '} array_make'.

See: ARRAY PRIMS
~~~~
ARRAY_DIFF|ARRAY_UNION|ARRAY_INTERSECT

array_diff array_union array_intersect ( a1 a2 -- a3 )
------------------------------------------------------
Level: M1 Apprentice
a1 a2 = 2 arrays to perform operations on.
a3    = array containing the result of the operations.

Inserver definitions for:

array_diff       = 2 array_ndiff
array_union      = 2 array_nunion
array_intersect  = 2 array_nintersect

See: ARRAY_NDIFF, ARRAY_NUNION, ARRAY_NINTERSECT, ARRAY PRIMS
~~~~
~~~~
CLEAR

clear ( -- )
------------
Level: M1 Apprentice

Clears all error flags for floating point math operations.

See: FLOAT ERRORS, FLOAT PRIMS
~~
ERROR_NUM

error_num ( -- i )
------------------
Level: M1 Apprentice
i = integer representing total float math error types.

Returns the total number of floating point error flag types.

See: FLOAT PRIMS, FLOAT ERRORS4
~~
CLEAR_ERROR

clear_error( s|i -- i )
-----------------------
Level: M1 Apprentice
s|i = string or integer representing a specific flag to reset.
i = Integer indicating valid error flag or not.

Clears a specific error flag for floating point math operations.
If the integer or string is not a valid flag, returns 0 to the stack, otherwise 1.

See: FLOAT PRIMS, FLOAT ERRORS
~~~
SET_ERROR
set_error ( s|i -- i )
----------------------
Level: M1 Apprentice
s|i = string or integer representing a specific error flag to set.
i   = integer representing result.

Sets the specified error flag for floating point operations.
If the flag given was invalid, return 0, otherwise returns 1.

See also FLOAT PRIMS, FLOAT ERRORS
~~~~
IS_SET?

is_set? ( s|i -- i )
--------------------
Level: M1 Apprentice
s|i = A string or integer represnting a float error.
i   = An integer representing true or false.

Given a valid error code for float math, returns 1 if that error
flag has been set, otherwise 0.

See: FLOAT PRIMS, FLOAT ERRORS
~~
ERROR_STR

error_str (s|i -- s )
---------------------
Level: M1 Apprentice
s|i = A valid integer or string representing a float math error.
s   = string containing a user readable description of the float error.

Given a valid error flag, returns a string representing the float 
error type. If given an invalid flag to convert, returns an empty string.

See: FLOAT PRIMS, FLOAT ERRORS
~
ERROR_NAME

error_name ( i -- s )
---------------------
Level: M1 Apprentice
i = integer representing an error flag.
s = string containing the name for that error flag.

Returns the string name for the error flag, given a floating
point error. If the integer is not a valid error flag, it returns
an empty string.

See: FLOAT PRIMS, FLOAT ERRORS
~
ERROR_BIT

error_bit ( s -- i )
--------------------
Level: M1 Apprentice
s = string containing a float error flag name.
i = integer representing the float error.

Converts a valid error flag into the integer representing that float
error bit. If the flag given was invalid, -1 is returned.

See: FLOAT PRIMS, FLOAT ERRORS
~
ERROR?|FLOAT ERRORS|FLOATERRORS|ERRORS

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.

See: FLOAT PRIMS
~~~~~
ISLOCKED?

islocked? ( d1 d2 s -- i )
--------------------------
Level: M1 Apprentice
d1 = dbref of a player or thing.
d2 = dbref of object that has the lock.
s  = prop that contains the lock.
i  = integer representing result.

Given a player or thing in d1, and an object in d2, checks the prop
s for a lock. Will run all the same checks that LOCKED? will, except
that it will not run any MUF programs called from the @lock. If the
player or thing does not pass the lock, then 1 is returned to the
stack. If d1 passes the lock, or there is no lock, then 0 is 
returned to the stack.

See: TESTLOCK, LOCKED?, CHECKLOCK
~~
PROPQUEUE

propqueue ( d1 s1 d2 s2 -- )
----------------------------
Level: W3 ArchWizard
d1 = The trigger dbref.
s1 = string containing the property name for the propqueue.
d2 = dbref of object to find the propqueue on.
s2 = string representing initial arguements for programs called.

Runs the contents of a propqueue just like the normal inserver 
propqueues. d1 is the value to be placed in the trigger variable,
s1 is the name of the propqueue, d2 is the dbref object that 
holds the propqueue, and s2 is the string that will be the initial
arguement of each MUF program called in the propqueue.
Given this information, the program will run down the contents
of the propqueue, running any MUF programs or parsing any MPI
as appropriate, just like the in-server propqueues such as 
_listen and _connect, allowing programmers to create their own
propqueues.

See: ENVPROPQUEUE, PROPQUEUES
~~~~
ENVPROPQUEUE

envpropqueue( d1 s2 d2 s2 -- )
------------------------------
Level: W3 ArchWizard
d1 = Trigger dbref.
s2 = string containing propqueue name.
d2 = dbref of object to start searching up the environment tree from.
s2 = string containing initial arguement for any MUFs called.

Runs the contents of a propqueue just like the normal inserver 
propqueues. d1 is the value to be placed in the trigger variable,
s1 is the name of the propqueue, d2 is the dbref of where the 
program should start searching up the environment tree from, and 
s2 is the string that will be the initial arguement of each MUF 
program called in the propqueue. Given this information, the program 
will run down the contents of the propqueue, running any MUF programs 
or parsing any MPI as appropriate, just like the in-server propqueues 
such as _listen and _connect, allowing programmers to create their own
propqueues.

See: PROPQUEUE, PROPQUEUES
~~~~
CANCALL?

cancall? ( d s -- i )
---------------------
Level: M1 Apprentice
d = dbref of a MUF.
s = string representing the function to look for.
i = integer representing can or cannot.

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

fmtstring ( xn..x1 s1 -- s2 )
---------------------------
Level: M1 Apprentice
xn .. x1 = Any valid data type on the stack.
s1 = string with substitution tokens to be formatted.
s2 = Contents of s1 after formatting.

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 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
~~~~
DESCR_ARRAY


descr_array (d -- a) 
--------------------
Level: M3 Master
d = Valid player dbref.
a = array containing all of that player's descriptors.

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.

As of Proto1.5 and newer, the array will include descriptors that are not
yet connected to a character when given #-1. These would be the connections
that are open to the login screen that have not logged in yet.

See DESCRIPTORS, DESCRCON, CONDESCR, ARRAY PRIMS
~~~~
ONLINE_ARRAY

online_array ( -- a )
---------------------
Level: M3 Master
a = array containing a dbref for every connection.

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

See: ARRAY PRIMS
~~~
MOVEPENNIES

movepennies( d1 d2 i -- )
-------------------------
Level: M2 Journeyman
d1 = dbref of player/thing to take pennies from.
d2 = dbref of player/thing to move pennies to.
i  = integer representing the number of pennies to move.

Moves i pennies from player/thing d1 to player/thing d2.  

See: ADDPENNIES
~~~
GETLINKS

getlinks ( d -- dn..d1 i )
--------------------------
d = Any valid dbref except MUF objects.
dn..d1 = stackrange of links that d is linked to.
i = integer representing the number of links found.

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

srand ( -- i )
--------------
Level: M1 Apprentice
i = A random integer.

Generates a seeded random number.

See also SETSEED and GETSEED.
~~~
GETSEED

getseed ( -- s )
----------------
Level: M1 Apprentice
s = string representing the srand seed string.

Returns the the current SRAND seed string.

See: SETSEED, SRAND
~~~
SETSEED

setseed ( s -- )
----------------
Level: M1 Apprentice
s = string to become the seed for SRAND.

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.

See: GETSEED, SRAND
~~~
TOKENSPLIT
           
tokensplit ( s1 s2 s3 -- s4 s5 s6 )
-----------------------------------
Level: M1 Apprentice
s1 = Original string.
s2 = String containing token characters.
s3 = String representing the escape character.
s4 = The contents of s1 before the first unescaped token in s2
s5 = The contents of s1 after the first unescaped token ins2
s6 = The character used to split the string

  Searches s1 for the first character that matches any character in
2, so long as it is not escaped by the character given in s3.  
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"   "'"

~~
MAGECALL|WIZCALL|ARCHCALL|BOYCALL

magecall wizcall archcall boycall <funcname>
--------------------------------------------
Level: M1 Apprentice
funcname = The name of any function in the program.

  Specifies that the given function is a Wiz-only public function.  The function
can only be called by programs running under the permissioned equal to the level
of the call. An ARCHCALL function, for example, is like a PUBLIC function, except 
it can only be called by programs running at W3 or higher in permissions.

See: PUBLIC
~~
SELFCALL|SAFECALL

selfcall <funcname>              safecall
-------------------
Level: M1 Apprentice
funcname = The name of a function in the program.

  Specifies that the given function should be able to be called by the program
that it is in.   This allows you to use a function in a program via the 
  prog "funcname" call
convention, without having to explicitly make the function callable by outside
programs using PUBLIC or one of the WIZCALL related functions.  This permits
you to call a function by string at runtime.

SAFECALL is equivalient to SELFCALL, and means essentially the same thing.

See: PUBLIC
~~~
DESCR

descr ( -- i)
-------------
Level: M1 Apprentice
i = integer representing the descr that called the program.

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

See: DESCRIPTORS
~~~~
DESCRFLUSH

descrflush (i -- )
------------------
Level: M3 Master
i = integer representing descr number.

Flushes the output text on the given descriptor.  If i is -1, flushes
output on all descriptors.
~~~~
DESCR_HTML?|DESCR_PUEBLO?

descr_html? descr_pueblo? ( i1 -- i2 )
--------------------------------------
Level: M3 Master
i1 = integer representing valid descr number.
i2 =integer representing result of check.

Returns 1 if the descr represents a user connected via Pueblo or
a web browser, depending on which one is used, otherwise returns 0.

~~~~
DESCR_WELCOME_USER

descr_welcome_user ( i -- )
---------------------------
Level: M3 Master
i = Any valid descr number.

Displays the contents of the welcome.txt or welcome.html files depending
on the type of connection that descr i has. Primarially for use with 
login-programs.

~~~~~
DESCR?

descr? ( i1 -- i2)
------------------
Level: M3 Master
i1 = Any integer.
i2 = integer representing result of the check.

Given i1, returns 1 if i1 is a valid descr number, otherwise returns
0.

See: DESCRIPTORS
~~~~~
TREAD

tread ( i1 -- s i2 )
--------------------
Level: M1 Apprentice

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.

See: READ
~~~~~~~
FOR

for( i1 i2 i3 -- i4 )
------------------
Level: M1 Apprentice
i1 = Initial value of iterator.
i2 = Maximum or minimum of iterator.
i3 = How much to increase or decrease iterator by during each loop.
i4 = Current value of iterator.

For loops are a second way of beginning loops in MUF. They can be
used anywhere in a program that the BEGIN instruction can be. However,
unlike BEGIN that serves as just a marker for the beginning of a loop,
FOR creates an iterator variable, adds or subtracts from it, and exits
the loop once the variable has reached a certain point. These are ideal
for creating loops that are to be run a certain number of times.

i1 indicates the starting value for the interator. 
i2 is the maximum or minimum that the iterator should reach. For example,
  if the iterator starts out higher than i2 and goes down, the LOOP will
  exit once the iterator is lower than i2. If the iterator is lower than
  i2 and goes up, the LOOP will exit once the iterator is above i2. The
  check is made before ever running the loop. So 1 1 4 FOR will never run
  as i1 is already equal to i2. 
i3 is how much the iterator should be increased or decreased on each run
  of the loop. Note that i3 is not applied to the iterator until the loop
  has run through one time. So 1 5 3 FOR will push 1 onto the stack the
  first run of the loop, then push 4 onto the stack the second run, then
  exit after the second run.
i4 is the current value of the iterator each time the loop returns to the
  beginning.

See: LOOPS
~~~~~
FOREACH

foreach ( a -- @ ? )
--------------------
Level: M1 Apprentice
a = An array.
@ = The current index marker.
? = The current element value.

Given an array, FOREACH will repeat the loop as it goes through the contents
of the array, starting with the first element of the array, and ending once
there are no more elements of the array to push onto the stack. 
For example, {2 item array} FOREACH will push the contents of the first 
item onto the stack the first time through the loop, the contents of the
second item on the stack the second time through the loop, and then exit
before running the loop a third time.

See: LOOPS
~~~
EVENT_COUNT

event_count( -- i )
-------------------
Level: M1 Apprentice
i = integer representing the number of events waiting to be processed.

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

See: EVENTS
~~~
EVENT_WAIT

event_wait( -- x s )
----------------------
Level: M1 Apprentice
x = Can be almost any data type, depending on what the event sends.
s = string containing the ID of the event that is receieved.

When a MUF program encounters an event_wait, it essentially goes
to sleep until an event is sent. The event can be a timer event
started earlier in the same MUF, or it can be an event sent from
another program. s will be the string containing the ID of the event,
and x will be whatever the event passed to the program.

See: EVENTS
~~
EVENT_SEND

event_send( i s x -- )
----------------------
Level: M3 Master
i = integer representing process ID to send the event to.
s = string representing the event ID string.
x = The event data arguement. Can be any data type.

Sends a "USER." event to the process indicated by integer i.
The target process will receive an event that can be read with
EVENT_WAIT. The event type will be "USER." with the given id string
in string s appended to it. The event id string can be no longer than
32 characters. The event data arguement will be passed to the process
as the data element read by event_wait.
As of Proto1.6, in keeping in line with FB6 changes, EVENT_SEND now sends
a dictionary instead of just a value. The array will contain 'data' with
the value, "caller_pid" with the PID of the caller, and "caller_prog" with
the dbref of the caller.

See: EVENTS
~~
TIMER_START

timer_start( i s -- )
---------------------
Level: M1 Apprentice
i = integer representing number of seconds timer is to last.
s = ID string for the timer event.

Given a time in seconds, and a name to call the timer in string s,
starts a timer event running independently from the MUF. This timer
event can then be waited for at some point in the program via
EVENT_WAIT. It passes the time that it stops to EVENT_WAIT as an
integer representing the systime the timer stops. The name of the
event will be "TIMER." with the contents of string s appended to the
end of it. If a timer with the given name already exists, it will be
rescheduled to the new delay. Each MUF process can only have a limited
number of timers, specified by the @tune setting 'process_timer_limit'.
Timers are listed in 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.

See: EVENTS
~~
TIMER_STOP

timer_stop( s -- )
------------------
Level: M1 Apprentice
s = string with given timer ID to stop.

Stops the timer with the given timerid. Though the actual id of the
timer will be "TIMER." plus the name given by TIMER_START, the TIMER.
portion of the timer ID is assumed. So "first" timer_stop will stop
a timer that was created by '5 "first" timer_start. Timer ID names
ARE case sensitive.

See: EVENTS
~~
EVENTS|EVENTS PRIMS|MUF EVENTS

Events:
Introduced into MUF with FB6, MUF events are a powerful tool in taking
MUF to the next level in multitasking capabilities. At the moment, 
ProtoMUCK supports 2 event types. TIMER events, which return back to
the same process they were generated in, and USER events which are 
sent from one process to another via the EVENT_SEND prim. This allows
MUFs to run independent from each other, yet still send data back and
forth between the two programs, among many other capabilities. The
following event prims are available:

Timers: TIMER_START, TIMER_STOP
User Events: EVENT_SEND
Receiving Events: EVENT_WAIT, EVENT_WAITFOR
Misc: EVENT_COUNT, EVENT_EXISTS
~~
TEXTATTR

textattr( s1 s2 -- s3 )
-----------------------
s1 = Text string.
s2 = string containing attribute format.
s3 = Finished string with ANSI codes included.

Given a plain text string in s1 it adds the neccesary codes to create s3
that will display with the attributes listed in s2, given the appropriate
client support.  The attributes are given in s2 as comma seperated 
attribute names. The coded text can then be used with the NOTIFY prim to
display to the user.
The recognized format commands are:
reset, bold, dim, underline, reverse, black, red, yellow, green, cyan,
blue, magenta, white, bg_black, bg_red, bg_yellow, bg_green, bg_cyan,
bg_blue, bg_magenta, bg_white.
~~~~
PARSE_ANSI

parse_ansi( s1 i -- s2 )
------------------------
Level: M1 Apprentice
s1 = The text string to parse.
i  = integer representing the style of ANSI to parse.
s2 = string s1 with a string containing standard ANSI, ready to NOTIFY.

Given a string containing some kind of ANSI tags, the integer indicating
which version of ANSI tags are being passed, returns the string with the
standard ANSI tags in place, which can then be notified to the player to
display the message with ANSI color. 
Type 0 = FB6 style ANSI tags:  \[[0;31
Type 1 = Neon style ANSI tags: ^RED^
Type 2 = Mush style ANSI tags: %cg%ch
Type 3 = Tilde style ANSI tags: ~&110

See: ANSI
~~~~
ANSI_STRLEN

ansi_strlen( s -- i )
---------------------
Level: M1 Apprentice
s = Any string.
i = integer indicating length.

Just like STRLEN, returns the length of string s, except that characters
that are part of standard ANSI tags are not included in the count.

See: ANSI_STRCUT
~~~
ANSI_STRCUT

ansi_strcut( s1 i -- s2 s3 )
----------------------------
Level: M1 Apprentice
s1 = Any string.
i  = integer representing position in s1 at which to cut.
s2 = Contents of s1 before position i.
s3 = Contents of s1 after position i, including contents of i.

Works just like STRCUT, except that the characters that are part of
standard ANSI tags are not included in the count when determining where
to cut the string.

See: ANSI_STRLEN
~~~
ANSI_STRIP

ansi_strip( s1 -- s2 )
----------------------
Level: M1 Apprentice
s1 = Original string.
s2 = Contents of s1 except any standard ANSI tags.

Strips all of the standard ANSI tags from string s1. Included in Proto
mostly for compatability issues with FB6 MUF, otherwise UNPARSE_ANSI is 
likely to be more useful.

See: UNPARSE_ANSI
~~
ESCAPE_ANSI

escape_ansi( s1 i -- s2 )
-------------------------
Level: M1 Apprentice
s1 = Original string.
i  = integer representing type of ANSI tags to escape.
s2 = Contents of s1 with the ANSI tags escaped.

Given s1, puts the appropriate escape characters needed to 
cause the ANSI tags themselves to be seen by the user after
NOTIFY is used. The integer i represents which style of ANSI
tags are to be escaped. The choices are:
Type 0 = FB6 style ANSI tags:  \[[0;31
Type 1 = Neon style ANSI tags: ^RED^
Type 2 = Mush style ANSI tags: %cg%ch
Type 3 = Tilde style ANSI tags: ~&110
~~~
UNPARSE_ANSI

unparse_ansi( s1 i -- s2 )
--------------------------
Level: M1 Apprentice
s1 = Original string.
i  = integer representing type of ANSI tags to escape.
s2 = Contents of s2 without any ANSI tags of the indicated type.

Given a string, s1, and a type of ANSI to strip, i, will return
the contents of s1 without any of that particular version of ANSI
tags in it. Example:
"^RED^Red Text" 1 unparse_ansi  --->  "Red Text"
The choices for types are:
Type 0 = FB6 style ANSI tags:  \[[0;31
Type 1 = Neon style ANSI tags: ^RED^
Type 2 = Mush style ANSI tags: %cg%ch
Type 3 = Tilde style ANSI tags: ~&110
~~~
COMPILED?

compiled?( d -- i )
-------------------
Level: M1 Apprentice
d = dbref of a MUF program.
i = 0 or instruction count.

Given a program dbref, returns 0 if the program is not compiled, 
otherwise returns the number of instructions in the compiled program.
~~~~
INSTANCES

instances( d -- i )
-------------------
Level: M1 Apprentice
d = dbref of a MUF program.
i = 0 or number of instances running of that program.

Given a valid program dbref, returns 0 if there are no instances
of that program running, otherwise returns the number of instances
of that particular MUF that are running.
~~~~~
ARRAY_PUT_PROPLIST

array_put_proplist ( d s a -- )
-------------------------------
Level: M1 Apprentice
d = Any valid dbref.
s = string representing the propdir to put the list to.
a = A list style array.

Given a dbref, a propdir name, and a list style array, creates
a list on that object with the contents of that array. The list
that is created will be compatible with the lseditor.

See: ARRAY PRIMS, ARRAY_GET_PROPLIST
~~~
ARRAY_FINDVAL

array_findval( a1 x -- a2 )
---------------------------
Level: M1 Apprentice
a1 = Any array.
x  = Any data type.
a2 = A list array.

Given array a1 and something to look for as x, returns a list style
array containing the index markers of every element of a1 that pointed
to values matching the given value x. In other words:
{ "1" #1 "2" #2 "3" #1 } array_make_dict #1 array_findvals
would return an array that looks like: { 1,"1" 2 "3" }

See: ARRAY PRIMS, ARRAY_EXCLUDEVAL
~~~
ARRAY_EXCLUDEVAL

array_excludeval( a1 x -- a2 )
------------------------------
Level: M1 Apprentice
a1 = Any array.
x  = Any data type.
a2 = A list array.

Given array a1 and something to look for as x, returns a list style
array containing the index markers of every element of a1 that did NOT
point to values matching the given value x. In other words:
{ "1" #1 "2" #2 "3" #1 } array_make_dict #1 array_findvals
would return an array that looks like: { 1,"2" }

See: ARRAY PRIMS, ARRAY_FINDVAL
~~~~
MARK?

mark? ( x -- i )
----------------
Level: M1 Apprentice
x = Any data type on the stack.
i = integer representing true or false.

Given something on the stack, returns 1 if x is a stack marker, 
otherwise returns 0.
~~~
WEBSERVER|HTMUF|CGI|MUFCGI|CGIMUF

Carried over from NeonMUCK, ProtoMUCK is able to host web pages, and 
run programs called from the webserver room to allow web pages to be 
generated from MUF code. The webserver room is the dbref set in the
@tune table as www_root. When web browsers access the MUCK via the 
webserver port ( Also settable in @tune ), they can call MUF programs
that are set in the _/www/ prop directory off of the webserver room.

The program called depends on the URL used in the web browser, and the
name of the props the MUFs are attached to in the _/www/ directory.
For example, http://tnt.maison-otaku.net:1863/info
would call the program stored in the prop: _/www/info:
on the webserver room. HTMuf is written much like any other program,
but needs to use the notify_descriptor prim for writing out the HTML
back to the browser. Also make note of the 'parseweb' _def/ off of
#0, as using that as the very first step in writing your program will
make it a lot easier to manage. See 'help www' for additional information
on the abilities of the webserver support.
~~~~
STRIPSPACES

stripspaces ( s -- s' )
-----------------------
Level: M1 Apprentice
s  = Some string.
s' = The same string, with all spaces cut down to just one.

Strips out all the extra spaces from a string, both from the
front, the tail, and between words. So the following string:
"  This is    ProtoMUCK.  " would become "This is ProtoMUCK."
~~~~
SETPASSWORD

setpassword( d s1 s2 -- )
-------------------------
Level: W1 Mage
d  = Any valid player dbref.
s1 = The player's old password.
s2 = The player's new password.

Given a player's dbref and their old password in s1, will change
the player's password to s2. 
~~~~
NEWPASSWORD

newpassword( d s -- )
---------------------
Level: W3 ArchWizard
d = Any valid player dbref.
s = That player's new password.

Changes player d's password to the contents of string s. If player is
a wizard, then the program must be running under W4 level in order to
change their password.
~~~~
NEXT_FLAG

next_flag( d1 s -- d2 )
-----------------------
Level: W1 Mage
d1 = Any dbref.
s  = String representing the flag to search for. 
d2 = Next dbref in the data base with that flag.

Given a dbref d, checks through the data base to return the next 
dbref that has that flag set on it. If there are no more objects 
in the data base that have that flag, then #-1 is returned. 

See: NEXTOWNED_FLAG, NEXTPLAYER_FLAG, NEXTTHING_FLAG
~~~
NEXTOWNED_FLAG

nextowned_flag( d1 s -- d2 )
----------------------------
Level: W1 Mage
d1 = Any valid dbref.
s  = string representing the flag to search for.
d2 = Next dbref in data base with that flag owned by that player.

Given a valid dbref, d1, and a string representing the flag to look
for, will return the next item owned by the same player that owns
d1. I.e., if d1 is a player, it returns the first item found that
the player owns that has that flag. If d1 is an object, it returns
the next item owned by the player who owns d1 that also has the flag s.
If no objects are found, then #-1 is returned.

See: NEXT_FLAG, NEXTPLAYER_FLAG, NEXTTHING_FLAG
~~~
NEXTPLAYER_FLAG

nextplayer_flag( d1 s -- d2 )
-----------------------------
Level: W1 Mage
d1 = Any valid dbref.
s  = string representing the flag to search for.
d2 = Next player dbref in data base with that flag.

Given a dbref, searches up the data base and returns the first player
that has the flag s set. If there are no players found with that flag
set, #-1 is returned.

See: NEXT_FLAG, NEXTOWNED_FLAG, NEXTTHING_FLAG
~~~
NEXTTHING_FLAG

nextthing_flag( d1 s -- d2 )
----------------------------
Level: W1 Mage
d1 = Any valid dbref.
s  = string representing the flag to search for.
d2 = Next thing dbref in data base with that flag.

Given a dbref, searches up the data base and returns the next object of
type thing that has the flag s set. If there are no players found with 
that flag set, #-1 is returned.

See: NEXT_FLAG, NEXTOWNED_FLAG, NEXTPLAYER_FLAG
~~~~~
DESCR_LOGOUT

descr_logout( i -- )
--------------------
Level: W3 ArchWizard
i = integer representing a descriptor.

Given a valid descriptor number, returns the user to the login screen, 
effectively disconnecting the character but leaving the connection 
open.
~~~
MOTD_NOTIFY

motd_notify ( d -- )
--------------------
Level: M3 Master
d = Any valid player dbref.

Given a player dbref, d, will display the contents of the motd.txt file
to that character.
~~~~
EXPLODE_ARRAY

explode_array( s1 s2 -- a )
---------------------------
Level: M1 Apprentice
s1 = string to explode.
s2 = character to explode s1 by.
a  = A list array containing the contents of s1 broken up by s2.

Does exactly what the EXPLODE prim does, except instead of returning
the strings to the stack, it places them in a list style array.

See: EXPLODE
~~~
NEXTPROGRAM

nextprogram( d1 -- d2 )
-----------------------
Level: M3 Master
d1 = Any valid dbref.
d2 = Next program in the data base, or #-1.

Given a valid dbref, returns the dbref of the next object in the 
data base that is of type program. If there are no more programs in
the data base after d1, then #-1 is returned.

See: NEXTPLAYER, NEXTEXIT, NEXTROOM, NEXTTHING.
~~~
NEXTEXIT

nextexit( d1 -- d2 )
--------------------
Level: M3 Master
d1 = Any valid dbref.
d2 = Next exit in the data base, or #-1.

Given a valid dbref, returns the dbref of the next object in the
data base that is of type exit. If there are no more exits in the
data base after d1, then #-1 is returned.

See: NEXTPLAYER, NEXTROOM, NEXTTHING, NEXTPROGRAM.
~~~~
NEXTROOM

nextroom( d1 -- d2 )
--------------------
Level: M3 Master
d1 = Any valid dbref.
d2 = Next room in the data base, or #-1.

Given a valid dbref, returns the dbref of the next object in the 
data base that is of type exit. If there are no more exits in the
data base after d1, then #-1 is returned.

See: NEXTPLAYER, NEXTTHING, NEXTPROGRAM, NEXTEXIT
~~~
NEXTTHING

nextthing( d1 -- d2 )
---------------------
Level: M3 Master
d1 = Any valid dbref.
d2 = Next thing in the data base, or #-1.

Given a valid dbref, returns the dbref of the next object in the 
data base that is of type thing. If there are no more things in the
data base after d1, then #-1 is returned.

See: NEXTPLAYER, NEXTEXIT, NEXTROOM, NEXTPROGRAM
~~~
NEXTENTRANCE

nextentrance( d1 d2 -- d3 )
------------------------
Level: W1 Mage
d1 = Dbref of object to check entrances for.
d2 = Starting object to search from.
d3 = Next entrance after d2, or #-1 if there are no more entrances.

Will search for entrances that link to object d1. The search begins
at d2 and works its way up through the data base. d2 does not necessarially
have to be an object linked to d1, or even a valid dbref. Passing #-1 as d2
will make it so that the search begins at the bottom of the data base, before
#0.
~~~~~
NBSOCKOPEN|NBSOCK6OPEN

nbsockopen/nbsock6open ( s1 i -- socket s2 )
-------------------------------
Level: W3 ArchWizard
s1 = string representing the domain name to connect to.
i  = Port number to open the connection to.
socket = Special data type, represented as (SOCKET) on the stack.
s2 = Error string.

Given a host and a port number to connect to, returns a message string
and a socket object that may or may not be connecting still. If the 
host name is valid, s2 will contain "Operation now in progress".
Otherwise, a string containing the nature of the error will be returned,
such as "Invalid host."
The socket that is returned should then be checked with SOCKCHECK until
the connection is completed, or a pre-determined time out has been reached.
Note: The socket -must- clear through sockcheck before being used, or
it may not perform correctly when used with socksend.

NBSOCK6OPEN does precisely what NBSOCKOPEN does, except it takes 
IPv6 addresses and makes IPv6 connections.  This requires you
to compile in IPv6 support to use it.

See: SOCKCHECK, SOCKET PRIMS
~~~~
SOCKCHECK

sockcheck( socket -- i )
------------------------
Level: W3 ArchWizard
socket = MUF socket.
i = Integer representing connected or not. -1, 0, or 1.

Given a socket generated by NBSOCKOPEN, will return 0 if the socket is
still trying to connect, or 1 if the socket has connected. This should
be used in a loop to learn when a socket created by NBSOCKOPEN has 
finally connected. It is essential to check new sockets with sockcheck
before using them to transmit data, as they will not perform correctly
with socksend until having cleared sockcheck. 
If sockcheck ever returns -1, that indicates that the connection was refused.
This usually happens when trying to connect to an invalid port number on
a valid host.


Brief example of using NBSOCKOPEN and SOCKCHECK to establish a connection:
var mysock
: opensock ( -- i, tries to connect for 10 seconds before timing out )
  "some.server.com" 1864 nbsockopen pop mysock !
  1 10 1 for pop mysock @ sockcheck if 1 exit then 1 sleep
  repeat 0
;

See: NBSOCKOPEN, SOCKET PRIMS
~~~~
FUNCTION HEADERS|HEADERS|FUNCTIONHEADERS|FUNCTION_HEADERS

New in FB6 and Proto is the ability to write function headers that will
create the scoped variables and place the correct arguements into them
before actually beginning the function itself. Function headers are
created by ending a function name with a '[' mark. This tells the compilier
that you are declaring a set of variables with initial values pulled from
the stack. The function header is closed with a ']'. Each variable can also
be preceeded by a type name and a colon that represents the type of data
that the variable should be initialized with. Anything after a '--' in the
function header will be ignored. The idea is to put what the proceedure will
be returning there. For example:
: demo[ str:strVar int:intVar -- arr:arrVar ]

This would declare 2 variables, strVar and intVar, and place the top two
stack items in them as their initial values. According to the type names
on each variable, the top stack item should be an inst, and the 2nd item a
string, but this is not actually checked when the program is run. 
arrVar is not declared in the function header, as it comes after the '--', 
indicating that this function is intended to return an array.
The type names that should be used for the sake of consistency are:
'addr', 'arr','dbref', 'dict', 'float', 'int', 'lock', 'str', 'var', 
or 'lvar'.
~~~~~
VAR!

var! ( x var! <name> -- )
-------------------------
Level: M1 Apprentice
x = Any data tyle
<name> = Name of the variable to declare.

This is a short cut to declare a variable and initialize it with something
from the top of the stack all in one step. During compile time it is 
expanded to: 
var <name> <name> !
~~~~~
ISPOWER?

ispower? ( s -- i )
-------------------
Level: M1 Apprentice
s = A string representing a possible @power.
i = Integer indicating true or false.
 
Given a string, returns 1 if that string represents a valid
@power and 0 if string represents an invalid @power.
~~~
POWER?

power? ( d s -- i )
-------------------
Level: M1 Apprentice
d = Any valid player dbref.
s = String representing the @power to check for.
i = Integer indicating true or false.
 
Given a valid player dbref and a string containing a valid
@power to check for, returns 1 if that player has been given
that @power, and 0 if not.
~~~
NEXTPLAYER_POWER

nextplayer_power ( d1 s -- d2 )
-------------------------------
Level: W1 Mage
d1 = Valid player dbref.
s  = String representing the power to search for.
d2 = Dbref of next player in the data base, or #-1.
 
Given a valid player dbref, and a string representing the @power
to search for, returns the dbref# of the next player in the
data base that has that @power set, or #-1 if no players were
found with that power set.

See: NEXTPLAYER_FLAG
~~~~
PNAME-OK?

pname-ok? ( s -- i )
-----------------
Level: M1 Apprentice
s = Any string.
i = Integer indicating valid or not.

Given a string, will return a 1 if s contains a valid player name, 
otherwise returns 0.

See: NAME-OK?
~~~~
NAME-OK?

name-ok? ( s -- i )
-------------------
Level: M1 Apprentice
s = Any string.
i = Integer indicating valid or not.

Given a string, will return a 1 if s contains a valid name for
any object, otherwise returns 0.

See: PNAME-OK?
~~
ANSI_MIDSTR

ansi_midstr ( s1 i1 i2 -- s2 )
------------------------------
Level: M1 Apprentice
s1 = Original string.
i1 = integer representing the start point.
i2 = integer representing the length.
s2 = string representing the contents of s1 from i1 to i2.

Returns a sub-string of s1, starting at position i1, of length
i2. The first character is considered position 1, so that:
"testing" 2 3 midstr will return the value "est"
The difference between this and the normal midstr is that 
ANSI codes will be ignored when determining the string positions
from which to take the mid-string from. This applies only to the 
real ANSI escape codes. Use parse_ansi to convert other ANSI to
real ANSI.

If s1 is shorter than the range given by i2, then the maximum number
of character that could be returned will still be put on the stack.
If s1 is an empty string, returns an empty string no matter what.
If i1 is a point that is beyond the range of s1, returns a null string.
~~~~~
MCP PRIMS|MCP|MCPPRIMS|GUI PRIMS|GUIPRIMS|GUI

GUI MCP from FB6. 
At the time this version of the manual was completed, I had no idea
how to use the MCP prims. Below is a list of the MCP prims that are
in Proto, and each one is documented within this manual. Further
documentation regarding the use of this prims will be provided once
the way they are to be used becomes more clear. All of the manual
entries for them were taken straight from the FB6 MUF Manual.

MCP: MCP_REGISTER, MCP_REGISTER_EVENT, MCP_SUPPORTS, MCP_BIND, MCP_SEND
GUI: GUI_AVAILABLE, GUI_DLOG_CREATE, GUI_DLOG_SHOW, GUI_DLOG_CLOSE
     GUI_CTRL_CREATE, GUI_VALUES_SET, GUI_VALUES_GET, GUI_CTRL_COMMAND
     GUI_VALUE_GET

~~~~~~~~~~~~~~
MCP_REGISTER

mcp_register ( s f1 f2 -- )
---------------------------
Level: M1 Apprentice
s  = String containing the name of an MCP package to register.
f1 = Float representing minimum version number supported.
f2 = Float representing maximum version number supported.

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. 

See: MCP PRIMS
~~~~~~~
MCP_REGISTER_EVENT

mcp_register_event ( s f1 f2 -- )
---------------------------------
Level: M1 Apprentice
s  = string containing package name to register.
f1 = Float representing the minimum version package supported.
f2 = Float representing the maximum version package supported.

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

See: MCP PRIMS
~~~~~~~~~~~~
MCP_SUPPORTS

mcp_supports ( i s -- f )
-------------------------
Level: M1 Apprentice
i = integer representing a valid descriptor.
s = string representing a MCP package name.
f = float representing the packet version number supported.

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. 

See: MCP PRIMS
~~~~~~~~~~~
MCP_BIND

mcp_bind ( s1 s2 a -- )
-----------------------
Level: M1 Apprentice
s1 = string containing a package name.
s2 = string containing a specific message.
a  = A function address.

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. 

See: MCP PRIMS
~~~~~ 
MCP_SEND

mcp_send ( i s1 s2 dict -- )
----------------------------
Level: M1 Apprentice
i  = integer representing valid descriptor.
s1 = string representing package name.
s2 = string containing MCP message.
dict = Dictionary array.

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. 

See: MCP PRIMS
~~~~~
GUI_AVAILABLE

gui_available ( i -- f )
------------------------
Level: M1 Apprentice
i = integer containing valid descriptor.
f = float representing a version number.

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. 

See: MCP PRIMS
~~~~~~~~
GUI_DLOG_CREATE

gui_dlog_create ( i s1 s2 dict -- s3 )
--------------------------------------
Level: M1 Apprentice
i  = integer representing a valid descriptor.
s1 = string representing the type of dialog to show user.
s2 = string representing title to appear in the title bar.
dict = dictionary array.
s3 = string representing dialogid.

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. In general, dictArgs is only used to specify "panes" and "names"
 for D_TABBED and D_HELPER dialogs. 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.

See: MCP PRIMS
~~~~~~~~
GUI_DLOG_SHOW

gui_dlog_show ( s -- )
----------------------
Level: M1 Apprentice
s = string containing a MCP dialog to be shown to user.

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

See: MCP PRIMS
~~~~~~
GUI_DLOG_CLOSE

gui_dlog_close ( s -- )
-----------------------
Level: M1 Apprentice
s = string containing a dialog id.

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

See: MCP PRIMS, GUI_DLOG_CREATE
~~~~~ 
GUI_CTRL_CREATE

gui_ctrl_create ( s1 s2 s3 dict -- )
------------------------------------
Level: M1 Apprentice
s1 = string containing a dialog ID.
s2 = string containing dialog type.
s3 = string containing control ID.
dict - dictionary array.

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_HRULE, C_VRULE, C_BUTTON, C_CHECKBOX, 
C_EDIT, C_MULTIEDIT, C_COMBOBOX, C_SPINNER, C_SCALE, C_LISTBOX, 
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. 

See: MCP PRIMS
~~~~~ 
GUI_VALUES_GET

gui_values_get ( s -- dict )
----------------------------
Level: M1 Apprentice
s = string containing a dialog ID.
dict = dictionary array.

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

See: MCP PRIMS
~~~~~~~~~
GUI_VALUE_SET

gui_value_set ( s1 s2 s3 -- )
-----------------------------
Level: M1 Apprentice
s1 = string containing dialog ID.
s2 = string containing control ID.
s3 = string containing value to assign to control id.

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

See: MCP PRIMS
~~~~~~~~~~~
FORCE_LEVEL

force_level ( -- i )
--------------------
Level: M1 Apprentice
i = Integer representing a number of force levels.

This prim can be used to determine if a program's call was due to 
@force, {force:}, or the force prim. Any result higher than 0
indicates that the program's call was the result of a forcing.
A return of 0 indicates the player called the program without
being forced.
~~~~
ARRAY_SORT

array_sort ( a1 i -- a2 )
-------------------------
Level: M1 Apprentice
a1 = List style array.
i  = integer representing sort type.
a2 = Sorted array.

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 valid sort types are 0 - 3, which have
the following inserver muf macro $defines:

    SORTTYPE_CASE_ASCEND     Case sensitive and ascending order.
    SORTTYPE_NOCASE_ASCEND   Case insensitive and ascending order.
    SORTTYPE_CASE_DESCEND    Case sensitive and descending order.
    SORTTYPE_NOCASE_DESCEND  Case insensitive and descending order.
    SORTTYPE_SHUFFLE         Randomize the order of the array elements.

See: ARRAY PRIMS, SORT, ARRAY_SORT_INDEXED
~~~~~
EVENT_WAITFOR

event_waitfor ( a -- x s )
--------------------------
Level: M1 Apprentice
a = an array of string IDs.
x = The return value from the event found.
s = string containing the ID of the event found.

This will wait for an event to occur that matches one of the eventid 
strings in the given string list array.  The first event in the event 
queue that matches will be removed from the event queue, and will be 
returned, with the apropriate context data.  If there is no matching 
event, then this process will pause until a matching event becomes 
available.  The eventIDs are case sensitive.

See: MUF EVENTS
~~~~~
EVENT_EXISTS

event_exists ( s -- i )
-----------------------
Level: M1 Apprentice
s = string containing a MUF event ID.
i = integer representing the number of pending events with that ID.

Returns the number of pending events that have the given eventID type.

See: MUF EVENTS
~~~~~
GUI_CTRL_COMMAND

gui_ctrl_command ( s1 s2 s3 a -- )
----------------------------------
Level: M1 Apprentice
s1 = string with the Dialogue ID.
s2 = string with the control ID.
s3 = string with the specific GUI command.
a  = dictionary style array with the arguements of the command.

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

See: MCP PRIMS
~~~~~~~~
GUI_VALUE_GET

gui_value_get ( s1 s2 -- a )
----------------------------
Level: M1 Apprentice
s1 = string with the dialogue ID.
s2 = string with the control ID.
a  = A string list array representing the current value of the given control.

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

See: MCP PRIMS
~~~~~
PARSE_NEON

parse_neon ( d s1 s2 -- s3 )
----------------------------
Level: M1 Apprentice
d  = Any valid dbref.
s1 = String of text that may contain the ANSI tags.
s2 = The default color to insert into the tags where there is no preference.
s3 = The string returned with the Neon ansi tags replaced with standard ANSI.

This prim is designed to go along with the new color customization support
in ProtoMUCK. It takes a string with Neon style ANSI tags (See 'man neon ansi')
and converts them to standard ANSI format. However, it bases the conversion on
the preferences set on the dbref object, d, that is passed as well. First object
d is checked for color preference props. 
If none are found, #0 is checked for global color preferences. If none are found 
there either, then the default colors are used for normal color tags, or the 
color passed in s2 is used, if the tag wasn't a normal color tag. I.e., if s1 
contains a ^GREEN^ tag, and no preference is found on object d, nor on #0, then 
the color GREEN will be put in at that spot. But if the tag in s1 was something
like ^WHISPER^, and there is no pref for that on object d nor on #0, then 
the color indicated by string s2 will be inserted at that point. 
It is important to note that string s2 needs to contain a color formatted in
STANDARD ANSI (see 'man standard ansi'), -not- a normal Neon ANSI color tag.

See: COLORS for details on how Proto custom color props operate.
~~~~~
COLORS|CUSTOM COLORS|PARSE_NEON2|CUSTOM ANSI|NEON ANSI2
Color preferences are found under the _/colors/ directory on objects. 
For example, if the ANSI tag in s1 is ^GREEN^, and player d has a prop:
_/colors/green:forest
then instead of seeing GREEN when they get ansi_notified, they will see FOREST
instead. Or if the ANSI tag in s1 is ^PAGE^, and the player has a prop:
_/colors/page:yellow
then s1 will get returned as s4 with the standard ANSI code for 'yellow'
in place of the ^PAGE^ tags. This color customization supports sub-directories
as well. For example, if the ANSI tag is ^SAY/POSE^, and the player has a prop:
_/colors/say/text:cyan
then the occurances of ^SAY/POSE^ will be replaced with the standard ANSI for
cyan.
This color customization does not loop. For example if a player had:
_/colors/green:red        
and
_/colors/red:blue
^GREEN^ tags would be turned into the color red, not blue.

Note that the preferences on object d always take priority over the global
preferences on #0. 
~~~~~~
AKARI
akari ( -- i )
-------------------
Level: M3 Master
i = 1 or 0
Takes a program, shakes it, claims it... and then uses it to control the rest
of the MUCK. Use with care. Returns 1 if the operation is successful, or 0 if
there were not enough cookies to warrant a takeover.
~~~
MAN
MUF Manual
----------
The manual is arranged into entries on various MUF topics, special prim types,
individual prim entries, and other information.

For a list of MUF topics see: TOPICS LIST
For a list of the topics on MUF prims see: PRIMS LIST
For a list of condensed list of the MUF prims avalable see:
   PRIMS1 PRIMS2 PRIMS3 PRIMS4 PRIMS5 PRIMS6

The MUF manual is intended to be a reference to someone who already has  
some of understanding of MUF. Those looking to learn MUF from the ground
up should refer to some of the online resources available on the internet.
~~~~~
DESCRDBREF
descrdbref ( i -- d )
---------------------
Level: M3 Master
i = integer representing valid descriptor number.
d = dbref of the player connected to that descriptor.

Given a valid descriptor number, returns the player connected to that 
descriptor.
~~~~~
DESCRIDLE
descridle ( i1 -- i2 )
----------------------
Level: M2 Journeyman
i1 = A valid descriptor.
i2 = The idle time for that connected descriptor.

Given a valid descriptor, returns the amount of time that connection has
been idle in seconds.
~~~~
DESCRTIME
descrtime ( i1 -- i2 )
----------------------
Level: M2 Journeyman
i1 = A valid descriptor.
i2 = The time that descriptor has been connected in seconds.

Given a valid descriptor, returns the amount of time that connection has
been open in seconds.
~~~~
DESCRHOST
descrhost ( i -- s )
--------------------
Level: W1 Mage
i = A valid descriptor.
s = string representing the hostname for that connection.

Given a valid descriptor, returns the IP host name for that connection.
~~~~
DESCRUSER
descruser ( i -- s )
--------------------
Level: W3 ArchWizard
i = Valid descriptor.
s = string containing the user name.

Given a valid descriptor, returns a string representing the username of 
that connection's IP address.
~~~
DESCRIPNUM
descripnum ( i -- s )
---------------------
Level: W1 Mage
i = Valid descriptor.
s = string representing a IP number.

Given a valid descriptor, returns the IP number for that connection as a 
string.
~~~~
DESCRPORT
descrport ( i -- s )
--------------------
Level: W3 ArchWizard
i = Valid descriptor.
s = string representing a port number.

Given a valid descriptor, returns the IP port number for that connection
as a string. Note that that this is -not- the port that the user connected
to the muck via, but instead is a port that they are using from their IP
service to connect to the muck.
~~~~
DESCRCONPORT
descrconport ( i1 -- i2 )
-------------------------
Level: W3 ArchWizard
i1 = Valid descriptor.
i2 = integer representing a port number.

Given a valid descriptor, returns an integer representing the port number that
that user connected via.
~~~~~
DESCRLEASTIDLE
descrleastidle ( d -- i )
-------------------------
Level: M1 Apprentice
d = A valid player dbref.
i = That player's descriptor that is the least idle.

Given a valid player dbref, returns that player's least idle descriptor.
~~~~
DESCRMOSTIDLE
descrmostidle ( d -- i )
------------------------
Level: M1 Apprentice
d = A valid player dbref.
i = That player's descriptor that is the most idle.

Given a valid player dbref, returns that player's most idle descriptor
connection.
~~~~
FIRSTDESCR
firstdescr ( d -- i )
---------------------
Level: W1 Mage
d = A valid player dbref or #-1.
i = integer representing a descriptor.

Given a valid player dbref, returns that player's first descriptor number
to the MUCK. If given #-1, returns the very first descriptor connected
to the MUCK out of all the players.
~~~
LASTDESCR
lastdescr ( d -- i )
--------------------
Level: W1 Mage
d = A valid dbref or #-1.
i = integer representing a descriptor.

Given a valid player dbref, returns that player's first descriptor
number to the MUCK. If given #-1, returns the very first descriptor
connected to the MUCK out of all the players.
~~~~
ARRAY_JOIN

array_join ( a s1 -- s2 )
-------------------------
Level: M1 Apprentice
a  = List array.
s1 = Delimiter string.
s2 = String containing the contents of the array seperated by s1.

Given a list array, will return a string that is the contatenation of
all the items in the array, with each item seperated by the string in 
s1. For example:
{ "one" 2 "three" 3.14159 } array_make "... " array_join
would return:
"one... 2... three... 3.14159"

See also: }JOIN
~~~
ARRAY_MATCHVAL

array_matchval ( a1 s -- a2 )
-----------------------------
Level: M1 Apprentice
a1 = An array with all strings for its values.
s  = string containing a smatch pattern string.
a2 = dictionary array with containing key-value pairs.

Takes an array of all strings and a string representing a smatch pattern.
It returns a dictionary array that contains all the key-value pairs where
the value was a string that matched the given smatch wild card pattern.

See: SMATCH, ARRAY_MATCHKEY
~~~~
ARRAY_MATCHKEY

array_matchkey ( a1 s -- a2 )
-----------------------------
Level: M1 Apprentice
a1 = An array with all strings for its values.
s  = string containing a smatch pattern string.
a2 = dictionary array with containing key-value pairs.

Takes a dictionary array of all strings and a string representing a smatch pattern.
It returns a dictionary array that contains all the key-value pairs where
the the key was a string that matches the smatch wild card pattern.

See: SMATCH, ARRAY_MATCHKEY
~~~~
ARRAY_EXTRACT

array_extrat ( a1 a2 -- a3 )
----------------------------
Level: M1 Apprentice
a1 = An array.
a2 = A list array of indexes.
a3 = A dictionary array.

Given an array, and a second array that contains a list of index keys,
returns an array that contains only the elements who's keys were listed
in a2.
~~~~
FINDNEXT

findnext ( d1 d2 s1 s2 -- d3 )
------------------------------
Level: M2 Journeyman
d1 = dbref to start from.
d2 = Owner to search for.
s1 = Name smatch pattern.
s2 = string containing a flag list.

Searches for the next object in the data base that comes after d1 that
is owned by d1, who's name matches the wildcard pattern in s1, and 
who's flags match those specified in s2.

A search can be started with #-1, to ensure that all objects owned
by that player are checked. 

Players of M3 or higher can have d2 be #-1, which will leave out the
ownership checks. 
Players at M2 level can only perform searches with an owner being
the one that is the effective UID of the program.

If s1 is an empty string, then name checks will not be done. 
If s2 is an empty string, then flag checks will not be done.

The s1 checks for patterns using the smatch method.
The s2 is checked for the same sorts of flags used with the 
in-server @find command. Eg: "F3!D" will match all MUF programs
in the data base that are set mucker lefvel 3, and are not debug.

If there are no matches remaining in the data base after d1, then #-1
is returned. Otherwise d3 is the next matching objec that fits the 
parameters.

See also NEXT, NEXTOWNED, SMATCH, HELP @FIND.
~~~~~
FREADTO

freadto ( s1 i1 s2 -- i2 s3 )
-----------------------------
Level: W4 Boy
s1 = string containing the file name.
i1 = integer representing starting offset.
s2 = string containing a character to stop at.
i2 = integer representing final offset.
s3 = string read in from the file.

Given a file name, a starting offset, and a character to search for, reads
in the text file up until it either reaches the character contained in s2,
the end of the file, or the buffer size limit is reached, and returns it as
s3. i2 is the ending offset that the read in from the file ended at. 

At the moment, s2 may only be a single character. If more than one character is
passed, only the first one is considered. There is one special case that can
be used for s2 to find a normally unprintable character.
$EOF$ - Will cause it to read until it finds the end of the file or hits the
        buffer size limit.

Use '\r' to read to stop at line breaks.
~~~~
ARRAY_FILTER_PROP

array_filter_prop ( a1 s1 s2 -- a2 )
------------------------------------
Level: M1 Apprentice
a1 = A list array of all dbrefs.
s1 = string representing prop name.
s2 = smatch string representing prop contents.
a2 = A list array with only the dbrefs that passed the filter.

Given a list array of all dbrefs, a string representing the name of the
prop to search for in s1, and a string that can be smatched to the contents
of the props being checked in s2, returns an array that contains only
the dbrefs that have the prop in s1 with contents that pass the smatch 
matching with s2. 
So if "*" is passed as s2, then all dbrefs that have that prop at all
will get put into array a2.
~~~~~
GETPIDS

getpids ( d -- array )
----------------------
Level: W3 ArchWizard
d = Valid dbref.
array = An array of the PIDs associated with that dbref.

If d is a program dbref, will return all the PIDs that represent
active occurances of that program. If d is a player dbref, will
return an array of all the PIDs assigned to that player. If d is
a trigger dbref, it will return all the active PIDs associated with
that trigger. And finally, if d is #-2, then all active PIDs will be
included in the array that gets returned.

See: GETPIDINFO
~~~~
GETPIDINFO

getpidinfo ( i -- dict )
------------------------
Level: W3 ArchWizard
i = integer to represent an active PID.
dict = A dictionary array containing information about that process.

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

See: GETPIDS
~~~~~~
NEWPROGRAM

newprogram ( s -- d )
---------------------
Level: W4 Boy
s = string representing name of new program.
d = dbref of the new program object.

Given a string, creates an empty program object and returns the dbref
to the stack.
~~~~
COMPILE

compile ( d i1 -- i2 )
----------------------
Level: W4 Boy
d  = Program dbref.
i1 = Indicates if compilier messages should be shown or not.
i2 = Indicates if compiling was successful or not.

Given a valid dbref program, it runs that program through the
compilier. If i1 is 0, then no message is shown to the player that
the program is being compilied, or if it is successful or not. If 
1 is passed, then the compilier messages are displayed. If the 
program does not compile, then 0 is returned to the stack, otherwise
the number of instructions in the compiled program are returned.

See: UNCOMPILE
~~~~~
UNCOMPILE

uncompile ( d -- ) 
------------------
Level: W4 Boy
d = Valid program dbref.

Uncompiles the program out of memory. This is not the same as
the MUF editor's decompile option, which spams the player with the 
decompiling code. This simply removes the compiled program from
memory, so that it will compiled fresh again the next time a player
uses it.
~~~~
WATCHPID

watchpid ( i -- )
-----------------
Level: M3 Master
i = integer representing PID.

Sends a "PROC.EXIT.pid" event to the process given when the process 
referred to exits. If the process does not exist, the event will be
sent immediately. The exit event can be retrieved by a call to 
EVENT_WAITFOR. 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 when the process has terminated normally, or -1 when the
process has terminated due to abort or other crash.
~~~~
TRY

try ( i -- )
------------
Level: M1 Apprentice
i = integer representing number of stack objects to leave available. 

From FB6 comes exception handling in MUF. In order to initiate a section of
code that will be able to handle exceptions, a TRY instruction is called.
TRY takes an integer that represents the number of items on the stack to
to leave available for use during the TRY-CATCH section of code. For 
example, if i = 0, then nothing on the stack at the start of the TRY
block can be used or popped.  If i = 3, then only the top 3 items on the
stack at the start of the TRY block can be changed, used, etc. 
If any attempt to pop or change those locked stack items takes place 
between the TRY and CATCH prims, then an error will be thrown and the MUF 
program skips to the next CATCH prim. 

See: CATCH, ENDCATCH, EXCEPTION HANDLING
~~~~
CATCH

catch ( -- s )
--------------
Level: M1 Apprentice
s = string representing the error that was thrown in the TRY-CATCH block.

CATCH marks off a section of code that will be called only if there is an
error thrown in the TRY-CATCH block before the CATCH. This prim pops off 
all of the items from the stack that were not locked by the TRY prim, then
unlocks the stack. It returns a string that represents the error that caused
the code to skip to the CATCH-ENDCATCH block.

See: TRY, ENDCATCH, CATCH_DETAILED, EXCEPTION HANDLING
~~~~~
ENDCATCH

endcatch ( -- ) 
---------------
Level: M1 Apprentice

This prim represents the end of a CATCH-ENDCATCH section of code. If there
are no errors thrown in the TRY-CATCH portion of the code, then none of the
code between CATCH and ENDCATCH will be run. 

See: TRY, CATCH, CATCH_DETAILED, EXCEPTION HANDLING
~~~~
EXCEPTION HANDLING|EXCEPTIONS|ERROR THROWING|ERROR CATCHING|EXCEPTION CATCHING

Exception Handling
------------------
New from FB6 is the ability to catch exceptions thrown within the MUF code.
This is done by setting up a TRY - CATCH - ENDCATCH construction within
the code. 
TRY      denotes the start of a section of code that can catch errors, and 
         locks off the top so many items of the stack from being used. 
CATCH    denotes where the code should skip to if an error is thrown after the
         TRY call. CATCH_DETAILED has the same functionality, but returns more
         information when an exception is thrown.
ENDCATCH denotes the end of the CATCH block of code. If no error is thrown in 
         the TRY-CATCH segment, then the code between CATCH and ENDCATCH is
         never run. 

One might think of the sections of the TRY-CATCH-ENDCATCH arrangement to be
much like the IF-ELSE-THEN arrangement. Except that the code between the
CATCH-ENDCATCH will only be skipped to if an error is encountered in the
TRY-CATCH section of the program. 
An example of it in use:
: get_a_prop ( d s -- s )
  2 TRY 
    getpropstr
  CATCH
    pop ""
  ENDCATCH
;

See: TRY, CATCH, ENDCATCH, CATCH_DETAILED
~~~~
ENTRANCES_ARRAY

entrances_array ( d -- arr )
----------------------------
Level: M1 Apprentice
d = Any valid dbref.
arr = list array containing all objects linked to d.

Given a valid dbref, returns all objects linked to that object in
a list array.  Similar to the @ENTRANCES command.
~~~~
CONTENTS_ARRAY

contents_array ( d -- arr )
---------------------------
Level: M1 Apprentice
d = Any dbref other than a program or exit.
arr = list array containing that ref's contents.

Given a valid dbref that is not a program or an exit, returns that
object's contents in a list array.
~~~~
EXITS_ARRAY

exits_array ( d -- arr )
------------------------
Level: M1 Apprentice
d = Any dbref other than a program or exit.
arr = list array containing that ref's exits.

Given a valid dbref that is not a program or an exit, returns that
object's exits in a list array.
~~~~
GETOBJINFO

getobjinfo ( d -- dict )
------------------------
Level: M3 Master
d = Any valid dbref.
dict = A dictionary array of some data base related info on that object.

Returns a dictionary array containing the following information on an
object:
BLOCK       (i) - If the player can't do an action (from a read, or
                  foreground program), this is 1, otherwise 0.
CONTENTS    (d) - The start of that object's contents list.
CREATED     (i) - Systime that object was created.
CURR_PROG   (d) - Current program being run in foreground, or #-1.
DBREF       (d) - That object's dbref #.
EXITS       (d) - Start of that object's exits list.
HOME        (d) - dbref of that object's home location.
INSERT_MODE (i) - 1 if that object is insert mode, otherwise 0.
LASTUSED    (i) - systime when that object was last used.
LOCATION    (d) - dbref of object's current location.
MODIFIED    (i) - systime of when the object was last modified.
NAME        (s) - That object's name.
NEXT        (d) - What comes next in the data base when using the 'next' prim.
PENNIES     (i) - That object's penny count.
USECOUNT    (i) - That object's use count.
~~~~
GETDESCRINFO

getdescrinfo ( i -- dict )
--------------------------
Level: W3 ArchWizard
i = integer representing a valid descriptor.
dict = dictionary array containing info about that descriptor.

Given a valid descriptor, returns the following information about it:
BOOTED        (i) - Always 0, unless that descriptor will be booted shortly.
COMMANDS      (i) - Number of commands entered by that descriptor.
CON_NUMBER    (i) - Current connection number (place in WHO list)
CONNECTED     (i) - Always 1, unless the descriptor has just been dropped.
CONNECTED_AT  (i) - Systime that descriptor connected at.
CONPORT       (i) - The port that descriptor is connected via.
DESCRIPTOR    (i) - The descriptor number.
FAILS         (i) - Number of failed tries at the connection screen for 
                    descriptors not yet connected to a character.
HOSTADDR      (i) -
HOSTNAME      (s) - Hostname for the IP address.
HTTP_LOGIN    (i) - Is 1 if connected via the web login support.
HTTPDATA      (s) -
INPUT_LEN     (i) - Number of bytes sent in by that descriptor.
LAST_TIME     (i) - The last time any input was sent from the player. 
OUTPUT_LEN    (i) - Number of bytes sent out to that descriptor.
OUTPUTQUEUE   (i) - Number of lines of text waiting in the outputqueue.
OUTPUT_PREFIX (s) - See 'help outputprefix'.
OUTPUT_SUFFIX (s) - See 'help outputsufix'.
PLAYER        (d) - The character's dbref that descr belongs to.
PORT          (i) - The IP port that player connects from.
TYPE          (i) - 0 - telnet, 1 - HTTP, 2 - Pueblo, 3 - MUF port.
USERNAME      (s) - The user name for that descr's IP address.
IPV6          (i) - 1 if the connection is IPv6
SSL           (i) - 1 if the connection is secured with SSL
~~~~
FIND_ARRAY

find_array ( d1 s1 s2 -- arr )
---------------------------------
Level: M2 Journeyman
d1 = Owner to search for.
s1 = Name smatch pattern.
s2 = string containing a flag list.
arr = An array containing all the matches according to the parameters.

This prim works exactly like the FINDNEXT prim, except that it returns
all matches to the stack in a list array all at once. It is comperable to
the in-game @find command, except all matches are returned to the stack
in a single array.
  
See: FINDNEXT, ARRAY PRIMS
~~~~
DESCRBOOT

descrboot ( i -- )
------------------
Level: W3 ArchWizard
i = integer representing descriptor.

Boots the given descriptor from the MUCK.

See: CONBOOT
~~~
DESCR_SET

descr_set ( i s -- )
--------------------
Level: W3 ArchWizard
i = integer representing a descriptor
s = string representing the flag to set

Used to set descriptor flags on descriptors. 

See: 'HELP DESCRIPTOR FLAGS' for a list of descriptor flags
~~~~
DESCR_FLAG?

descr_flag? ( i1 s -- i2 )
--------------------------
i1 = integer representing a descriptor
s  = string representing the flag to check for
i2 = integer representing result

Used to check for checking for the presense of descriptor flags on
descriptors.

See: 'HELP DESCRIPTOR FLAGS' for a list of descriptor flags.
~~~~~
JMP

jmp ( address -- )
------------------
address - A function address to jump to

Moves program iteration to that function address. Was an early
way to implement tail recursion without the overhead of pushing
another function onto the stack. By today's standards, this is 
no longer an issue and use of this prim has been deprecated. It
still exists because it is one of the prims that the internal
program iteration uses JMP to implement loops and if-else-then
statements.
~~~~
GETDIR

getdir ( s -- arr )
-------------------
Level: W4 Boy
s = String representing directory to check for.
arr = Array containing the contents of that directory.

Given a directory name, it returns an array containing that
directory's contents. Subdirectories are indicated with a / mark 
following the name. If given just '/' as the directory name, it
returns the contents of the files/ directory. Works under the same 
rules as the rest of the file prims concerning the use of shortcuts 
for security reasons.

If nothing exists at the location s, then 0 is returned.
If a file exists, but is not a directory, then 0 is returned.
If the directory exists, then the array is returned. The array may
    be empty if the directory is empty. 

Example: "$INFO/" getdir would return the contents of the data/info directory

See: FILE PRIMS, SHORTCUTS
~~~~~
ARRAY_CUT

array_cut ( a1 @ -- a2 a3 )
---------------------------
Level: M1 Apprentice
a1 = Array to cut.
@  = Index of where to cut at.
a2 = Contents of a1 before the index of @
a3 = Contents of a1 after the index of @

Given an array and an index in the array, it cuts the array into
two arrays at that possition. The 2 arrays remain the same type
of array as the original array was. The first array will contain
all of the items that were before the index, and the second array
will contain all the items that were after the index. 
~~~~~~~
ARRAY_COMPARE

array_compare ( a1 a2 -- i )
----------------------------
Level: M1 Apprentice
a1 = An array to be compared.
a2 = The array to compare a1 to.
i  = Indicates the result. 

Compares the two arrays and returns 0 if they are exactly the same, otherwise
it returns a negative value if the second array is greater than the first, and
a possitive value if the first array is greater than the second. It is case
sensitive.
~~~~
REFLIST_FIND

reflist_find ( d1 s1 d2 -- i )
------------------------------
d1 = dbref of where the prop is.
s1 = string representing the name of the prop.
d2 = dbref to search for in the ref list.
i  = integer indicating if where the dbref is in the string if it is present.

A reflist is a list of dbrefs in a string type prop, often used for permissions
lists, player lists, etc. This prim takes a dbref object, the name of the 
reflist prop, and then checks to see if d2 is one of the dbrefs listed in the
reflist. If it isn't, it returns 0, if it is, it returns the position of d2
in the reflist. In other words, if it's the first dbref, then 1 is returned,
2 if it's the second, etc.

See: REFLIST_DEL, REFLIST_ADD
~~~~~~
REFLIST_ADD

reflist_add ( d1 s1 d2 -- )
---------------------------
d1 = dbref of where the prop is.
s1 = string representing the dbref.
d2 = dbref to add to the reflist.

A reflist is a list of dbrefs in a string type prop, often used for permissions
lists, player lists, etc. This prim adds dbref d2 to the reflist stored in the
prop s1 on object d1. If the dbref is already in the reflist, then it gets 
moved to the end of the list. 

See: REFLIST_FIND, REFLIST_DEL
~~~~~
REFLIST_DEL

reflist_del ( d1 s1 d2 -- )
---------------------------
d1 = dbref of where the prop is.
s1 = Name of the prop.
d2 = dbref to remove from the reflist.

A reflist is a list of dbrefs in a string type prop, often used for permissions
lists, player lists, etc. This prim removes dbref d2 from the reflist stored in
the prop s1 on object d1. If the dbref is not found in that reflist, then no
changes are made to the reflist.

See: REFLIST_FIND, REFLIST_ADD
~~~~~
DIFF3

diff3 ( fx1 fy1 fz1 fx2 fy2 fz2 -- fx' fy' fz' )
------------------------------------------------
Level: M1 Apprentice
fx# ... - The numbers to subtract from each other.
fx' ... - The difference between each of the points.

Performs the following math:
fx1 - fx2, fy1 - fy2, and fz1 - fz2, then pushes the 3 answers onto the stack.
~~~~~
FLAG_2CHAR

flag_2char ( s1 -- s2 )
-----------------------
Level: M1 Apprentice
s1 = string containing a flag name.
s2 = string containing a flag token.

Given a valid flag, returns a string containing that flag's token.
Example:
"PARENT" would return "%"
"LINK_OK" would return "L"

See: POWER_2CHAR
~~~~
POWER_2CHAR ( s1 -- s2 )
------------------------
Level: M1 Apprentice
s1 = string containing a power name.
s2 = string contaiing a power token.

Given a valid power, returns a string containing that power's token.
Example:
"CONTROL_MUF" would return "f"
"HIDE" would return "h"

See: FLAG_2CHAR
~~~~
NOTIFY_DESCRIPTOR_CHAR

notify_descriptor_char ( i1 i2 -- )
-----------------------------------
Level: W1 Mage
i1 = A valid descriptor
i2 = integer representing the ASCII character to notify out

This prim notifies a single character out to the descriptor.
It does not include an endline, so most modern MU* clients will
ignore it. 
It isn't intended to be a normal means of notifying strings out
to connections, but rather was implemented for 'special 
circumstances' programming, when something needs to be notified
to a connection without undergoing any changes in-muck.
~~~~
BANDWIDTH

bandwidth ( -- i1 i2 i3 )
-------------------------
Level: W1 Mage
i1 = Total number of bytes input to the MUCK.
i2 = Total number of bytes output by the MUCK.
i3 = Total number of commands entered since startup.

This reports stats on the bandwidth usage of the MUCK in the form 
of bytes total.  Adding i1 and i2 together should give a very accurate
total of the amount of data that has flowed over the MUCK's connections.
~~~~~
LSOCKOPEN|LSOCK6OPEN

lsockopen/lsock6open ( i1 i2 -- lsock s )
-----------------------------------------
Level: W4 Boy
i1 = integer representing the waiting queue size
i2 = integer representing the port to listen on
lsock = A listening MUF socket
s  = string containing status message

Given a waiting queue size and a port number, attempts to bind and
open a listening socket to that port. The waiting queue represents
the number of connections that can be waiting to be accepted at one
time. If you do not know what this is, just set it to 5. The port 
should be something over 1024 and must not be in use by anything 
else already.

If everything works out, an open listening socket is pushed onto
the stack and s will contain "noerr". If an error happens, then a
0 is pushed onto the stack in place of the socket and s will 
contain a message indicating an error. 

Once a listening socket is made, that port will stay open for as
long as there is an instance of that MUF socket (either in a 
variable or on the stack). Use SOCKACCEPT to accept incoming
connections.

LSOCK6OPEN does precisely what LSOCKOPEN does, except it binds
to an IPv6 address and takes IPv6 connections.  This requires you
to compile in IPv6 support.

See: SOCKACCEPT, SOCKET PRIMS
~~~~
SOCKACCEPT

sockaccept (lsocket -- socket or 0 )
------------------------------------
Level: W4 Boy
lsocket = A listening socket as created by lsockopen
socket = A traditional send/recieve MUF socket.

Given an open listening socket, checks for any incoming
connections waiting to be accepted. If there are no waiting
connections, it returns a 0 to the stack.

If there is a waiting connection, a normal MUF socket is
created and pushed onto the stack. One can then interact
with the connection via SOCKSEND and NBSOCKRECIEVE like 
normal.

See: LSOCKOPEN, SOCKET PRIMS
~~~~~~~~~~~
ARMAGEDDON

armageddon ( s -- )
--------------------
Level: W4 Boy
s = Message to send to all users before shutdown.

This primitive can be used to terminate the MUCK without an
 automatic database save. Please note, that all data created
 after the last database save, will be lost.

See the help file on @armageddon for more information.
~~~~~~~~~~~
SHUTDOWN|RESTART

shutdown ( s -- )
restart  ( s -- )
--------------------
Level: W4 Boy
s = Message to send to all users before shutdown.

These primitives can be used to shutdown or restart the MUCK.

See the help files on @shutdown and @restart for more info.
~~~~~~~~~~~
DUMP|DELTA

dump  ( -- )
delta ( -- )
--------------------
Level: W3 ArchWizard

These primitives can be used to force the MUCK to dump a standard
 or delta database save.
~~~~
ARRAY_SORT_INDEXED

array_sort_indexed ( a1 i ? -- a2 )
-----------------------------------
Level: M1 Apprentice
a1 = A list array of arrays (a stack range of arrays turned into a single array )
i  = Sort type. Can be a #define listed below.
?  = An index key value.
a2 = A list array of sorted arrays

Given a list array of arrays, this will sort all of the contained arrays
according to the contents of one of their index values as specified by the
? parameter in the arguments.  The types of sorting available are:

    SORTTYPE_CASE_ASCEND     Case sensitive and ascending order.
    SORTTYPE_NOCASE_ASCEND   Case insensitive and ascending order.
    SORTTYPE_CASE_DESCEND    Case sensitive and descending order.
    SORTTYPE_NOCASE_DESCEND  Case insensitive and descending order.
    SORTTYPE_SHUFFLE         Randomize the order of the array elements.

Once the sorting is done, the contents of a2 will be a sequence of arrays
sorted according to the element value corresponding to the index indicated
by the ? argument.

See: ARRAY_SORT, SORT
~~~
ABS

abs ( i1 -- i1 )
----------------
Level: M1 Apprentice
i1 = Any integer
i1 = Absolute value of that integer

Simply returns the absolute value of the integer. Note that in ProtoMUCK,
this can be done with the FABS prim as well. 

Ex. Both -1 and 1 would return 1.
~~~~~~~~
SIGN

sign ( i1 -- i2 )
-----------------
Level: M1 Apprentice
i1 = Any integer
i2 = The sign of the integer.

Just added this prim for compatibility reasons with FB6, but it seems to
be the most pointless prim ever. 

If i1 is negative, i2 will be -1.
If i1 is zero, i2 will be 0.
If i1 is positive, i2 will be 1.

Letting you do:
<number> sign -1 = if   ( branch if <number> is negative. 4 steps. )
For the record, you could do the same thing in 2 steps anyway:
<number> 0 < if

In other words, don't use the prim. :P
~~~~
DESCRBUFSIZE

descrbufsize ( i1 -- i2 )
-------------------------
Level: M3 Master
i1 = A valid descr number.
i2 = The space in bytes left.

Returns the number of bytes left in that descriptor's output buffer
before <Flushed> gets displayed and the buffer purged. 
~~~~
READ_WANTS_BLANKS

read_wants_blanks ( -- )
------------------------
Level: M1 Apprentice

When used, it will toggle whether or not blank entries from the user
will be caught by the READ prim or not. Initally, READ will ignore
blank strings sent by the user, but after this prim is used once, it
will make it so that empty input from the user will be caught by 
READ, causing a empty string to be pushed onto the stack.
Note that if READ_WANTS_BLANKS is used a second time, it will turn
off the behavior (i.e., it will toggle it each time it is used. ).
Also, this behavior affects all 'read events', so TREAD, or 
EVENT_WAITFOR can also be affected.

See: READ, TREAD, EVENT_WAITFOR
~~~~
MUF EDIT PRIMS|MUF EDITING PRIMS|MUF EDIT
These prims are used for editing MUF and macros. Tools needed for
writing custom MUF editors. They are a compile time option and
may not be present.

For macros: KILL_MACRO, INSERT_MACRO, GET_MACROS_ARRAY
For code: PROGRAM_LINECOUNT, PROGRAM_GETLINES, PROGRAM_DELETELINES, 
          PROGRAM_INSERTLINES
~~~~~
KILL_MACRO

kill_macro ( s -- i )
---------------------
Level: W2 Wizard
s = Name of the macro to delete.
i = Indicator of success.

Given the name of a macro in the macro table, deletes it. Returns
1 if the macro was deleted, or 0 if the macro was not found.

See: MUF EDITING PRIMS
~~~~
INSERT_MACRO

insert_macro( s1 s2 -- i )
--------------------------
Level: W2 Wizard
s1 = Name of the macro to add.
s2 = Definition of the macro to add.
i  = Indicator of success.

Given the name of a macro, and its definition, inserts the macro
into the macro table. Returns 1 if the macro was added or 0 if not.

See: MUF EDITING PRIMS
~~~~
GET_MACROS_ARRAY

get_macros_array ( -- dict )
----------------------------
Level: W1 Mage
dict = Contains all the macros and their definitions.

Returns a dictionary array where the key values are macro names,
and the data values are the definitions of the corresponding macros.

See: MUF EDITING PRIMS
~~~~
PROGRAM_LINECOUNT

program_linecount ( d -- i )
----------------------------
Level: W2 Wizard
d = dbref of a valid program object.
i = The number of lines in that program.

Returns the number of lines found in the program.
Note that in order to do this, the MUCK must load the entire
program into memory from the disk, so it is not recommended that
this prim be used frequently as longer programs could pause 
the MUCK while being loaded.

See: MUF EDITING PRIMS
~~~~
PROGRAM_GETLINES

program_getlines ( d i1 i2 -- arr )
-----------------------------------
Level: M1 to W2 Apprentice to Wizard
d  = dbref of the program to get the lines from.
i1 = Starting line to retrieve.
i2 = Last line to retrieve.
arr = List array containing the requested lines of code.

Given a dbref, and a starting and end point, returns a list
array containing those lines of code. 

Under W2 permissions, it can retrieve lines from any program
that is not set PROTECT.
An owner of a program can always retrieve their own program's
lines.
Anyone can retrieve lines from any program set VIEWABLE, unless
the program is set PROTECT.

See: MUF EDITING PRIMS
~~~
PROGRAM_DELETELINES

program_deletelines ( d i1 i2 -- i3 )
-------------------------------------
Level: W4 Boy
d  = dbref of the program to delete the lines from.
i1 = First line to delete.
i2 = Last line to delete.
i3 = Number of lines actually deleted.

Given a program, a range of lines to delete, will delete
those lines from the program. i3 contains the actual 
number of lines deleted in case there were fewer lines
in the program than in the range to be deleted.

Note that this prim will error out if the program d is
already being edited by someone. To avoid this error,
check for the INTERNAL flag with the flag? prim. If a
program is INTERNAL, then it is being edited by the 
in-server MUF editor. 
See: MUF EDITING PRIMS
~~~
PROGRAM_INSERTLINES

program_insertlines( d i1 arr -- i2 )
-------------------------------------
Level: W4 Boy
d  = dbref of the program to insert the lines into.
i1 = Starting line to insert at.
arr = List array containing the strings of code to insert.
i2 = The line number that the last line of code was inserted at.

Given a dbref d, a starting point of 1 or greater, and an array
of strings of code, inserts them into the MUF code at that point
if possible.  If the start number is higher than the actual number
of lines in the program, it will insert the lines at the end of
the code. It returns i2, the line number that the last line was
inserted at. 

Note that this prim will error out if the program d is
already being edited by someone. To avoid this error,
check for the INTERNAL flag with the flag? prim. If a
program is INTERNAL, then it is being edited by the 
in-server MUF editor. 
See: MUF EDITING PRIMS
~~~~
SQL PRIMS|SQLPRIMS

This is a set of prims for working with MySQL data bases.
They are a compile time option and may not actually be
available.

SQLCONNECT, SQLQUERY, SQLPING, SQLCLOSE
~~~~
SQLCONNECT

sqlconnect ( s1 s2 s3 s4 i1 -- (MYSQL) i2 )
        or ( s1 s2 s3 s4 i1 -- s5 i2      )
-------------------------------------------
Level: W3 ArchWizard
s1 = hostname to connect to.
s2 = username to login as.
s3 = password to use.
s4 = database to use after connecting.
i1 = Timeout in seconds to wait before giving up.
i2 = Success or failure.
s5 = Error message.

This prim is used to establish a MYSQL connection.
Note that the entire MUCK will be halted while waiting
for the connection to be made, so it is recommended that
the database be on the same machine or that the timeout
be set to very low. 

s1, s3, s4 can be blank, but s2 must have a user name.
If hostname (s1) is blank, it is assumed to be localhost.

If the connection is successful, a -0- is pushed onto the
stack along with a (MYSQL) data structure. 
If the connection was unsuccessful, an error number is pushed
along with a string containing the error message. 

See: SQL PRIMS
~~~~~
SQLQUERY

sqlquery ( (MYSQL) s1 -- dict1 ... dictn n arr )
      or ( (MYSQL) s1 -- s2 i )
------------------------------------------------
Level: W3 ArchMage
(MYSQL) - A MySQL socket.
s1 = The query to send to the data base. 
dict1 ... dictn = Each row of the result is pushed on as a dict.
arr = A list array of the field names in order.
n = Number of rows returned.
s2 = Error string.
i = Error number.

Used to make a query to a MySQL data base.
The result is pushed onto the stack as a series of dictionaries,
where the key values are the names of the fields, and the data
values are the contents of the fields for that row. Next a number
indicating the number of rows returned is pushed. 
A list array is pushed onto the stack containing the names of the 
fields in the order that they appear in the data base.

The max number of results can be set by an @tune (defaults to 40),
to keep it from trying to push rows up to the stack limit.

If there is an error with the query, an error number and a string
containing the error message are pushed onto the stack instead.
Thus it is best to check the -second- argument returned for success
for failure when using this prim.

See: SQL PRIMS
~~~~
SQLPING

sqlping ( (MYSQL) -- i )
------------------------
Level: W3 ArchWizard
(MYSQL) = SQL data socket.
i = open or closed connection.

Checks the status of the MySQL connection. Pushes 1 onto
the stack if it is open, and 0 if it is closed. Note that
once a MySQL connection is found to be closed via 
SQLPING, it is no longer usable for queries and a new
connection must be made.

See: SQL PRIMS
~~~~
SQLCLOSE

sqlclose ( (MYSQL) -- ) 
-----------------------
Level: W3 ArchWizard
(MYSQL) = SQL data socket.

Closes a MySQL connection. Note that once a connection has
been closed using SQLCLOSE, it is no longer usable with
SQLQUERY and a new connection must be made.

See: SQL PRIMS
~~~~ 
SQL?

sql? ( x -- i )
---------------
Level: M1 Apprentice
x = Any stack object.
i = 1 if it is a MYSQL connection, otherwise 0.

Returns 1 if the top of the stack is a MYSQL connection, otherwise
a 0 is returned. 

See: SQL PRIMS
~~~~
GET_SOCKINFO

get_sockinfo ( (SOCKET) -- dict )
---------------------------------
Level: W3 ArchWizard
(SOCKET) = A MUF socket.

Returns a dictionary containing information about the socket as
follows:

DESCR        = The socket's descriptor number. (int)
CONNECTED    = Indicates the socket established a connection. (int)
LISTENING    = Indicates it is a listening socket. (int)
HOST         = The hexidecimal host address. Only means anything
                   when used with SOCKACCEPT sockets. (str)
CONNECTED_AT = Systime the socket was connected. (int)
LAST_TIME    = Systime that the last input came on that socket.
               With Listening Sockets, it is the time that the last
                   connection was accepted. (int)
COMMANDS     = The number of times a message has been recieved on that
                   socket. (int)
               With Listening Sockets, it is the number of sockets
                   that it has accepted.
PORT         = The port that the socket is on. (int)
               With sockets made with NBSOCKOPEN it is the remote port.
               With sockets made with LSOCKOPEN it is the port it is
                   listening to.
               With sockets made with SOCKACCEPT it is the port that 
                   the socket connected to.
SOCKQUEUE    = Indicates if the recieve buffer is turned on or not. (int)
SMARTQUEUE   = Indicates if the recieve buffer is telent compliant. (int)
READWAITING  = Indicates that the socket is ready for reading. (int)
HOSTNAME     = Hostname for the socket's connection.
               With NBSOCKOPEN sockets, it is the host it is connecting to.
               With LSOCKOPEN sockets, it just says 'localhost'.
               With SOCKACCEPT sockets, it is the remote connection's host.
USERNAME     = Username for the socket's connection.
               With NBSOCKOPEN sockets, it is the player's name.
               With LSOCKOPEN sockets, it is the muck name.
               With SOCKACCEPT sockets, it is the remote connection username.
IPV6         = If IPv6 is enabled, this is true when this socket is an 
               IPv6 connection.
SSL          = If SSL is enabled, the current connection is secured if 
               this is true.

See: SOCKET PRIMS
~~~~
SOCKET_SETUSER

socket_setuser( (SOCKET) d s -- i )
-----------------------------------
Level: W3 ArchWizard
(SOCKET) = MUF Socket
d = dbref of player to connect the socket to.
s = string containing that player's password.
i = Indicates failure or not.

Given a MUF socket, a valid player dbref, and that player's password,
will establish a normal telnet connection to that character using the
MUF socket's descriptor. 

As far as the user can tell, the connection will seem like a standard
telnet connection to the MUCK from thereon out. Note that the SOCKET
can't be a listening socket. Normally it -should- be a socket made
from SOCKACCEPT, but in theory, sockets made by NBSOCKOPEN can be
used in the same way, though the behavior isn't certain. Note that
the username and host address of the player is only valid if
using this with sockets made from SOCKACCEPT.

As a final note: Once a MUF socket is connected to a player, it should
no longer be used as a MUF socket.

See: SOCKET PRIMS
~~~~~
SET_SOCKOPT

set_sockopt ( (SOCKET) i1 -- i2 )
---------------------------------
Level: W3 ArchWizard
(SOCKET) = A MUF socket.
i1 = Integer representing what options to set.
i2 = Indicates success or failure.

This prim is used to configure a variety of SOCKET options. 

These are the following options options for i1:
NOQUEUE =      Traditional NBSOCKRECV behavior. This is also the default behavior,
               so there is little reason to send 0, unless you are turning off
               the recieve buffer after having turned it on.
SIMPLEQUEUE  = Buffers all valid ASCII input until it hits an end-of-line, or
               the buffer fills up, in which case, it pushes the string onto 
               the stack. With most client connections, this won't make any
               difference, since most clients send their data as full lines
               anyway. But raw Windows telnet, Hyperterminal, and a few other
               clients do not.
TELNETQUEUE  = Exactly the same as option 1, except that the buffer is Telnet
               compliant. That is to say, it won't contain non-printable
               ASCII, and if backspace or delete is encountered, it will
               remove characters from the buffer accordingly. 
HOMEINSTANCE = Assigns the MUF Socket to the current instance. This determines
               which instance gets notified of Socket Events on that socket.
               By default, events only get sent to the instance that the
               socket was created in. Using this option, the socket will
               be reassigned to the current instance. 

Note: Changing the mode from TELNETQUEUE or SIMPLEQUEUE to NOQUEUE will cause
      any buffered data to be lost. 

See: SOCKET PRIMS, SOCKET EVENTS
~~~~
SOCKET EVENTS|SOCKETEVENTS|EVENT SOCKETS

Socket Events
-------------

As of Proto 1.80, MUF sockets can have events as well.  This allows
one to write MUF Socket programs that don't revolve around CPU
wasting loops for NBSOCKRECV and SOCKACCEPT. Instead, by learning
to use Socket Events correctly, it becomes possible to let MUF
socket using programs to sleep when there is no traffic on their
sockets.  

Then @tune socket_events is set to 'yes', MUF sockets will be
polled by the server several times faster than they could be
polled in MUF. When the server finds a MUF socket is ready
to be read from, it sends a Socket event to that socket's
'Home Instance'. When a normal socket has an event, that means
there is some kind of input to be read from it. When listening
sockets have an event, that means there is a connection waiting
to be accepted by them. 

EVENT_WAITFOR will return:
(SOCKET) "SOCKET.READ.<sock number>" for normal sockets and
(LSOCKET) "SOCKET.LISTEN.<sock number>" for listening sockets. 

See: SOCKET EVENTS 2
~~~
SOCKET EVENTS 2|SOCKETEVENTS 2|SOCKET EVENTS2

Socket Events - Continued
-------------------------

Only one PID can recieve events for one socket at a time. This
PID is called the 'Home Instance' for the socket. By default,
this is always the PID that the socket was created in. However,
by using:
(SOCKET) HOMEINSTANCE SET_SOCKOPT
the 'Home Instance' for that socket gets changed to whatever
the currently running PID is. 

For example, if a socket is accepted via SOCKACCEPT in one
program instance, and then a process is forked off to handle
reading input from that socket in another instance, simply 
use HOMEINSTANCE SET_SOCKOPT on that socket once it is in 
its new PID to make it so that Socket events will be recieved
to that new PID instead of the PID where the socket was made
via SOCKACCEPT. 

Correct use of Socket Events can greatly increase the efficiency
of MUF socket programs, elimiating wasteful checking loops.
~~~~
COPYPROPS

copyprops ( d1 s1 d2 s2 i1 -- i2 )
----------------------------------
Level: W3 ArchWizard
d1 - Source object
s1 - Source propdir
d2 - Destination object
s2 - Destination propdir
i1 - If 1, recurse into propdirs
i2 - Number of properties copied

This primitive can be used to copy the properties and
 sub-properties from the specified propdir of one object
 into a specified propdir on another object.

If i1 is 1, COPYPROPS will also copy all propdirs and
 their properties from the specified propdir.

Example:
  #200 "a" #400 "/" 0 copyprops
 Would copy:
  /a/la:no
  /a/bob?:yes
 But would not copy:
  /a/b/c:yes
  /a/f/g/l:no
~~~
CHECKLOCK

checklock ( d1 d2 s -- i )
--------------------------
Level: M1 Apprentice
d1 = dbref of a player or thing.
d2 = dbref of object that has the lock.
s  = prop that contains the lock.
i  = integer representing result.

Given a player or thing in d1, and an object in d2, checks the prop
s for a lock. Will run all the same checks that LOCKED? will, including
any MUF calls that are contained in the lock. This prim works just 
the same as ISLOCKED? except that it will call MUF unlike ISLOCKED?
If the player or thing does not pass the lock, then 1 is returned to 
the stack. If d1 passes the lock, or there is no lock, then 0 is 
returned to the stack.

See: TESTLOCK, LOCKED?, CHECKLOCK
~~~
SYSPARM_ARRAY

sysparm_array ( s -- dict )
--------------------------
Level: M1 Apprentice
s = string to smatch parm names against or empty.
dict = dictionary containing the matching @tune parameters.

Given a string to smatch @tune names against, returns a dictionary
of the matching @tune options with the syntax of:
{ <parameter name>:<parameter value> }

If s is an empty string, it returns the entire @tune table.
~~~~
XOR

xor ( x x -- i )
----------------
x = Any to stack data objects.
i = Result of boolean XOR.

Performs the XOR operation on the top two stack objects.
~~~~
SOCKTODESCR

socktodescr ( (SOCKET) -- i )
-----------------------------
Level: W3 ArchWizard
(SOCKET) = A MUF socket. 
i = integer representing the descriptor number of the socket.

Given a MUF socket, adds the descriptor for that MUF socket to the
internal descriptor table, making it a valid descriptor as far as the 
MUCK can tell. Almost no coders will have a use for this prim, but
it was essential in order for the MUF based webserver project to be
backwards compatible. 

There is ONE advantage of using this prim that might be useful to 
others. That is for notifying out large amounts of data to a socket.
Since the MUF sockets are BLOCKING when using SOCKSEND, they might 
abort or error on excessive data going out, whereas using 
NOTIFY_DESCRIPTOR to notify to the descriptor made by this prim will
allow the output to be queued just like standard outgoing MUF text. 

The newly made descriptor will show up in !WHO as [Inbound]. There
are a few things to keep in mind should you chose to use this prim:
    The [Inbound] descriptor will never be idled off by the
        inserver idle routines.
    While the [Inbound] descriptor can be written to via
        the various descriptor notification routines,
        it cannot be read from AT ALL. The original MUF
        socket MUST be used with NBSOCKRECV to read in anything
        on that connection.
    The descriptor will be unconditionally closed once the MUF
        socket it was made from no longer exists. 
~~~~
PARSEPROPEX

parsepropex ( d s1 dict i -- dict' s2 )
---------------------------------------
Level: M3 Master
d  = Object on which the prop exists.
s1 = Prop name. 
dict = Dictionary of variables.
i  = Private/public bool.
s2 = Result after MPI parsing. 

Similiar to PARSEPROP, except that it allows the programmer to
pass a dictionary of variables to go with the MPI parsing. 
The dict has the syntax of:
{ <var name>:<var value> }
i indicates if any messages from {delay:} should be public or
private. 
The variable dictionary will be returned after the parsing with
any new changes made to the variables during parsing reflected in
it. 

See: PARSEPROP, PARSEMPI
~~~~
DEBUG_ON|DEBUG_OFF|DEBUG_LINE

debug_on   ( -- )
debug_off  ( -- )
debug_line ( -- )
-----------------
Level: M1 Apprentice

debug_on    - Sets the program DEBUG.
debug_off   - Removes the DEBUG flag from a program.
debug_line  - Prints out a single line of debug tracing for whatever is
              on the stack that instant. 
~~~~
MUF OPTIMIZING|MUFOPTIMIZING

MUF Optimizing
--------------
New in Proto 1.80 is the byte-code optimizer as implemented in FB6.
optimize_muf must be @tuned to yes for it to work. If a program is
set = N, then that program will not be optimized during compile time.

The MUF optimizer removes redundent steps from the MUF code and also
combines certain instructions into single steps, all to reduce the
number of instructions ran during run time. The actual number of 
instructions reduced will be reported during compile time.

Most of the optimization involves variables, in terms of reducing the
number of steps needed to set, clear, retrieve data, etc. 

The other things that are currently optimized are as follows:
"" strcmp 0 =        ------> not
# # +                ------> <sum of the two ints>
# # -                ------> <difference of the two ints>
# # *                ------> <product of the two ints>
# # /                ------> <quotent of the two ints>
# # %                ------> <result of MOD on the two ints>
0 =                  ------> not
1 +                  ------> ++
1 -                  ------> --
rot rot swap         ------> swap rot
not not if           ------> if

There is room for additional optimization to be added in future versions:
"" stringcmp 0 = into simply 'not'
and
"" stringcmp not if into simply 'not' 
There's a bunch of others too.
floating point number optimizing. 
~~~
ITOH
 
itoh ( i -- s )
-----------------
Level: M1 Apprentice
i = Integer to convert to hexadecimal.
s = Hexadecimal value returned as string.
 
Converts an integer into a hexadecimal string.
 
Example:
     15 becomes "0F"
    255 becomes "FF"
   4095 becomes "FFF"
  65535 becomes "FFFF"
 
See: HTOI
~~~~
HTOI
 
htoi ( s -- i )
-----------------
Level: M1 Apprentice
s = Hexidecimal string to convert into integer.
i = Integer value of hexidecimal string.
 
Converts a hexadecimal string into an integer.
 
Example:
     "E" becomes 14
    "8A" becomes 138   
   "E4A" becomes 3658
  "FFFA" becomes 65530
 
See: ITOH
~~~~
UNESCAPE_URL
 
unescape_url ( s1 -- s2 )
-----------------
Level: M1 Apprentice
s1 = URL string to process.
s2 = URL string returned with %xx hex codes converted.
 
Given an escaped URL as argument s1, converts the %xx hex
codes into their ASCII character values.
 
Used primarily by the MUF webserver and HTMuf/CGI 
programs.
     
See: ESCAPE_URL
~~~~
ESCAPE_URL
 
escape_url ( s1 -- s2 )
-----------------
Level: M1 Apprentice
s1 = Unescaped URL string to process.
s2 = Escaped URL string.
 
Given an unescaped URL as argument s1, converts certain 
characters
into %xx hex values.
 
Used primarily by the MUF webserver and HTMuf/CGI 
programs.
 
See: UNESCAPE_URL
~~~~
SOCKSHUTDOWN

sockshutdown ( (SOCKET) i1 -- i2 )
----------------------------------
Level: W3 ArchWizard
i1 = integer (0 through 2) indicating how to shut down the socket.
i2 = success indicator

This closes down the socket. You can control in which way you want
the socket to be shutdown. 
i1 can be the following values:
0 = Stop recieving data for this socket. 
1 = Stop trying to transmit any data from this socket. This will
    also keep the TCP layer from looking for acknowledgement packets
    on this connection.
2 = Close down the socket in both directions. This is the traditional
    SOCKCLOSE behavior. 

This prim will replace SOCKCLOSE in 1.9. SOCKCLOSE will be defined
as '2 SOCKSHUTDOWN' come 1.9. 

See: SOCKCLOSE
~~~~
MKDIR

mkdir ( s -- i )
----------------
Level: W4 Boy
s = name and path of the new directory
i = Success in making the directory

Given a string, attempts to make a directory by that name. Respects
and requires the file token shortcuts. If the directory is made,
1 is returned. 0 is returned if the prim was unable to make the
directory.

See: FILE PRIMS, SHORTCUTS
~~~~
RMDIR

rmdir ( s -- i )
----------------
Level: W4 Boy
s = name and path of the directory to delete
i = Success in removing the directory

Given a string, attempts to delete a directory by that name and
all of that directory's contents. Respects and requires file
token shortcuts. If the directory is deleted, 1 is returned.
0 is returned if the prim was unable to delete the directory.

See: FILE PRIMS, SHORTCUTS, MKDIR
~~~~
DEBUGGER_BREAK

debugger_break ( -- )
--------------------------
Level: M1 Apprentice

When this prim is encountered, the MUF is forced straight into the 
interactive debugger mode on whoever it was that was running the MUF.
~~~~~
SYSTIME_PRECISE

systime_precise ( -- f )
------------------------
Level: M1 Apprentice
f = floating point number

This prim returns the systime time with an accuracy down to millisecond
accuracy. Can be used for high precision timing loops.
~~~~~
ARRAY_INTERPRET|}CAT

array_interpret ( a -- s )
---------------
Level: M1 Apprentice
a = array of nearly any datatypes
s = concated string of converted datatypes

This primitive takes the array given, converts all floats to strings with
the least significant zeros truncated, converts all integers to strings, 
converts all locks to strings, converts all dbrefs to names, and contencates
all strings into one, returning the string.

Example: 
{ #2 " has " 2 3 + " apples and gave " 1 2 / " to you. } array_make array_interpret
Results in "Alynna has 5 apples and gave 0.5 to you." if #2 is named Alynna.

}cat is an inserver define for '} array_make array_interpret', so the following
works: { "The answer is: " 2 3 4 5 + + + }cat
~~~~~
FTOSTRC

ftostrc ( f -- s )
-------
Level: M1 Apprentice
f = a floating point number
s = a sane representation of the number as a string

Takes the float on the stack, and converts it to a string representation of the
float with all significant digits removed.   So 1.000000 becomes '1', and 
0.666000 becomes "0.666".

It should also in most cases round 5.9999999999... right up to "6" for you.
~~~~
TRUECONTROLS

truecontrols ( d1 d2 -- i )
------------
Level: M1 Apprentice
d1 = a player or players object
d2 = any other object
 i = binary true or false if d1 truly controls d2

Returns true if player d1 would have control over d2 even if it were not set
CONTROLS.
~~~
BASE64ENCODE|BASE64DECODE|BASE64

BASE64ENCODE BASE64DECODE ( s1 -- s2 )
-------------------------
Level: M1 Apprentice
s1 = string to be converted one way or the other
s2 = string result from conversion

Converts raw binary data to base 64 ASCII text, for storage in props or to
be sent over a connection that is not 8 bit clean.

Base64Encode converts binary to Base64 ASCII ...
Base64Decode converts it back to binary
~~~
IGNORE_ADD

IGNORE_ADD ( d1 d2 -- )
----------
Level: W3 Archwizard

d1 = playing wanting to ignore someone
d2 = player to be ignored

Adds d2 to d1's ignore list.

See: HELP IGNORE
~~~
IGNORE_DEL

IGNORE_DEL ( d1 d2 -- )
----------
Level: W3 Archwizard

d1 = player wanting to remove the ignore
d2 = player to be removed from ignore

Removes d2 from d1's ignore list.

See: HELP IGNORE
~~~
IGNORING?

ignoring? ( d1 d2 -- )
---------
Level: W3 Archwizard

d1 = player to be tested
d2 = player being checked

Returns >0 (or TRUE) if d2 is on d1's ignore list, or 0 (false) if not.
The returned value corresponds to its exact position in the string. 

See: HELP IGNORE
~~~
ARRAY_GET_IGNORELIST

array_get_ignorelist ( d -- a )
--------------------
Level: W3 Archwizard

d = player to get the ignore array from
a = array of players on the list

Returns an array of people being ignored by the player indicated by d.
This array can be modified and written back by a W3 archwizard by using
<player> "/@/ignore" <array> ARRAY_PUT_REFLIST

See: HELP IGNORE
~~~
MAX_IGNORES

max_ignores ( -- i )
-----------
Level: M1 Apprentice

i = number of ignores compiled into the MUCK, or 0 if not compiled on

Returns the maximum number of ignores that have been compiled in.
Usually this is 16.  More or less may be added to the ignore list but only
the first ones up to MAX_IGNORES will actually work.

If MAX_IGNORES is 0, ignore support isnt compiled in, setting @/ignore will
do nothing, and none of the ignore prims but this one will work.

See: HELP IGNORE
~~~
SOCKSECURE

socksecure ( socket -- i )
----------
Level: W4 boy
socket = A socket connected to an SSL supported connection
     i = 0 if connected, -1 if disconnected, >0 for other SSL errors

Attempts to secure a connection using SSL.  The remote end must support SSL
or SSL negotiation.  If successful, this returns 0.

See: SOCKUNSECURE
~~~
SOCKUNSECURE

sockunsecure ( socket -- )
------------
Level: W4 boy
socket = A socket.

Attempts to unsecure a connection with an SSL session open.  Does not and 
cannot return a result.  Will do nothing on an insecure connection, on an
SSL connection, it shuts down the SSL session, which, if the connection 
supports it, can continue unsecured.

See: SOCKSECURE
~~~
SSL_SOCKACCEPT

ssl_sockaccept ( lsocket -- socket or 0 or errorstring )
--------------
Level: W4 Boy
lsocket = A listening socket as created by lsockopen
socket = A traditional send/recieve MUF socket.

Works just like sockaccept, except it will immediately try to negotiate
SSL with the client connecting.

A socket is returned if an SSL session can be established.
0 is returned if theres no connections in the queue.
A string 'SSLerr: #' is returned if SSL couldnt be negotiated.
~~~
ARRAY_NESTED_GET

array_nested_get ( a1 a2 -- ? )
----------------
Level: M1 Apprentice

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' )
----------------
Level: M1 Apprentice

  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' )
----------------
Level: M1 Apprentice

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
~~~
CATCH_DETAILED

catch_detailed ( -- dict )
--------------
Level: M1 Apprentice

Used in place of catch, it returns a dictionary of values relating to the 
error that occured in the MUF code.

  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.
~~~
ARRAY_SUM

array_sum ( a -- n )
---------
Level: M1 Apprentice

a = An array of integers or floats
n = An integer or float result of the sum of array a.

Takes an array of integers and/or floats, and outputs a result containing
the sum of all integers and floats found.  If any floating points were
in the array, the result will be float, even if the result is not
fractional.

If any other datatypes are in the array, it will abort in an error.
~~~~~
ARRAY_STRING_FRAGMENT

array_string_fragment ( s i -- a )
Level: m1 Apprentice

s = A string to break up
i = The size of fragments to break it into 

Takes string s and breaks it into fragments of size i and returns
them in array a.
 
For example:
"Greetings" 3 array_string_fragment would return an array with
"Gre" "eti" "ngs" as the 3 values. 
Using a value of 1 for i will break the string into individual
characters. i must be greater than 0. 

See: ARRAYS2
~~~~~
LABELS|MUF LABELS|LABEL|MUFLABELS|LABELS1|LABEL1

MUF Labels
----------
Introduced with ProtoMUCK 2.0, MUF labels allow programmers to mark and
 jump to specific points within an MUF function.  MUF labels are handled
 during compile time and are pre-processed, meaning a program can get the
 address of a specific label within a function before that label is even
 defined.
 
MUF labels are simply used to mark an address to a specific point in a
 function.  You cannot jump to a label inside a different function than
 the one that is currently executing, nor can you pass label addresses
 to different programs or functions.
 
In order to jump to a label address you must first get the address of the
 label using the ' method, just as you would get the address of a function,
 and then use the JMP primitive to move execution of the program to that
 address.  However, unlike a function call, it does NOT store a return
 address on the system stack, so you cannot EXIT back to the execution point
 from where the JMP was called.
 
For an example, see: LABELS2
 
See: JMP, EXIT, ADDRESS
~~~~~
LABELS2|MUF LABELS2|LABEL2|MUFLABELS2|LABELS2|LABEL2

MUF Labels, example
-------------------
An example of MUF label use:
 
: main ( i -- )
   me @ "Hello "
   'skipover jmp
      "Planet!"
   skipover:
      "World!" strcat notify
;
 
The result, is to print "Hello World!" to the user.
~~~~~
INTERRUPTS|INTERRUPT|MUF INTERRUPTS|MUFINTERRUPTS|INTERRUPTS1|INTERRUPT1

MUF Interrupts
--------------
Introduced with ProtoMUCK 2.0, MUF interrupts allow MUF programs to set
 interrupts linked to specific events.  When this specific event is received,
 program execution will halt and the function specified (using ONEVENT) is
 called.  When this function exits, program execution continues at whatever
 point and state it was at when the interrupt was thown.

At the time of this writing, timer events cannot interrupt SLEEP or READ. The
 cause of this problem is unknown.  Also, interrupt functions cannot interrupt
 eachother.  That is, if a new interrupt is thrown while a previous interrupt's
 function is still in execution, the second (and any following interrupts) will
 be handled after the exit of each previous interrupt handler function.

The maximum level of interrupts queued for execution at a time is 32, although
 an unlimited number of interrupts can be declared at a time using the ONEVENT
 primitive.

Interrupts can interrupt EVENT_WAITFOR, SLEEP, READ and any other blocking
 MUF program states, and can wait for any specific event.

Multiple interrupts can be queued for the same event, and will be executed
 in reverse order of how they were declared (using ONEVENT).

Continued, see: INTERRUPTS2
~~~~~
INTERRUPTS2|INTERRUPT2|MUF INTERRUPTS2|MUFINTERRUPTS2

MUF Interrupts, continued
-------------------------
Based on the integer value passed to ONEVENT, the triggering event may or may
 not be passed to the MUF event queue (IE: caught by EVENT_WAITFOR).  If
 multiple interrupts exist for the same event, and any one of those says to
 leave the event in the queue, such will be done.  Please keep this in mind
 if EVENT_WAITFOR is used within interrupt-called functions.

When an interrupt is thrown, the function it calls is passed the following set
 of arguements:

   ( ???:Data strEvent strID )

Data is the data passed to the event, strEvent is the string event ID name, and
 strID is the interrupt's ID name as passed to ONEVENT.  Only one interrupt can
 be declared with the same name per program instance.  Keep this in mind if
 using interrupts in libraries or other shared programs.

Please note that interrupt functions are _NOT_ protected from the rest of the
 program's active stack.  If stack items are edited, changed, or you fail to
 pop or use the three stack items provided to the interrupt function, the main
 program _WILL_ fail (unless otherwise done by design).

For an example, see: INTERRUPTS3

See: ONEVENT, INTERRUPT_LEVEL
~~~~~
INTERRUPTS3|INTERRUPT3|MUF INTERRUPTS3|MUFINTERRUPTS3

MUF Interrupts, example
-----------------------
Here is a simple example program which throws an interrupt every 5 seconds
 using a timer:

: ping ( ? s s -- )
   ( Notify the user, reset the timer, and make sure )
   (  to leave with a clean stack.                   )
   me @ "Got interrupt ID: " rot strcat notify
   pop pop 5 "ping" timer_start
;

: main ( s -- )
   "TIMER.ping" "intping" 'ping 0 onevent
   5 "ping" timer_start
   begin
     event_waitfor pop pop
     ( We never fall here, the event is never passed )
     (  to EVENT_WAITFOR.                            )
   repeat
;
~~~~~
ONEVENT

onevent ( s1 s2 a i -- )
------------------------
Level: M1 Apprentice
s1 = Event ID of the event to trigger this interrupt.
s2 = This interrupt's ID name.
a  = Address of function to execute when the interrupt is thrown.
i  = If true, event is passed into the program's event queue.

Example usage:
 "TIMER.ping" "int1" 'pingfunc 0 onevent

Declares interrupt s2 for the current program, which will be triggered
 whenever the program receives an event with the same ID as s1.  s1 accepts
 SMATCH-like patterns like EVENT_WAITFOR does.

If i evaluates to a true integer, the event will be passed to the program's
 event queue, so that it can be caught by EVENT_WAITFOR and EVENT_EXISTS.
 Otherwise, the event is not passed and is deleted after all interrupts for it
 are thrown.

See: INTERRUPTS, EVENT_WAITFOR, ADDRESS
~~~~~
INTERRUPT_LEVEL

interrupt_level ( -- i)
-----------------------
Level: M1 Apprentice
i = Number of interrupt levels.

Returns the number of interrupts the program has serviced without returning
 itself to normal execution.  The maximum is 32 before the program errors out.

See: INTERRUPTS, ONEVENT
~~~
UDPOPEN

udpopen ( i1 -- i2 )
------------------
Level: W3 Archwizard
i1 = Port to listen on
i2 = 1 if successful, 0 if the port is in use.

Opens a UDP listening port.  Your MUF program will receive events called 
UDP.<port> whenever something is received in the port.

If IPv6 support is compiled in, this also opens up an UDPv6 listener.

See: UDP
~~~
UDPCLOSE

udpclose ( i1 -- i2 )
------------------
Level: W3 Archwizard
i1 = Port to stop listening on
i2 = 1 if successful, 0 if the port was not open.

Closes a UDP listening port.  Events on the port will stop coming.

See: UDP
~~~
UDPSEND|UDP6SEND

udpsend/udp6send ( s1 s2 i1 -- i2 )
-----------------------------------
Level: W3 Archwizard
s1 = UDP data to send
s2 = Hostname or IP to send to
i1 = Port to send to
i2 = 1 if successful, 0 if the hostname couldnt be resolved.

Attempts to send a UDP packet to a remote host, on the port specified.
The packet size is limited to 1500 characters.  There is no way to know
if the remote host gets the data, since it is a datagram.  If the host
cannot be resolved, 0 is returned.  If sending is successful, 1 is returned.

UDP6SEND does exactly what UDPSEND does, except it takes IPv6 addresses,
and sends UDPv6 requests.

See: UDP
~~~
UDP|UDP SOCKETS|DATAGRAM|DATAGRAMS|UDP EVENT|UDP EVENTS

UDP support in Proto
--------------------
As of Proto 2.0b7.32, UDP support has been introduced into ProtoMUCK.  This
allows you to send and receive datagrams to remote hosts.  Receiving datagrams
is done entirely through events, and can be received without making your 
MUF program a daemon.

A UDP event comes in as "UDP.<portnumber>" with an dictionary as its data.
The dictionary contains the following data:

PID             The PID of the program receiving it
PORT            The port number it came in from
FROM            The IP of the sender
DATA            A string containing the UDP payload

The following prims are related to using the UDP support:

UDPOPEN ( i:port -- i ) 
 Start listening on the given port

UDPCLOSE ( i:port -- i )
 Stop listening on the given port

UDPSEND ( s:payload s:hostname i:port -- i ) 
 Send a UDP packet to a remote port
 
And a quick example of its use.  This will listen for packets on port 8472 and
echo them to you with the IP that they came from:

: main
background 8472 udpopen
begin 
 { "udp.*" }array event_waitfor pop var! data
 me @ { data @ "from" [] ": " data @ "data" [] }cat ansi_notify
repeat
;

And to send data to this:
: main "127.0.0.1" 8472 udpsend ;
~~~
DNS

dns ( s1 -- s2 s3 )
-------------------
Level: W3 Archwizard
s1 = Name of host to look up
s2 = Canonical name of host (its reverse DNS)
s3 = IP of the host given

Looks up the IP of a host by its name.  It returns the real name of the host
and the IP of the host on the stack.  If the host cannot be found, it returns
a pair of null strings.
~~~
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 "Flag" argument may be a combination, or none of the following:
  
    $def REG_ICASE    1   (Case insensitive match)
    $def REG_ALL      2   (Substitute all matches, rather than just the first)
    $def REG_EXTENDED 4   (Allows PCRE comments, etc.  See PCRE docs.)
  
Ie: to replace all words in a string with 'yadda', ignoring case, you would
use the following code:
  
    "[a-z]+" "yadda" REG_ICASE REG_ALL + REGSUB
~~~
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 apropriate
for use with the MIDSTR primitive, and consider the first character of the
string to be position 1.
  
The "flag" argument may be 0, or a combination of the following:
  
    $def REG_ICASE    1   (Case insensitive match)
    $def REG_EXTENDED 4   (Allows PCRE comments, etc.  See PCRE docs.)
~~~
SUID

suid ( i:mode/descr d:target -- b:success )
-------------------------------------------
Level: W4 Boy
i = mode or descriptor to give to the target
d = target to receive the process and/or descriptor

The SUID prim is useful for assigning players to MUF or HTTP descriptors, or
for handing off a running MUF to another player.   The first argument takes
the target of the handoff.   The second argument specifies either a mode or
descriptor.  Here's what happens with different values for mode:

-1: The process only is handed off to the target, the descriptor remains with
    the trigger player.   This causes output to fork, anything notified to the
    descriptor using a notify_descriptor class prim will go to the original
    trigger, while anything notified to me @ will go to the target, as well as
    any other output related to the program.
 0: The current descriptor of the running program, as well as the program itself
    is handed off to the target.  If the descriptor is connected to a MUCK
    connection like CT_MUCK or CT_SSL, when the program exits, the descriptor
    will still be logged into the player.  In all instances, the descriptor is
    handed to the target player and they are brought into an online state.  This
    is mostly useful for assigning web and MUF connections to a particular 
    player and for other 'alternative client' uses.
>0: Same as above, except usable for any other descriptors as well.  Provide
    the name 

There was a reason why this is a W4 prim.  Tread Carefully.
~~~
LFLAGS_UPDATE

lflags_update
-------------
Level: W3 Archwizard

Simply refreshes the list of flags from the @flags props on #0.  Use this to
update the names and permissions levels of local database flags while your
program is running.
