&&& man The following topics are currently available: flow flow control and compilation primitives operands mathematical and other logic logical tests testing/setting things stack stack operations array array operations string string property property-related conversions data conversion db db operations interaction player interaction operations stamp timestamp operations daytime time operations descriptor descriptor operations system system parameters file file operations Type `man TOPIC' to get specific information, or `man op' to get information on `op'. See "man terminology" for some terminology. &&& MARKER - end of main man and beginning of topic pages &&& terminology Primitives marked with "[wizard]" are wizard-only; they work only for programs set WIZARD and owned by wizards. The descriptions use the term "wizard program" to refer to such programs. The term "effective player" refers to the player running the program, unless the program is set S(etUID), in which case it means the program's owner, or T(rigUID), in which case it's the owner of the trigger. A program is said to be "able to build" if it is a wizard program, if the effective player is a builder, or if the program's B bit is set. &&& propinfo Every dbref has a property list. Properties are named by strings, and most properties have strings as their values. Every property has permission bits that control who is allowed to perform what operations on it. When a property is created via an interface that does not specify the permissions, they are derived from the first character of the name ("control", as used here, means that the effective player controls the dbref): _ read-only: anyone may read it, but changing/removing it requires control. . private: any operation requires control. * MUF: not accessible from the command line (except for wizards), but unrestricted from MUF. @ wiz-only: any operation requires wizard access. ~ wiz-write-user-read: anyone may read, but changing/removing requires wizard access. Other first characters have no restrictions by default. See "man propperm" for more details on permissions, or "man property" for the associated primitives. Property values may be strings, dbrefs, or arbitrary MUF values. Strings are the commonest; a string-valued property remains until explicitly removed. A dbref-valued property is similar, except that if the dbref is recycled, the property value automatically changes to #-1. An anyval property is the most general, but, unlike string- and dbref-valued propertyes, anyval properties are not saved in the database file, which means they do not survive server shutdowns and restarts (which can be useful). Note that it is entirely possible (and sometimes useful) to have an anyval property whose value is a string or dbref. &&& propperm Property permissions are theoretically the cross product of "who", "what", and "how". "who" can be WHO-O, the object wner, WHO-R, for oyalty, WHO-W, for izards, or WHO-A, for nyone else. "what" can be BIT-X, to test for eistence, BIT-R, to read the property's value, BIT-W, to rite the property's value, BIT-D, to elete the property, BIT-F, to ind when traversing the list, or BIT-C, to hange the permissions. "how" can be HOW-C, for the ommand line, HOW-M, for UF code, or HOW-L, for ock tests. (There are MUF primitives for these bits; see "man propperm-bits".) Any attempted access can be classified into a "who", a "what", and a "how". The masks associated with the three have only one bit in common; if this permissions bit is set for the property, the operation is allowed. Two notes MUF coders should be aware of: (1) for HOW-L, the only meaningful operation is read, so BIT-R is the only one of the BIT- masks that has any bits in common with HOW-L; (2) a god character (see "help god") or a program running with god permissions is always allowed any property operation. This is done by having an additional bit that is always set. (This matters to code that calls getpropperm, which will see an otherwise inexplicable bit always set.) &&& library MUF libraries are a means of making packages of code widely accessible. A library is just an ordinary MUF program, except that some of the words defined in it have specifically been made accessible for other programs to use. The $lib and $import compiler directives are how these words are made accessible to programs that want to use them; see their descriptions for syntax and some usage notes. For a library to be accessible, it must be placed in the MUF library room; this room is distinguished by having its dbref in an @muf-library-room: property on the global environment room #0. A library name is mapped to a dbref by looking for a property _lib-NAME (where NAME is the library name specified) on the MUF library room; if no such property is found, the contents of the room are searched looking for a program object called NAME. If nothing is still found, the search fails, and the $lib or $import directive produces an error. ($lib and $import accept the #nnn syntax for dbrefs, though it is of limited use; see the restrictions listed below for call time. Even when using this syntax, the program object must exist and be a program at compile time.) For a word to be exported, a property must be placed on the program object; if the word is called "foo" in the library program and the library wants it to be known as "bar" to programs using it, then a property _export-bar: with value "foo" should be placed on the program object. As an abbreviation, if the _export- property exists with a zero-length value, the library-internal name is taken to be the same as the exported name. Only some of the above is checked at compile time. At compile time, the library must be found, and, if $lib is used, the list of words imported is obtained by searching the object for _export-* properties. However, $import does not check for _export-* properties at compile time. At compile time, the dbref of the library object and the exported name of the word being called are compiled into the calling program. At run time, a number of things are checked: - The library dbref must still be a program. - At least one of the following must be true: - The effective user owns the library. - The library is set L(ink_OK). - The calling program is a wizard program. - The library is in the MUF library room. - The library must be compiled or compilable. - The _export- property for the called name must exist on the library dbref, and the internal name it indicates (see above) must be defined by the library's code. If any of these checks fail, an error is generated. &&& MARKER - end of general information and beginning of lists of prims &&& flow Flow control and compilation-time primitives: : word begins definition of the word ; ends a definition begun with : var word declares word as a variable forward word forward declaration, for co-recursion $def word text define a (program-local) macro $define word text $enddef define a (program-local) macro $undef word undefine a macro $lib libname call on a MUF library $import lib word [as] selectively import from a MUF library if ( i -- ) begins a conditional construct else separates then-part from else-part eif marks an else-if construct then ends an if construct exit ( -- ) returns from the word it appears in to whatever called that word call ( d -- ? ) call another program sleep ( i -- ) sleep for i seconds sleep ( d -- ) sleep until a wakeup is done on the dbref wakeup ( d -- ) wake up anyone sleeping on the dbref kill ( d -- ) kills a daemon nop ( -- ) does nothing begin, do ( -- ) marks the begining of a loop for ( i1 i2 i3 -- i1 ) initiates a FOR .. LOOP i1 is the begin, i2 is the end, and i3 is the stepsize. Each run through the loop will place the new value of the counter on the stack. loop, repeat ( -- ) terminates a begin/do or for loop. until ( x -- ) terminates a begin/do or for loop, both syntactically and, conditionally, in terms of flow control as well. break ( -- ) terminates a begin/do or for loop prematurely, that is, before it normally would. This affects the smallest enclosing such loop. while ( i -- ) conditionally break a loop, like "not if break then". continue ( -- ) branches to the end of a loop, just before the closing "loop". fork ( -- i ) forks a new daemon; in the original daemon or player, the pushed value is the number of the new daemon; in the new daemon, it's 0. ' word ( -- ptr ) Pushes a pointer to the word on the stack. The word must have already been defined. exec ( ptr -- ) Pops a pointer to a word and executes the word. { ..code.. } Pushes a pointer to the code. 'word ( -- addr ) Pushes address of a word. execute ( addr -- ) Executes a word, given its address. yield ( -- ) Lets others execute. critical ( x -- ) Marks a critical-section word. An iteration counter has been added to the server. See `man system'. &&& operands Operands: + ( x x -- x ) add - ( x x -- x ) subtract * ( n n -- n ) multiply / ( n n -- n ) divide /0 ( i i -- i ) divide /% ( n n -- i n ) quotient/remainder % ( n n -- n ) remainder/modulus %0 ( i i -- i ) remainder/modulus | ( i i -- i ) bitwise or & ( i i -- i ) bitwise and ^ ( i i -- i ) bitwise xor ~ ( i -- i ) bitwise not << ( i i -- i ) bit shift left >> ( i i -- i ) bit shift right < ( n n -- i ) less than > ( n n -- i ) greater than = ( n n -- i ) equals != ( n n -- i ) not-equals <= ( n n -- i ) less than or equals >= ( n n -- i ) greater than or equals neg ( n -- n ) negate abs ( n -- n ) absolute value dbcmp ( d d -- i ) compare two dbrefs, 1 = same random ( -- i ) a random # from 0 to MAXINT qrandom ( -- q ) a quad filled with random bits @ ( v -- x ) fetch value of a variable ! ( x v -- ) set value of a variable ++ ( v -- ) increment value of a variable -- ( v -- ) decrement value of a variable ldexp ( f i -- f ) load exponent frexp ( f -- f i ) split exponent and fraction sin, cos, tan ( n -- f ) trigonometric functions sincos ( n -- fs fc ) sin and cos combined asin, acos, atan ( n -- f ) inverse trigonometric functions atan2 ( ny nx -- f ) two-argument arc tangent sinh, cosh, tanh ( n -- f ) hyperbolic trig asinh, acosh, atanh ( n -- f ) inverse hyperbolic trig exp, expm1 ( n -- f ) exponentials log, log1p, log10 ( n -- f ) logarithms pow ( n1 n2 -- f ) general power sqrt, cbrt ( n -- f ) square and cube roots hypot ( n1 n2 -- f ) Euclidean distance frandom ( -- f ) random number in [0..1) pi ( -- f ) common constant e ( -- f ) common constant &&& logic Logical operators: and ( x x -- i ) logical and or ( x x -- i ) logical or not ( x -- i ) logical not The empty string "", the integer 0, and #-1 are false; anything else is true. &&& tests Tests and related primitives: address? ( x -- i ) is arg an address object? array? ( x -- i ) is arg an array? awake? ( x -- i ) is arg a connected player? builder? ( d -- i ) is the dbref a builder? daemon? ( x -- i ) is arg a daemon dbref? dbref? ( x -- i ) is arg a dbref? exit? ( x -- i ) is arg an exit dbref? flag? ( d s -- i ) is the named flag set on the dbref? float? ( x -- i ) is arg a floating-point number? god? ( d -- i ) is the dbref god? int? ( x -- i ) is arg an integer? locked? ( d -- i ) is the dbref locked? mucker? ( d -- i ) is the dbref a mucker? number? ( x -- i ) is arg a string that contains a number? ok? ( x -- i ) is arg a valid dbref? passlock? ( d1 d2 -- i ) does d1 pass the lock on d2? player? ( x -- i ) is arg a player dbref? plt? ( x -- i ) is arg an property list traversal object? program? ( x -- i ) is arg a program dbref? prop-exists? ( d s -- i ) does the property exist on the dbref? ptr? ( x -- i ) is arg a pointer object? quad? ( x -- i ) is arg a quad? quota? ( d i -- i ) does the player have enough building quota? regexp? ( x -- i ) is arg a regular expression object? room? ( x -- i ) is arg a room dbref, or #-3? royalty? ( d -- i ) is the dbref royalty? string? ( x -- i ) is arg a string? thing? ( x -- i ) is arg a thing dbref? true-royalty? ( d -- i ) is the dbref royalty, ignoring Quell? true-wizard? ( d -- i ) is the dbref wizard, ignoring Quell? var? ( x -- i ) is arg a variable? wizard? ( d -- i ) is the dbref wizard? getflags ( d -- i ) get flags word as integer set ( d s -- ) set/clear the named flag on the dbref flagbit ( s -- i ) convert flag name to flag bit passwordchk ( d s -- i ) check password's correctness &&& stack Stack manipulation: depth ( -- i ) returns number of entries on the stack dup ( x -- x x ) duplicates top element over ( x1 x2 -- x1 x2 x1 ) copies next-to-top element pick ( x1 ... xN N -- x1 ... xN x1 ) copies Nth element down from stack (thus, dup = 1 pick, over = 2 pick) pop ( x -- ) pops top element off stack mpop ( x1 ... xN N -- ) pops many things at once put ( x1 ... xN y N -- y x2 ... xN ) replaces Nth element down on stack roll ( xN ... x1 N M -- xM ... x1 xN ... xM-1 ) rotates top N elements M places rot ( x1 x2 x3 -- x2 x3 x1 ) rotates top three elements (3 rotate) -rot ( x1 x2 x3 -- x3 x1 x2 ) rotates top three elements (-3 rotate) rotate ( x1 x2 ... xN N -- x2 ... xN x1 ) ( x1 ... xN-1 xN -N -- xN x1 ... xN-1 ) rotates top N elements (N -1 roll or N 1 roll) swap ( x1 x2 -- x2 x1 ) swaps top two elements copy ( x1 ... xN N -- x1 ... xN x1 ... xN ) copies top N elements of the stacp pstack ( i -- ) debugging aid - prints part or all of stack &&& array Array operations: newarray ( i1 ... iN N -- a ) create a new array aset ( x i1 ... iN a -- ) store a value in an array aset1d ( x i a -- ) store a value in an array aget ( i1 ... iN a -- x ) get a value from an array aget1d ( i a -- x ) get a value from an array array-n-dims ( a -- i ) get number of dimensions of array arrayshape ( a -- i1 ... iN N ) get dimensions of array array1size ( a -- n ) get total size of array array-n-to-1 ( i1 ... iN a -- i ) convert multidimensional index to linear array-1-to-n ( i a -- i1 ... iN N ) convert linear index to multidimensional afill ( x min1 max1 ... minN maxN a ) fill part or all of an array with a value &&& string String operations: caps ( s -- s' ) uppercases first char, lowercases rest explode ( sA sB -- s1 ... sN N / sA i -- s1 ... sN N ) explodes sA, with sB as delimiter explode1 ( sA sB -- sA2 sA1 1 / sA 0 ) splits sA at sB implode ( s1 ... sN N sB -- sA) inverse of explode rexplode ( sA sB -- sN ... s1 N / sA i -- sN ... s1 N ) explodes sA, with sB as delimiter rexplode1 ( sA sB -- sA1 sA2 1 / sA 0 ) splits sA at sB rimplode ( sN ... s1 N sB -- sA) inverse of rexplode instr ( s1 s2 -- i ) finds first s2 in s1 instring ( s1 s2 -- i ) finds first s2 in s1 pronoun_sub ( d s -- s' ) performs % substitution rinstr ( s1 s2 -- i ) finds last s2 in s1 rinstring ( s1 s2 -- i ) finds last s2 in s1 strcat ( s1 s2 -- s ) concatenates two strings strcmp ( s1 s2 -- i ) compares two strings stringcmp ( s1 s2 -- i ) compares two strings, ignoring case strncmp ( s1 s2 n -- i ) compares prefixes of two strings stringncmp ( s1 s2 n -- i ) stringcmp crossed with strncmp strcut ( s i -- s1 s2 ) cut a string in two strlen ( s -- i ) finds length of string strspn (s1 s2 -- sA sB) span initial substring strcspn (s1 s2 -- sA sB) span initial substring subst ( s sA sB -- s' ) substitutes sA for sB in s multisubst ( s sA1 sB1 sA2 sB2 ... n -- s' ) do multiple "subst"s at once tolower ( s -- s' ) maps string to lower case toupper ( s -- s' ) maps string to upper case re-compile ( s -- re ) compile a regular expression re-match ( re s -- v1 ... vN N / 0 ) match a string against a regular expression re-subst ( v1 ... vN N s -- v1 ... vN N s' ) performs regexp substitutions &&& property Dbref property and message manipulation primitives. See "man propinfo" for general information about properties; see "man propperm" for property permission info. pennies ( d -- i ) gets money of dbref addpennies ( d i -- ) adds money to dbref name ( d -- s ) gets name of dbref desc ( d -- s ) gets description of dbref drop ( d -- s ) gets drop message of dbref fail ( d -- s ) gets fail message of dbref succ ( d -- s ) gets success message of dbref odrop ( d -- s ) gets odrop message of dbref ofail ( d -- s ) gets ofail message of dbref osucc ( d -- s ) gets osuccess message of dbref setname ( d s -- ) sets name of dbref setdesc ( d s -- ) sets description of dbref setdrop ( d s -- ) sets drop message of dbref setfail ( d s -- ) sets fail message of dbref setsucc ( d s -- ) sets success message of dbref setodrop ( d s -- ) sets odrop message of dbref setofail ( d s -- ) sets ofail message of dbref setosucc ( d s -- ) sets osuccess message of dbref addprop ( d name val -- ) adds/changes property on dbref getpropstr ( d s -- s' ) gets property string value getpropval ( d s v -- v' ) gets property value propfirst ( d -- t s 1 / 0 ) gets first property name of dbref propnext ( t -- t s 1 / 0 ) gets next property name of dbref remove_prop ( d s -- ) removes property from dbref addprop-if ( d sp sv -- s / 0 ) test-and-set property setting remprop-if ( d sp sv -- i) test-and-remove property backprops ( d -- d1...dN N ) list of objects with props with d as value getpropperm ( d s -- q ) get permissions on property setpropperm ( d s q -- ) set permissions on property setprop ( d s k v -- ) set property changeprop ( d sp o n -- 1/0 ) compare-and-set property setting &&& propperm-bits Property permission bits (see "man propinfo" for more information): propperm-who-o the "owner" bits propperm-who-r the "royal" bits propperm-who-w the "wizard" bits propperm-who-a the "anyone else" bits propperm-bit-x the "test for existence" bits propperm-bit-r the "read value" bits propperm-bit-w the "write value" bits propperm-bit-d the "delete property" bits propperm-bit-f the "find property" bits propperm-bit-c the "change permissions" bits propperm-how-c the "command-line" bits propperm-how-m the "MUF" bits propperm-how-l the "lock check" bits &&& conversions Conversion functions: atof ( s -- f ) convert string to float atoi ( s -- i ) convert string to int atoq ( s -- q ) convert string to quad ceil ( f -- i ) convert float to integer floor ( f -- i ) convert float to integer ftoq ( f -- q ) convert float to quad round ( f -- i ) convert float to integer trunc ( f -- i ) convert float to integer dbref ( i -- d ) convert int to dbref float ( i -- f ) convert int to float itoq ( i -- q ) convert int to quad variable ( i -- v ) convert int to variable qtoa ( q -- s ) convert quad to string qtof ( q -- f ) convert quad to float qtoi ( q -- i ) convert quad to int int ( d -- i ) convert dbref to int intostr ( n -- s ) convert number to string &&& db DB operations: db_top ( -- i ) integer = highest element in db + 1 dbtop ( -- d ) highest dbref in db moveto ( d d -- ) move object 1 to 2 contents ( d -- d ) returns first content of dbref exits ( d -- d ) returns first exit of dbref next ( d -- d ) find next of contents/exits/daemons match ( s -- d ) match string in current location rmatch ( d s -- d ) match string in remote location copyobj ( d -- d ) returns dbref of copy of thing location ( d -- d ) returns the location of a dbref owner ( d -- d ) returns owner of a dbref getlink ( d -- d ) returns link of a dbref dig ( s d -- d d ) create a room named 1 with parent 2 returns the room dbref as 1 and parent as 2 open ( s d -- d ) open an exit program ( s -- d ) create a new program online ( -- d1 ... dN N ) returns a list of players chown ( d d -- ) changes ownership of 1 to 2 recycle ( d -- ) recycles an object create ( s i -- d ) creates a new object unlink ( d -- ) unlink an exit/object addlink ( d d -- ) links object 1 to object 2 linkcount ( d -- i ) find the number of links on an object getlinks ( d -- d1...dN N ) returns all the links on an object trig ( -- d ) returns the dbref of the trigger prog ( -- d ) returns the dbref of the current program caller ( -- d ) returns the player who ran the program callers ( -- d1...dN N ) returns a list of callers backlinks ( d -- d1...dN N ) returns a list of objects linked to obj backlocks ( d -- d1...dN N ) returns a list of objects locked to obj nextowned ( d -- d' ) returns the next in an owned list numowned ( d -- i ) returns count of owned dbrefs daemons ( -- d ) returns the first in a list of the daemons daemon ( -- d ) returns the dbref of the daemon, #0 if being run by a player. kill ( d -- ) kills a daemon unparse_flags ( d -- s ) returns verbose flags, eg "Player" flagstr ( d -- s ) returns short flags, eg "Pwaj" unparse_lock ( d -- s ) returns lock as a human-readable string lockstr ( d -- s ) returns lock as string usable for lock lock ( d s -- ) sets the key on d unlock ( d -- ) unlocks a dbref force ( d s -- ) force player to execute command trigger-exit ( d -- ) trigger an exit memused ( d -- i ) get memory usage uid ( -- d ) get effective player current-frame-id ( -- q ) get execution frame serial number frame-id-busy? ( q -- 0/1 ) is frame serial number in use? &&& interaction Player interaction: read ( -- s ) reads in a string notify ( d s -- ) notify one player notify_except ( d1 d2 s -- ) notify all but 2 in room 1 prompt ( s -- s' ) read with a prompt timed-prompt ( s i -- s / 0 ) read with prompt and timeout &&& stamp Timestamp operations: time_created ( d -- i ) get time dbref was created time_modified ( d -- i ) get time dbref was last modified time_used ( d -- i ) get time dbref was last used touch ( d -- ) sets the last-used time to now &&& daytime Time-of-day operations: ctime ( i -- s ) convert time value to a string date ( -- d m y ) get current date (day/month/year) time ( -- s m h ) get current time (second/minute/hour) systime ( -- i ) get current time in timestamp form gmtsplit ( i -- s m h md m y wd yd ) split a timestamp value in UTC timesplit ( i -- s m h md m y wd yd ) split a timestamp value in local timezone &&& this is for later, in case these come back gmtmerge ( s m h md m y wd yd -- i ) inverse of gmtsplit timemerge ( s m h md m y wd yd -- i ) inverse of timesplit &&& descriptor Descriptor stuff: concount ( -- i ) the number of connections to the MUCK, connections ( -- i1...iN N ) returns a list of descriptor #'s conidle ( i -- i ) returns the idle time in seconds contime ( i -- i ) returns the connection time in seconds conuser ( i -- s ) [wizard] returns the user connected from conhost ( i -- s ) [wizard] returns the host connected from condbref ( i -- d ) returns the dbref of a connection connotify ( i s -- ) [wizard] notifies a connection conboot ( i -- ) [wizard] disconnects a descriptor conforce ( i s -- ) [wizard] forces a connection connected? ( i -- i ) is the descriptor connected? See "man invalid-con" for an important note. &&& invalid-con The primitives listed under "man descriptor" deal with connections. Connections are identified with small nonzero integers, chosen by the server. Primitives that return connection numbers will always return positive values. Primitives that take connection numbers can be passed a positive number, in which case the number is taken as the connection number, and if the connection doesn't exist, an error occurs; they also can be passed a negative number, in which case the absolute value is taken as the connection number, and if the connection doesn't exist, something sensible happens, appropriate to the primitive in question. The descriptions of the primitives refer to this condition as "invalid". Zero is considered positive and is never a valid connection number. &&& system System values: ilimit ( -- i ) get current ilimit value setilimit ( i -- ) set ilimit &&& file These primitives provide very minimal filesystem access. There are no privilege restrictions on use of these primitives, but the site admin must create a directory for each player that is to be able to use them. Pathnames as passed to sys-open (a) must not attempt to use .. to ascend in the filesystem hierarchy (at all) and (b) will have a string prepended to them, this prefix string being created as if int intostr "files/" swap strcat "/" strcat were applied to the effective player's dbref. (This is why the directory must be created; if it doesn't exist, all open attempts will fail indicating ENOENT.) Also, the server can be built with filesystem access disabled; when this is done, sys-open, sys-read, sys-write, and sys-lseek will still exist, but will do nothing but generate errors if executed. There is no sys-close. An open file is closed by dropping the last reference to the open file object. sys-open ( s i -- o ) opens a file sys-read ( o n -- s / o n -- s -1 ) reads a line from an open file sys-write ( o s -- n / o s -- s -1 ) writes a line to an open file sys-lseek ( o i1 i2 -- i ) seeks within an open file O_RDONLY, O_RDWR, O_WRONLY, O_CREAT, O_TRUNC, O_EXCL, SEEK_SET, SEEK_CUR, SEEK_END constants &&& MARKER - end of topic pages and beginning of individual descriptions &&& ! ! ( x v -- ) Sets a variable. The value on top of the stack must be a variable; the value below can be any MUF object. The variable's value is set to the object. &&& != != ( n1 n2 -- i ) Returns 1 if n1 is not equal to n2, 0 otherwise. See = for a relevant note about float arguments. See also "man cmp-types" for more. &&& $def $def word ...text... A $def defines the word as expanding to the specified text (which is taken to be up to the end of the line, as constrasted to $define). This expansion is done inline at compile time, unlike defining a word with : and ;, which compiles only one copy of the code and calls it at run-time. $def expansions, unlike : ... ; definitions, also do not need to be balanced with respect to control structure. For very small definitions, using $def produces more efficient code than a : ... ; definition does (a typical example would be defining a prefix string intended to be tweaked as a configuration parameter; it is more efficient to write [ $def prop-prefix "_foo/" ] than it is to write [ : prop-prefix "_foo/" ; ]). A $def macro can call another $def macro; this can be nested to unlimited depth. This is done by rescanning the expanded text when the macro is used, not by expanding macros during the definition. In particular, this means that the relative order of definitions is irrelevant. For example, if you write $def foo bar $def bar blee the "foo" will expand to "blee", same as if the definitions had been done in the other order. Infinite recursion during expansion is prevented by disabling a macro for the duration of its expansion. This also means that if, for example, you write : foo ... ; $def foo swap foo 1 + then when you use "foo" after that point, it will do a "swap", call the "foo" word defined with : ... ;, and then do "1 +". &&& $define $define word ...text... $enddef This is just like $def, except that the replacement text is taken to be everything up to the $enddef, instead of being everything up to the end of the line. Once made, there is no distinction between words defined with $def and those defined with $define. &&& $enddef See $define. &&& $import $import libname wordname $import libname wordname asname This directive makes a single word from a MUF library accessible. The first form, with only two arguments, works just like $lib except that only the specified word is made accessible; the second form is just like the first except that instead of being made accessible under the name the library exports it with (wordname) it is made accessible under a name specified on the $import directive (asname). For example, if the library called "somelib" exports the name "foo" but this program wants to call it "bar" instead for some reason, the appropriate line would be "$import somelib foo bar". See "man library" for more information on MUF libraries. A $import directive must all be on a single line. &&& $lib $lib libname This makes accessible all words exported by the named MUF library, under the names the library exports them as. See "man library" for more information on MUF libraries. A $lib directive must all be on a single line. &&& $undef $undef word This removes any $def or $define definition of the given word. It is not an error to $undef something that isn't defined. &&& % % ( n1 n2 -- n ) Divides n1 by n2, returning the remainder, unless n2 is zero, in which case an error occurs. The arguments can be two integers, in which case an integer is returned; or an integer and a float, or a quad and a float, or two floats, in which case a float is returned; or an integer and a quad, or two quads, in which case a quad is returned. In the presence of negative integer operands, the rounding direction is not guaranteed. For integers, this form uses the C % operator, so the same caveats apply: if both arguments are positive, the result is the mathematical modulus, but if either of the arguments is negative, the result may be negative. Its absolute value will be less than that of n2, and it will always be the case that, given two integers on the stack, with the top one non-zero, over over % 3 pick 3 pick / rot * + = will return 1. (For those who know C, this corresponds to the C identity ((a/b)*b)+(a%b) == a, for b != 0.) If either argument is a float, the other is converted to a float, and the result is a number of the same sign as n1, with absolute value less than that of n2, which differs from n1 by an integer multiple of n2. (Unless n1/n2 is large enough to overflow an integer, in which case the value of the result is undefined.) If no floats are involved, but a quad is, both arguments are converted to quads and a quad reminader is done. &&& %0 %0 ( i1 i2 -- i ) This is just like % (for integer arguments) except that if i2 is 0, the result is 0 with no error. Note that unlike %, it does not accept floats. &&& & & ( n n -- n ) Returns the bitwise AND of its operands. See "man bit-types" for more. &&& ' ' word ( -- ptr ) ' generates a pointer that points to the word following the '. Aside from manipulations that work on any MUF types, such as stack operations, this pointer is good for nothing but passing to the exec primitive. Note that there is a similar syntax, which has no space between the ' and the following word, which generates a different type of pointer (called an address) that can be passed only to the execute primitive. These two types of pointers are incompatible; each may be used only with the corresponding primitive to call the word pointed to. Pointers work correctly when calling from one program to another; addresses don't, but are slightly faster to call. Note that this works only with words defined with :. It cannot be used with built-in primitives. &&& * * ( n1 n2 -- n ) Multiplies its arguments and returns the product. The arguments can be two integers, in which case an integer is returned; or an integer and a float, or a quad and a float, or two floats, in which case a float is returned; or an integer and a quad, or two quads, in which case a quad is returned. &&& + + ( x1 x2 -- x ) Adds its arguments and returns the sum. The arguments can be two integers, in which case an integer is returned; or an integer and a variable, in which case a variable is returned; or an integer and a dbref, in which case a dbref is returned; or an integer and a float, or two floats, or a quad and a float, in which cases a float is returned; or an integer and a quad, or two quads, in which cases a quad is returned. &&& ++ ++ ( v -- ) Increments the value of the variable; the value must be an integer, quad, dbref, or variable (or a run-time error occurs). &&& - - ( x1 x2 -- x ) Subtracts i2 from i1, returning the difference. The arguments can be two integers, in which case an integer is returned; or the first can be a variable and the second an integer, in which case a variable is returned; or the first can be a dbref and the second an integer, in which case a dbref is returned; or both variables, or both dbrefs, in which case an integer is returned; or an integer and a float, or a quad and a float, or two floats, in which cases a float is returned; or an integer and a quad, or two quads, in which case a quad is returned. &&& -- -- ( v -- ) Decrements the value of the variable; the value must be an integer, dbref, or variable (or a run-time error occurs). &&& -rot -rot ( x1 x2 x3 -- x3 x1 x2 ) Rotates the top three elements of the stack. This is equivalent to `-3 rotate'. (See also rot.) &&& / / ( n1 n2 -- n ) Divides n1 by n2, returning the quotient, unless n2 is zero, in which case an error occurs. The arguments can be two integers, in which case an integer is returned; or an integer and a float, or a quad and a float, or two floats, in which case a float is returned; or an integer and a quad, or two quads, in which case a quad is returned. In the presence of negative integer operands, the rounding direction is not guaranteed; see the % operator for more information. &&& /% /% ( n1 n2 -- iq nr ) If n2 is zero, an error occurs; otherwise, divides n1 by n2, returning the integer quotient (iq) and remainder (nr). The quotient will always be an integer, even for float arguments, and (n2*iq)+nr will equal n1, unless the quotient overflows an integer. In the presence of negative integer arguments, the rounding direction is not guaranteed; see the % operator for more information. iq is always an integer; nr has the same type that * would return for the same operands. &&& /0 /0 ( i1 i2 -- i ) Divides i1 by i2, returning the quotient, unless i2 is zero, in which case 0 is returned. In the presence of negative operands, the rounding direction is not guaranteed; see the % operator for more information. Note that unlike /, this is integer-only. &&& : : word This begins the definition of a word. The definition extends until the following ;. Note that, unlike real FORTH, : and ; cannot be embedded in the definition of a word; also, the body of a word cannot be empty. &&& ; ; Ends a definition begun with :. See : for more information. &&& < < ( n1 n2 -- i ) Returns 1 if n1 is less than n2, 0 otherwise. See "man cmp-types" for more. &&& << << ( n1 i2 -- i ) Returns n1 left-shifted i2 bits. Unlike the C operator, if i2 is negative, this shifts right instead. However, like C, if the magnitude of i2 is greater than or equal to the number of bits used to represent n1, the result is undefined. n1 must be an integer or quad. &&& <= <= ( n1 n2 -- i ) Returns 1 if n1 is less than or equal to n2, 0 otherwise. See "man cmp-types" for more. &&& = = ( n1 n2 -- i ) Returns 1 if n1 is equal to n2, 0 otherwise. Note that floating-point numbers can look equal but be different; in some circumstances you may be better off with a test like "- abs espilon <" for some appropriate epsilon. See also "man cmp-types" for more. &&& > > ( n1 n2 -- i ) Returns 1 if n1 is greater than n2, 0 otherwise. See "man cmp-types" for more. &&& >= >= ( n1 n2 -- i ) Returns 1 if n1 is greater than or equal to n2, 0 otherwise. See "man cmp-types" for more. &&& >> >> ( n1 i2 -- i ) Returns n1 right-shifted i2 bits. Unlike the C operator, if i2 is negative, this shifts left instead. However, like C, if the magnitude of i2 is greater than or equal to the number of bits used to represent n1, the result is undefined. n1 must be an integer or a quad. &&& @ @ ( v -- x ) Fetches the value of a variable. The top element of the stack must be a variable; its value is fetched and replaces the variable on top of the stack. &&& O_CREAT A constant for use with sys-open that specifies that the file is to be created if it doesn't already exist. Has no effect if the file already exists. &&& O_EXCL A constant for use with sys-open that specifies that an error is to be returned if the file already exists. Using this together with O_CREAT allows unambiguous atomic file creation. &&& O_RDONLY A constant for use with sys-open that specifies that the file is to be opened for read-only access. &&& O_RDWR A constant for use with sys-open that specifies that the file is to be opened for read/write access. &&& O_TRUNC A constant for use with sys-open that specifies that the file is to be truncated to zero size. &&& O_WRONLY A constant for use with sys-open that specifies that the file is to be opened for write-only access. &&& SEEK_CUR A constant for use with sys-lseek, which specifies that the seek is to be relative to the current position in the file. &&& SEEK_END A constant for use with sys-lseek, which specifies that the seek is to be relative to the end of the file. &&& SEEK_SET A constant for use with sys-lseek, which specifies that the seek is to be relative to the beginning of the file. &&& ^ ^ ( n n -- n ) Returns the bitwise XOR of its operands. See "man bit-types" for more. &&& abs abs ( n -- n ) Returns the absolute value of its argument. Except as regards errors, this is equivalent to "dup 0 < if neg then". &&& acos acos ( n -- f ) Computes the arc-cosine, in radians, of its argument. &&& acosh acosh ( n -- f ) Computes the hyperbolic arc-cosine of its argument. &&& addlink addlink ( d1 d2 -- ) Links d1 to d2, much like the @link game command. The program must be able to build. If d1 is an exit, then except for wizard programs, it must be owned by the effective player, unless it has no links currently, and in any case the effective player is charged for the link. If d1 is is a player, thing, or room, then except for wizard programs, the effective player must control d1, and it must be possible for the effective player (or for wizard programs, d2's owner) to perform the link. Programs and daemons are not acceptable as d1. &&& addpennies-wizonly [This entry is here to avoid throwing away the documentation for this variant of addpennies. There is no addpennies-wizonly primitive.] addpennies ( d i -- ) Gives i dollars to d. Works only for wizard programs. d may be a player or a thing; i may be positive or negative. Things may not have their money supply reduced below 1; players' money supply is unrestricted. &&& addpennies-conserving [This entry is here to avoid throwing away the documentation for this variant of addpennies. There is no addpennies-conserving primitive.] [addpennies-conserving is the current variant; see "man addpennies".] &&& addpennies addpennies ( d i -- ) Gives i dollars to d. Wizard programs are allowed to use addpennies without restriction to change the money supply of players or objects; the following apply to all other uses: - The dbref must refer to a player, or an error occurs. - The money is taken away from the program's owner. - If the amount is negative, money is transferred in the other direction. - If the program's owner is a wizard, that player's money supply is not affected. Whether the target player is a wizard makes no difference. - No player's money supply may be reduced below 0. - If the game was compiled with a limit on player money amounts, no player's money supply may exceed this limit. Attempts to violate the last two restrictions cause a run-time error. &&& addprop addprop ( d s1 s2 -- ) Adds property s1 to thing d with s2 as the value. Any previous property with the same name is replaced. (For compatability with old versions, addprop also accepts (d s1 s2 i), and ignores the integer.) &&& addprop-if addprop-if ( d s1 s2 -- s / 0 ) If d already has a property s1, its value (as would be fetched by getpropstr) is pushed; otherwise, the property is set to s2 (as if with addprop), and 0 is pushed. This operation is atomic with respect to all other property manipulations. &&& address? address? ( x -- i ) Returns 1 if its argument is an address object, 0 otherwise. (See the ' operator for more information.) &&& afill afill ( x min1 max1 ... minN maxN a ) afill copies the value given (x) throughout part or all of the array. The elements of the array that are affected are those whose subscripts fall in the specified ranges. For example, given a three-dimensional array dimensioned at least "5 4 4", 100 2 4 2 3 1 3 array afill will store 100 into elements (2,2,1), (2,2,2), (2,2,3), (2,3,1), (2,3,2), (2,3,3), (3,2,1), (3,2,2), (3,2,3), (3,3,1), (3,3,2), (3,3,3), (4,2,1), (4,2,2), (4,2,3), (4,3,1), (4,3,2), (4,3,3), just like (but much more efficiently than) 2 4 1 for 2 3 1 for 1 3 1 for 100 4 pick 4 pick 4 pick array aset pop loop pop loop pop loop If both min and max values for any given dimension are -1, they are replaced with 0 for the minimum and the largest legal subscript for the maximum (thus, the entire array can be filled easily by supplying all min and max values as -1). It is not an error for a min value to be larger than a max value, but nothing is filled in that case. &&& aget aget ( i1 ... iN a -- x ) aget fetches an element of an array. The array is on top of the stack, with the subscripts just below it. They are popped; the value retrieved from the array is pushed. &&& aget1d aget1d ( i a -- x ) aget1d fetches an element from an array, just as aget does, except that rather than giving the whole list of subscripts, you give just a single linear subscript, such as would be obtained with array-n-to-1 for the same array. &&& and and ( x1 x2 -- i ) Logical AND. The result is 1 if neither argument is false and 0 otherwise (see `man logic'). &&& array1size array1size ( a -- n ) Returns the total size of an array, the total number of elements in it. This is the product of all the dimensions. Valid subscript arguments for aset1d and aget1d range from 0 to one less than this number, which is useful if you wish to do something to all elements of an array and you don't care what order you access them in. (A zero-dimensional array will of course have an array1size of 1.) &&& array-1-to-n array-1-to-n ( i a -- i1 ... iN N ) array-1-to-n converts a linear array subscript to its corresponding multidimensional indices; it also pushes the number of indices (the dimensionality of the array) for the convenience of code that wants to use this but doesn't know the dimensionality of the array at compile time. This is the converse of array-n-to-1; see that for further discussion. &&& array-n-dims array-n-dims ( a -- i ) array-n-dims returns the number of dimensions of its array argument. &&& array-n-to-1 array-n-to-1 ( i1 ... iN a -- i ) array-n-to-1 converts a multidimensional array subscript to a linear index into the array. Arrays are stored linearly; currently, the linearization simply multiples each subscript by the product of all less-significant dimensions, such that the last subscript (closest to the top of the stack) varies the fastest, but since no part of this is guaranteed, array-n-to-1 is provided to convert from multidimensional indexing to linear indexing. (This is how to obtain an index for use with aset1d and aget1d.) &&& array? array? ( x -- i ) Returns 1 if its argument is an array, 0 otherwise. &&& arrayshape arrayshape ( a -- i1 ... iN N ) arrayshape returns the dimensions used to create the array: the dimensions, with their count. &&& aset aset ( x i1 ... iN a -- ) aset sets an element of an array. The array is on top of the stack, the subscripts just below it, and the new value below that. The given value is stored into the array element corresponding to the subscripts. &&& aset1d aset1d ( x i a -- ) aset1d stores into an array, just as aset does, except that rather than giving the whole list of subscripts, you give just a single linear subscript, such as would be obtained with array-n-to-1 for the same array. &&& asin asin ( n -- f ) Computes the arc-sine, in radians, of its argument. &&& asinh asinh ( n -- f ) Computes the hyperbolic arc-sine of its argument. &&& atan atan ( n -- f ) Computes the arc-tangent, in radians, of its argument. &&& atan2 atan2 ( ny nx -- f ) Computes the arc-tangent of ny/nx, but does not actually perform the division; it also does proper quadrant handling depending on the signs of nx and ny. &&& atanh atanh ( n -- f ) Computes the hyperbolic arc-tangent of its argument. &&& atof atof ( s -- f ) Converts a string to a float. If the string doesn't look like a number, the result will be 0. &&& atoi atoi ( s -- i ) Converts a string to an integer. If the string doesn't look like a number, the result will be 0. &&& atoq atoq ( s -- q ) Converts a string to a quad. The string representation of quads is unadorned hexadecimal. &&& awake? awake? ( d -- i ) Given the dbref of a player, this returns the number of times that player is connected. If given a non-player, it will always return 0. &&& backlinks backlinks ( d -- d1 d2 ... dN N ) Given an object, this returns a list of the objects which are linked to it. &&& backlocks backlocks ( d -- d1 d2 ... dN N ) Given an object, this returns a list of the objects which are locked and whose locks involve it. &&& backprops backprops ( d -- d1 d2 ... dN N ) Given an object, this returns a list of objects which have dbref-valued properties with this object as value (An object which has multiple properties pointing to the argument may or may not appear multiple times.) &&& begin This is equivalent to "do"; see `man do'. &&& break break ( -- ) break causes an immediate unconditional exit from the smallest enclosing do or for loop (see `man do' and `man for'). Control passes immediately to a point just after the closing "loop", "repeat", or "until". &&& builder? builder? ( d -- i ) Returns true if the dbref is a builder. Precisely what this means can be changed at compile time, but for players it corresponds to the ability to use builder commands like @create and @dig, and typically is equivalent to something like `dup wizard? swap "b" flag? or'. &&& call call ( d -- ? ) Call hands execution over to a program specified by the dbref on the top of the stack. You either have to own the program being called or it has to have its L flag set. Be aware that when the program called finishes, it returns control to the caller, and the stack will be in the state that the called program left it in. &&& caller caller ( -- d ) Returns the player that called the first program in the chain of calls that eventually led to this program being executed. &&& callers callers ( -- d1 d2 ... dN N ) This returns a rudimentary stack trace. The list pushed onto the stack is a trace of the chain of calls by which control arrived in the program being executed: dN called dN-1 which called ... which called d2 which called d1 which called the program being executed. &&& caps caps ( s -- s ) Uppercases the first character of the string, lowercases the rest. &&& cbrt cbrt ( n -- f ) Computes the cube root of its argument. &&& ceil ceil ( f -- i ) Converts a float to an integer, rounding towards positive infinity. &&& changeprop changeprop ( d sp o n -- 1/0 ) This does a compare-and-conditionally-set on a property's value. If there is a property named sp on d with value o, the property's value is changed to n and 1 is returned; otherwise, no property changes are made and 0 is returned. This operation is atomic with respect to all other property manipulations. o and n each may be strings or dbrefs, and they do not need to be the same type. A property of one type is never considered equal to a value of the other type. Note that changeprop works only for strings and dbrefs. In particular, it cannot create anyval properties and it considers anyval values unequal to strings and dbrefs even if the actual value is indeed an equal string or dbref. &&& chown chown ( d1 d2 -- ) Changes ownership of d1 to d2. &&& conboot conboot ( i -- ) [wizard] Boots a specific connection. This is the only way to forcibly disconnect only one connection of a player who is connected multiple times. If invalid, nothing happens. &&& concount concount ( -- n ) Returns the number of connections to the muck. This includes connections that have not yet issued a `connect' command to connect to a character. &&& condbref condbref ( i -- d ) Returns the dbref of the player connected on a connection. If the connection has not yet connected to a character, #-1 is returned. If invalid, #-4 is returned. &&& conforce conforce ( i s -- ) [wizard] Works like force (see "man force"), except that it affects a connection rather than a player. Since most commands are not connection-specific, this will usually have the same effect as force on the player connected on that connection, but this can be used for commands like QUIT and OUTPUTFOLD that force can't. The descriptor does not have to be connected to a player (yes, you can conforce a "connect" command). If invalid, nothing happens. &&& conhost conhost ( i -- s ) [wizard] Returns the name of the host from which the specified connection was made, "" if invalid. &&& conidle conidle ( i -- i ) Returns the idle time for a connection, measured in seconds, -1 if invalid. &&& connected? connected? ( i -- i ) Returns true if there is a connection on the specified descriptor. This will return true for connections that have not yet connected to a player; condbref can be used to distinguish. This is an exception to the rules described in "man invalid-con"; it never produces errors when passed invalid connection numbers, even if the argument is positive (it returns false in such cases). &&& connections connections ( -- d1 d2 ... dN N ) Returns a list of all connected descriptors. &&& connotify connotify ( i s -- ) [wizard] Writes the string to a connection. If invalid, nothing happens. &&& contents contents ( d -- d ) Returns the first thing contained in a dbref. `next' should be used to step through the list of contents. Note that moving things into or out of the containing thing can invalidate this list; care is called for. &&& contime contime ( i -- i ) Returns the time since the descriptor connected, in seconds, -1 if invalid. &&& continue continue ( -- ) continue causes the current iteration of the smallest enclosing do, for, or begin-while loop (see `man do', `man for', and `man while') to end and the next to begin. Thus, it's equivalent to braching to a point immediately before the closing "loop". &&& conuser conuser ( i -- s ) [wizard] Returns the username reported by the RFC-1413 daemon on the host from which the specified connection was made, or a string describing why such a username is unavailable. If invalid, "" is returned. &&& copy copy ( x1 ... xN N -- x1 ... xN x1 ... xN ) Copies the top N elements of the stack. If N is less than zero, an error occurs. &&& copyobj copyobj ( d -- d ) Clones the thing and returns the copy. Works only for objects, not players, rooms, exits, etc. In most respects, the copy is identical to the original; it differs only in that it has a different dbref number (of course) and that it has no actions attached to it. All other fields - property list, description, etc - are copied. The program must be able to build; except for wizard programs, the effective player is charged for the copy. The copy is owned by the same player as the original and is placed in the effective player's inventory. &&& cos cos ( n -- f ) Computes the cosine of its argument, in radians. &&& cosh cosh ( n -- f ) Computes the hyperbolic cosine of its argument. &&& create create ( s i -- d ) Creates an object with the string as its name and the number as its cost. The new object is owned by the effective player and is placed in that person's inventory. The program must be able to build, and except for wizard programs, the effective player is charged for the object. &&& critical ( x -- ) Marks a critical-section word. This pops a value off the stack and saves it. Once this is done, if the server context-switches to another thread before the currently-executing word - the one that called critical - returns, three things will happen: - The stack will be popped, if necessary, so that it is no deeper than it was when critical was executed. - x will be pushed. - `exit's will be done, as many as necessary to return from the word that called critical. These happen between the time the last primitive runs in the executing thread and the time the first primitive runs in the switched-to thread. As this implies, the aggregate of the above three actions is atomic. If the calling word returns before a context switch happens, the critical section is canceled: the saved value of x is thrown away and nothing else happens. Doing a sleep silently cancels the critical section. Using fork causes the new daemon to not be in a critical section; it does not disturb any critical section in effect in the old thread, and does not trigger the above actions. If the program drops into interactive mode (eg, calls read), the critical section is silently canceled. If another critical is attempted before the critical section triggers or is canceled, an error occurs. It is normally good practice to do a yield immediately before doing a critical, to ensure as large a quantum as is available. &&& ctime ctime ( i -- s ) Convert a time value, such as is returned by systime, to a human-readable string. (For those who know C, this is done with asctime(localtime(...)), with the trailing newline removed.) &&& current-frame-id current-frame-id ( -- q ) Returns the current execution frame's serial number. &&& daemon daemon ( -- d ) Returns the dbref of the daemon that executes the call. If the code is being run by a player instead of a daemon, returns #0. (#-1 would make more sense, granted.) &&& daemon? daemon? ( d -- i ) Returns true if the dbref refers to a daemon, false otherwise. &&& daemons daemons ( -- d ) Returns the first in a list of all daemons in the system (if there are no daemons, #-1 is returned). The `next' primitive can be used to step through the list. &&& date date ( -- d m y ) Returns the current date. y includes the century number. m is 1..12; d is 1..28, 1..29, 1..30, or 1..31 depending on y and m. Note that the returned values apply to the timezone the muck is running in, which doesn't necessarily bear any relation to the timezone any particular player is in. &&& db_top db_top ( -- i ) Returns the lowest dbref number that does not exist at all (that is, one more than the highest dbref that does exist). The returned value is an integer; see `man dbtop'. &&& dbcmp dbcmp ( d1 d2 -- i ) Returns true if d1 and d2 are identical (both must be dbrefs). Neither one need be a valid dbref. Note that unlike strcmp, this returns true if the dbrefs are equal. &&& dbref dbref ( i -- d ) Converts an integer to the corresponding dbref. No checks are made; if the integer is out of range, the result will not be a valid dbref. &&& dbref? dbref? ( x -- i ) Returns true if the thing is a dbref (room, player, object, etc), false if it's anything else (integer, string, etc). &&& dbtop dbtop ( -- d ) Returns the highest valid dbref. Identical to `db_top 1 - dbref' (except that it doesn't need an extra space on the stack, compiles to one instruction instead of 4, and is correspondingly faster). &&& depth depth ( -- i ) Returns the number of things on the stack. (The number returned is the count of things on the stack *before* the result is pushed; thus, the smallest possible returned value is 0, not 1.) &&& desc desc ( d -- s ) Returns the description string of a dbref. &&& dig dig ( s dp -- dr dp ) Digs a new room with name s and parent room dp; the new room (dr) is pushed on the stack and then the parent is pushed as well. (I'm not sure why the parent is pushed back on.) The program must be able to build, the effective player must be able to link rooms to the parent, and except for wizard programs, the effective player is charged for the room. The new room inherits its J flag setting from the effective player's J flag setting. &&& do do ( -- ) loop ( -- ) format: do loop do repeats body between the do and the loop indefinitely. This loop can be broken only by an exit, break, or while within it, an interpreter error, or (if it's running in a daemon) by killing the daemon. See also `man break', `man while', and `man continue'. &&& drop drop ( d -- s ) Returns the drop message of a dbref. &&& dup dup ( x -- x x ) Duplicates the top element of the stack. &&& e e ( -- e ) Returns e (2.7182818etc). &&& eif See `man if'. &&& else See `man if'. &&& exec exec ( ptr -- ) This takes a pointer to a word on top of the stack and executes the word it points to. See ' for more information. &&& execute execute ( addr -- ) This takes an address on top of the stack and executes the word it points to. See ' for more information. &&& exit exit ( -- ) Exits from the word it appears in, returning to whatever called that word. &&& exit? exit? ( x -- i ) Returns true if the argument is an exit dbref; otherwise (if the argument is not a dbref, or is some other kind of dbref), returns false. &&& exits exits ( d -- d ) Returns the first exit of a dbref. The `next' primitive can be used to step through the list. &&& exp exp ( n -- f ) Computes the natural antilogarithm of its argument (the e^x function). Mathematically, this is equivalent to "e swap pow", but exp is likely to be both more accurate and more efficient. &&& explode explode ( sA sB -- sN ... s1 N ) explode ( sA i -- sN ... s1 N ) If the second argument is a string: Breaks sA into pieces, with occurrences of sB being the boundaries. Pushes the pieces and the number of pieces. Note that multiple consecutive occurrences of sB will produce empty strings in the resulting list. The pieces are pushed in reverse order. "this is a test" " " explode => "test" "a" "is" "this" 4 "foo bar" " " explode => "bar" "" "foo" 3 "a$b@c$@d$e@f" "$@" explode => "d$e@f" "a$b@c" 2 "this is a test" "xx" explode => "this is a test" 1 If the second argument is an integer: Breaks sA into pieces, each piece being i characters long (except for sN, which may be shorter). If sA is "", no pieces are pushed, and N is zero. i must be greater than zero. "KhKdKcKs" 2 explode => "Ks" "Kc" "Kd" Kh" 4 "hello" 1 explode => "o" "l" "l" "e" "h" 5 "" 8 explode => 0 "hello there" 5 explode => "e" " ther" "hello" 3 &&& explode1 explode1 ( sA sB -- sA2 sA1 1 ) [or] ( sA sB -- sA 0 ) Breaks sA at the first occurrence of sB within it. The part after the break (sA2) is pushed, then the part before the break (sA1), then 1. If sB does not occur within sA, sB is popped but sA is not, and 0 is pushed. Note carefully how the return values are defined in comparison to rexplode1. &&& expm1 expm1 ( n -- f ) Computes (e^x)-1 (the same value that "exp 1 float f-" ideally would), but does so in a way that avoids the loss of significance that would occur with the simplistic implementation when the argument is very close to zero. &&& fail fail ( d -- s ) Returns the fail message for a dbref. &&& flag? flag? ( d s -- i ) The second argument must be a valid flag name or abbreviation. The flag? primitive returns true if the flag is set on the dbref, false otherwise. &&& flagbit flagbit ( s -- i ) Converts a flag's name to the corresponding bit. This is suitable for testing against getflags's return value with &. &&& flagstr flagstr ( d -- s ) Returns the short flag string for a dbref, with each flag represented by a single character (eg, Pmb or Rnjhv). &&& float float ( i -- f ) Converts the integer to a float. &&& float? float? ( x -- i ) Returns 1 if its argument is a floating-point number, 0 otherwise. &&& floor floor ( f -- i ) Converts a float to an integer, rounding towards negative infinity. &&& for for ( i i i -- i ) format: for <> loop The parameters to the for primitive are: the starting number, the ending number, and the size of the step [size of 0 will result in an endless loop]. The for primitive pushes the current value onto the stack and then executes the block of code. The body is always run at least once, even if the arguments would seem to imply otherwise. For example, `1 4 1 for dup loop' will push the same numbers on the stack that `1 1 2 2 3 3 4 4' would. See also `man break' and `man continue'. &&& force force ( d s -- ) The dbref must be a player. This causes the string to be executed as a command, as if the player had typed it. This does not work for commands such as QUIT or OUTPUTPREFIX which affect the connection rather than the player; see "man conforce". Except for wizard programs, the player who owns the program and the player being forced must be the same. (The effective player is irrelevant.) &&& fork fork ( -- i ) Creates a new daemon (see `man sleep', `help @ps', and `help @kill' for more info). In the old thread, the number pushed is the number of the dbref of the new daemon (as integer, not dbref, type); in the new daemon, the number pushed is zero. The new daemon is executing the same code its parent thread was, at the same place; the only difference is the value pushed onto the value stacks by the fork call. &&& forward forward word Normally, a word must be defined before it can be called. A "forward" declaration relaxes this, allowing you to call the word before it is defined. (You must eventually define the word, or an error results.) &&& frame-id-busy? frame-id-busy? ( q -- 0/1 ) Tests whether a particular execution frame, identified by its serial number (as returned by current-frame-id), is still active (indicated by return value 1) or not (0). &&& frandom frandom ( -- f ) Returns a random floating-point in [0..1), that is, less than 1 but not less than 0. &&& frexp frexp ( f -- f i ) Finds the floating and integer values f and i such that its argument can be written as f*(2^i), with f having absolute value in [.5,1), unless the argument is zero, in which case both returned values are 0. &&& ftoq ftoq ( f -- q ) Converts a float to a quad. The float must be nonnegative, and if it is larger than the largest possible quad the result will be some quad, but its value is undefined. &&& getflags getflags ( d -- i ) Returns all the flags of a dbref, as an integer. This is of little use, as there is no corresponding setflags, and the bit definitions are undocumented and liable to change between versions of the system, but the various flags do correspond to bits in the integer. See also `man flagbit'. &&& getlink getlink ( d -- d ) Returns the thing a dbref is linked to. If the argument is an exit that is linked to more than one thing, only the first thing is returned; use getlinks if you need to access the others. &&& getlinks getlinks ( d -- d1 d2 ... dN N ) Returns all the things a dbref is linked to. If the argument is a room, thing, or player, the list contains only one dbref, its drop-to or home (as appropriate), unless it's #-1, in which case the list is empty (ie, N is 0). If the argument is an exit, the list consists of all things the exit is linked to. If the argument is anything else, the list is empty. &&& getpropperm getpropperm ( d s -- q ) Returns a property's permissions bit vector, as a quad. If the property does not exist or BIT-X permission is denied, the result will be zero. &&& getpropstr getpropstr ( d s -- s ) Fetches a property string. The first argument is the dbref whose property list is to be accessed; the second is a string naming the property. The result is the string value of the property, or "" if the property is not set. Dbref-valued properties are converted to strings of the form "#nnn"; anyval properties are converted to "" (even if the actual value is a string). If the property exists but R permission is denied, what happens depends on X permission: if X permission is granted, an error occurs, but, if not, "" is returned. &&& getpropval getpropval ( d s v -- v' ) Fetches a property value. The first argument is the dbref whose property list is to be accessed; the second is a string naming the property. If the property exists, the third value is ignored and the return value is the property's value; otherwise, the third value is used as the retyurn value. Even when the property exists, the return value can be of any type, since the property may be an anyval property. (If the property exists but R permission is denied, if X permission is granted, an error occurs, but, if not, it is as if the property did not exist.) &&& gmtmerge gmtmerge ( i i i i i i i i -- i ) Converts a split-up time (see `man timesplit') to a timestamp value, interpreting the arguments as being UTC (nee GMT). &&& gmtsplit gmtsplit ( i -- i i i i i i i i ) Splits a timestamp value into a split-up time (see `man timesplit'), converting it to UTC (nee GMT) values. &&& god? god? ( d -- i ) Returns 1 if the argument has god privileges, 0 if not. Precisely what this means can be changed at compile time; it is typically equivalent to something like `dup #1 dbcmp swap "g" flag? or'. &&& hypot hypot ( n1 n2 -- f ) Computes sqrt((f1*f1)+(f2*f2)) (like "dup * swap dup * + sqrt"), but does so in a way that avoids unwarranted overflow. &&& if if ( i -- ) basic format: if [else ] then The if command will execute the block between it and the then (or the else, if present) if the value on the top of the stack is true. If the value is false, it will execute the block between the else and the then, if any. The test value is popped from the stack before either block is executed. (See `man logic' for the definitions of true and false.) An additional primitive, eif, is available, which functions as an "else if" conditional: the code between the else and the eif is executed, and if the top of the stack is true, the block after the eif is executed, otherwise control passes to the next else: if else eif else .... then This is equivalent to if else if else .... then then except that only one then is needed to close the whole structure. &&& ilimit ilimit ( -- i ) Returns the iteration count limit. If a program attempts to execute more than this many iterations, a fatal error will be generated. &&& implode implode ( sN ... s1 N sB -- sA ) implode concatenates the list of strings s1 through sN, placing sB between them. Thus, this is the converse of explode, though there is no requirement that s1...sN are in fact what would be produced by exploding sA with sB; in particular, "" implode can be used as a multi-string strcat (but with the pieces in reverse order from the way strcat would take them - see rimplode). &&& instr instr ( s1 s2 -- i ) Finds s2 within s1, returning the offset of the first such occurrence, or 0 if s2 does not occur within s1. (The returned offset is 1-origin, that is, if s2 occurs at the very beginning of s1, the returned value is 1.) &&& instring instring ( s1 s2 -- i ) Just like instr, except that the matching is done case-independent. &&& int int ( d -- i ) Converts a dbref to its integer index in the database. (This actually works for variables as well, returning the variable number, though MUF variables are of questionable utility in any case.) &&& int? int? ( x -- i ) Returns 1 if its argument is an integer, 0 otherwise. &&& intostr intostr ( n -- s ) Converts a number to a string. This is the converse of atoi and atof. &&& itoq itoq ( i -- q ) Converts an integer to a quad. The integer must be nonnegative. &&& kill kill ( d -- ) Kills a daemon, as identified by its dbref. The daemon being killed will execute no further code after this call. Thus, for example, a daemon can commit suicide with [ daemon kill ]. (This will work only when the code is actually being run by a daemon; to force a program into a daemon, [ 0 sleep ] can be used - [ 0 sleep daemon kill ] is the idiom to unconditionally abort execution.) &&& ldexp ldexp ( f i -- f ) Computes f*(2^i), but does so efficiently by manipulating the floating-point representation rather than by performing an exponentiation and a multiplication. (This is the inverse of frexp, though there is no requirement that the arguments be such as frexp could return.) Note that the first argument must be a float. &&& linkcount linkcount ( d -- i ) Returns the link count of a dbref. For players, always returns 1; for programs and daemons, always returns 0. For objects, returns 1 if the object has a home, otherwise 0; for rooms, returns 1 if the room as a drop-to, otherwise 0. For exits, returns the number of things the exit is linked to (0 if unlinked). &&& location location ( d -- d ) Returns a thing's location. For players, this is the room the player is in; for objects and programs, the room or player. For rooms, it is the room's parent. For exits, it is the thing the exit is attached to. For daemons, I'm not sure what it does. &&& lock lock ( d s -- ) Locks a dbref. s is a string giving the lock expression. If s is "", the dbref is unlocked. (unlock can also be used to unlock a dbref.) &&& locked? locked? ( d -- i ) Returns true if the dbref is locked, false if it's unlocked. &&& lockstr lockstr ( d -- s ) Returns the lock of the dbref as a string. If the dbref is not locked, "" is returned. The resulting string is acceptable to the lock primitive, but is generally not appropriate for human interaction. See also unparse_lock. &&& log log ( n -- f ) Computes the natural logarithm of its argument. &&& log10 log10 ( n -- f ) Computes the common (base 10) logarithm of its argument. &&& log1p log1p ( n -- f ) Computes log(1+x) (the same value that "1 + log" ideally would), but does so in a way that avoids the loss of significance that would occur with the simplistic implementation when the argument is very close to zero. &&& loop loop terminates a for, while, or do loop. See `man for', `man while', and `man do'. &&& match match ( s -- d ) Matches a string, returning the dbref of the matched thing. If the match fails, #-1 is returned; if the match is ambiguous, #-2 is returned. (#-3 is returned if the string is "home".) &&& memused memused ( d -- i ) Calculates the amount of memory used by a dbref. &&& moveto moveto ( d1 d2 -- ) Moves d1 to location d2. Unfortunately this is fairly restrictive; several restrictions apply. They are rather complicated and the details vary depending on the type of thing being moved. In all cases, though, the thing being moved must either be set J(ump_OK) or be owned by the effective player running the program (exception: wizard programs are free from this restriction). To see the other restrictions, ask for `man moveto-', where is the type of the thing being moved: player, thing, room, or exit (programs are treated as things for the purposes of moveto). (Eg, `man moveto-player' to see the restrictions that apply when moving a player with moveto.) Objects of other types (eg, daemons) cannot be moved with moveto at all. To send a player or thing to its home, #-3 can be given as the destination. &&& mpop mpop ( x1 ... xN N -- ) Pops many things off the stack at once. This functions identically to : mpop begin dup 0 > while 1 - swap pop loop pop ; except as regards errors (for example, a negative N is an error). &&& mucker? mucker? ( d -- i ) Returns 1 if the thing has mucker privileges, 0 if not. Precisely what this means can be changed at compile-time; it is typically equivalent to something like `dup wizard? swap "m" flag? or'. For players, this corresponds to permission to use the @prog and @edit commands. &&& multisubst multisubst ( s sA1 sB1 sA2 sB2 ... n -- s' ) Performs multiple "subst" operations (qv) in parallel. The s argument is scanned, looking for any of the the sB strings. (The n argument specifies the number of sA/sB pairs present.) Whenever an sB string is found, it is replaced with the corresponding sA string; the scan then continues after the replacement, much as for subst. In general, it's preferable to use multisubst when possible instead of multiple calls to subst, both for efficiency reasons and because multisubst avoids the potential problems resulting from the possibility that one search-for string may occur inside an earlier replace-with string: "you give *a the *b" "-*b*-" "*a" subst "widget" "*b" subst -> "you give -widget*- the widget" but "you give *a the *b" "-*b*-" "*a" "widget" "*b" 2 multisubst -> "you give -*b*- the widget" If two of the sB strings are identical but have differing sA strings, and that sB string is found in the s string, which sA string gets used is undefined and may vary from moment to moment, even from occurrence to occurrence within a single multisubst operation. &&& name name ( d -- s ) Returns a dbref's name. &&& neg neg ( n -- n ) Negates its argument. Except as regards errors, this is equivalent to "-1 *". &&& newarray newarray ( i1 ... iN N -- a ) Creates a new array. N is the number of dimensions the created array has; the actual dimensions are given by N numbers on the stack. There are limits on the number of dimensions, on the individual dimensions, and on the total size of the array; exceeding these limits produces a run-time error. (At this writing, these limits are 16 dimensions, 16384 maximum for any one dimension, and 65536 maximum total size.) The initial contents of the array are unspecified. All operations on the array must use the number of subscripts specified when the array was created. An array may have zero dimensions (such arrays have exactly one element), but it may not have a zero size in any dimension. Array subscripts range from zero to one less than the number given. &&& next next ( d -- d ) If the dbref is an exit, returns the next exit in the internal list of exits attached to the object the exit is attached to. If the dbref is some other type, returns the next object in the list of contents in the object's containing object. If the dbref is a daemon, returns the next daemon. This is intended to be used to step down a list obtained with the contents, exits, or daemons primitive. #-1 is returned to indicate the end of the list. Note that to step down a list, each call to next should pass as argument the previous thing in the list, not the head of the list. For example, to scan all a player's exits, you might do something like : process-this-exit ( exit -- ) .... ; : scan-my-exits me @ exits begin dup while dup process-this-exit next loop pop ; If the list changes while such a traversal is in progress, the traversal may misbehave in various ways, but, provided the changes eventually stop, the loop will eventually terminate also. &&& nextowned nextowned ( d -- d ) Returns the next object in the internal list of objects owned by the owner of the specified object. This is intended to be used to step down the list of everything owned by a player. (The proper way to start such a loop is to use the player itself as the beginning of the list.) #-1 is returned to indicate the end of the list. &&& nop nop ( -- ) Does nothing. Doesn't even show up on debug traces. This exists mainly for internal reasons, though it can be used as a placeholder where an empty block is not allowed (such as the body of a word that is supposed to do nothing). &&& not not ( x -- i ) Returns 1 if its argument is false, 0 if its argument is true. (See `man logic' for a description of what is considered false and true.) &&& notify notify ( d s -- ) Sends the string to the dbref. If the dbref is a player, the string is sent to all of that player's connections. If the dbref is a player or thing, all hear exits attached to it are activated. If the dbref is of any other type, nothing happens. &&& notify_except notify_except ( d1 d2 s -- ) Sends the string to everything contained in d1, which must be a room, except that if d2 is one of the things contained in d1, it does not get notified. To not omit anything, d2 can be #-1. (Notification is done as if with the notify primitive.) In addition, any hear exits attached to d1 or any of its ancestors are activated. Any hear exits attached to the player running the program are also activated [may be the effective player, but I think not]. &&& notify_exclude notify_exclude This primitive is not yet implemented; its intent is to behave like notify_except, but to specify more than one dbref to be excluded from the notification. &&& number? number? ( s -- i ) Returns 1 if the argument is a string which contains a valid number, 0 if the argument is not a string or doesn't look like a number. &&& numowned numowned ( d -- i ) Returns the number of dbrefs owned by the player who owns the argument dbref. Wizard programs may use this with any dbref; for other programs, the player whose ownership count is to be computed must be the player running the program (or if running in a daemon, the player owning the daemon.) &&& odrop odrop ( d -- s ) Returns the odrop message on the argument dbref, or "" if the dbref has no odrop message. &&& ofail ofail ( d -- s ) Returns the ofail message on the argument dbref, or "" if the dbref has no ofail message. &&& ok? ok? ( d -- i ) Returns true if the dbref is a valid object: its number is not less than 0 or larger than the current size of the database, and is not a garbage object. &&& online online ( -- d1 ... dN N ) Returns a list of players online. Players connected more than once appear in the list more than once. The list is in an unspecified order (currently, the order it happens to be kept in internally, which is not useful to MUF programmers). &&& open open ( s d -- d ) Opens a new exit with the specified name, attached to the specified dbref. The new exit's dbref is left on the stack. The new exit is owned by the effective player, but is not linked (note that linking an unlinked exit affects its owner). The program must be able to build, and except for wizard programs, the effective player (a) must own the argument dbref and (b) is charged for the exit. &&& or or ( x x -- i ) Returns 1 if either of its arguments is true, otherwise 0. (See `man logic' for a description of what is considered true and false.) &&& osucc osucc ( d -- s ) Returns the osuccess message on the argument dbref, or "" if the dbref has no osuccess message. &&& over over ( x1 x2 -- x1 x2 x1 ) Duplicates the next-to-topmost thing on the stack, pushing it on top, over the topmost thing. &&& owner owner ( d -- d ) Returns the dbref of a dbref's owner. &&& passlock? passlock? ( d1 d2 -- i ) Returns 1 if d1 passes the lock on d2, otherwise 0. If d2 is not locked, this will always return 1. &&& passwordchk passwordchk ( d s -- i ) The dbref must be a player (or an error occurs). If the string is the correct password for the player, 1 is returned; otherwise, 0 is returned. Two notes apply to non-wizard programs: (1) the dbref argument must be the effective player and (2) a 0 return value costs the caller the rest of its timeslice quantum. &&& pennies pennies ( d -- i ) Returns the amount of money of a dbref. The argument must be a player or thing. &&& pi pi ( -- pi ) Returns pi (3.14159etc). &&& pick pick ( x1 ... xN N -- x1 ... xN x1 ) Copies the Nth item down on the stack, pushing the copy on top of the stack. Thus, for example, 1 pick is equivalent to dup and 2 pick is equivalent to over. &&& player? player? ( x -- i ) Returns true if the argument is a dbref that refers to a player, 0 if it's not a dbref or is some other type of dbref. &&& plt? plt? ( x -- i ) Returns 1 if its argument is a property-list traversal object, 0 otherwise. See `man propfirst' for more. &&& pop pop ( x -- ) Pops the top element off the stack and throws it away. &&& pow pow ( n1 n2 -- f ) Raises n1 to the power n2. Note that the result is always a float, even when both arguments are integers. &&& prog prog ( -- d ) Returns the dbref of the program the call occurs in. &&& program program ( s -- d ) [wizard] Creates a new program, with name and description set to the string from the top of the stack. The new program's dbref is returned. The program's text is empty. (There is currently no way to get text into a program from MUF, except by conforceing a connection connected to a player who can edit it; this primitive exists largely for de-archiving code.) The program is owned by the effective player and is created in that player's inventory. &&& program? program? ( x -- i ) Returns true if the argument is a dbref that refers to a program, 0 if it's not a dbref or is some other type of dbref. &&& prompt prompt ( s -- s' ) Like read, but prints its argument string first, without a line break following it, as a prompt. (This message is invisible to hear exits.) If the argument is "", this is equivalent to read (except that it pops its argument string). &&& pronoun_sub pronoun_sub ( d s -- s ) Performs pronoun substitution on the string, using the dbref as the source of replacement strings. Pronoun substitution is done with % signs in the string. When a % occurs, the following character determines what the pair is replaced with. In most cases, the _sex: property on the dbref also affects the result, and in some cases the dbref's name (which is assumed to be "Name" in the table below). First, the % and the following character are taken as a two-character property name which is looked for on the dbref. If it's found, the property string value is used as the replacement string. Otherwise, the following table describes the replacement string. _sex:male _sex:female _sex:neuter other %a his hers its Name's %s he she it Name %o him her it Name %p his her its Name's %r himself herself itself Name %n Name Name Name Name If the character after the % is uppercase, the first character of the replacement string is uppercased, except when the replacement comes from the "other" column of the table; in that case, the initial character is left alone. (I don't know why this is, particularly when the %n row and properties get the capitalization.) If the sequence is not one given in the table and no property is found, the % is dropped and the following character retained as the replacement. (In particular, to get a % into the output string, use %% in the argument string.) &&& prop-exists? prop-exists? ( d s -- i ) Returns 1 if the specified dbref has a property whose name is the given string, 0 otherwise. The value of the property is irrelevant; thus, this is more reliable than calling getpropstr and checking to see whether the result is "", since a property can exist with "" as its value. &&& propfirst propfirst ( d [i] -- t s 1 ) [or] ( d [i] -- 0 ) Basic operation: if the dbref has any properties, a property-list traversal object is pushed on the stack, then the first property's name, then 1; if the dbref has no properties, it is popped from the stack and 0 is pushed. (The number is intended to be used by a conditional of some sort, with the string used by further code, with the property-list traversal object ready to hand to propnext.) The integer argument holds flags; each bit of it is potentially a different flag. At present, the defined flags are: 1 Include string-valued properties 2 Include dbref-valued properties 4 Include anyval-valued properties Undefined flag bits, if set, are ignored. The integer can be omitted; if this is done, 1 is supplied. See propnext for more information. &&& propnext propnext ( t -- t s 1 ) [or] ( t -- 0 ) Given a property-list traversal object, propnext returns the next property's name and 1, if there are any more properties, or pops the traversal object and returns 0, if not. The order in which properties are accessed by propfirst and propnext is unspecified. What happens if properties are added or deleted during the traversal is also unspecified; however, two things are guaranteed: (1) in the absence of additions to or deletions from proeprties on the dbref, starting with propfirst and iterating with propnext is guaranteed to find all properties the dbref has that the traversal is supposed to see (props the program is not allowed to find or which are suppressed by the flags argument to propfirst will not appear), and (2) even in the presence of property additions or removals during the traversal, looping with propnext is guaranteed to eventually terminate, provided the property additions and deletions eventually stop - it is not possible to get things into a state where a propnext loop on its own is an infinite loop. A property-list traversal object encapsulates the state of the traversal in an unspecified way; it is not good for anything but handing to propnext. However, there is no need to complete the traversal; the traversal object may be discarded at any time by simply popping it from the stack. &&& propperm-bit-c propperm-bit-c ( -- q ) This returns the BIT-C property permission mask. See "man propperm" for more. &&& propperm-bit-d propperm-bit-d ( -- q ) This returns the BIT-D property permission mask. See "man propperm" for more. &&& propperm-bit-f propperm-bit-f ( -- q ) This returns the BIT-F property permission mask. See "man propperm" for more. &&& propperm-bit-r propperm-bit-r ( -- q ) This returns the BIT-R property permission mask. See "man propperm" for more. &&& propperm-bit-w propperm-bit-w ( -- q ) This returns the BIT-W property permission mask. See "man propperm" for more. &&& propperm-bit-x propperm-bit-x ( -- q ) This returns the BIT-X property permission mask. See "man propperm" for more. &&& propperm-how-c propperm-how-c ( -- q ) This returns the HOW-C property permission mask. See "man propperm" for more. &&& propperm-how-l propperm-how-l ( -- q ) This returns the HOW-L property permission mask. See "man propperm" for more. &&& propperm-how-m propperm-how-m ( -- q ) This returns the HOW-M property permission mask. See "man propperm" for more. &&& propperm-who-a propperm-who-a ( -- q ) This returns the WHO-A property permission mask. See "man propperm" for more. &&& propperm-who-o propperm-who-o ( -- q ) This returns the WHO-O property permission mask. See "man propperm" for more. &&& propperm-who-r propperm-who-r ( -- q ) This returns the WHO-R property permission mask. See "man propperm" for more. &&& propperm-who-w propperm-who-w ( -- q ) This returns the WHO-W property permission mask. See "man propperm" for more. &&& pstack pstack ( i -- ) pstack ( i s -- ) The integer argument is taken as a count of stack elements; the top that many elements of the stack are printed. The output goes to the same place the debugging output from programs set D goes. If the string second argument is present, it is printed as a tag at the beginning of the line; otherwise, a default ("Stack" as of this writing) is used instead. There is a length limit (about 500 characters at this writing) on the resulting line; if this is exceeded, remaining elements will be printed as "...". This is intended as a debugging aid. &&& ptr? ptr? ( x -- i ) Returns 1 if its argument is a pointer object, 0 otherwise. See ' for more information. &&& put put ( x1 ... xN y N -- y x2 ... xN ) This simply replaces the Nth element down on the stack, rather like an assignment with the stack treated as an array. &&& qrandom qrandom ( -- q ) This returns random quad, from 0 through the largest possible quad. &&& qtoa qtoa ( q -- s ) This converts a quad to a string. The string representation of quads is unadorned hexadecimal. &&& qtof qtof ( q -- f ) This converts a quad to a float. &&& qtoi qtoi ( q -- i ) This converts a quad to an int. If the quad's value is not representible as an int, some int will still be produced, but no promises are made about its value. &&& quad? quad? ( x -- i ) Returns 1 if its argument is a quad, 0 otherwise. &&& quota? quota? ( d i -- i ) If the dbref argument is not a player, or if the integer argument is less than zero, an error occurs. Otherwise, if the player could build as many dbrefs as the integer argument, 1 is returned, otherwise 0. (If the player is not subject to building quotas - a wizard, for example - then 1 will always be returned.) &&& random random ( -- i ) This returns a random positive integer, from 0 through the largest positive integer the muck can represent. Normally this is followed with a % operation to reduce the range of the number to something useful. &&& re-compile re-compile ( s -- re ) Compiles a regular expression into internal form, suitable for re-match. &&& re-match re-match ( re s -- vN-1 ... v1 v0 N / 0 ) Matches the string against the regular expression. If the match fails, the result is just a 0. If the match succeeds, the substring-matched strings are pushed, from highest number to lowest number; the whole matched string is then pushed, followed by the total number of strings pushed. (N will always be at least 1.) If a (...) pair occurs in the expression but does not match anything, the integer 0 will be pushed instead of a string for the corresponding value. &&& re-subst re-subst ( vN-1 ... v0 N s -- vN-1 ... v0 N s' ) Processes the string as a replacement string for a regular expression substitution. N and the v values are such as would be produced by re-match. The string is scanned, and \0 through \9 are replaced by v0 through v9, respectively, when found. (It is an error if some \X occurs but vX is not a string; vX values that are not referred to are not checked.) Also, \\ is replaced by \. \ before any character other than another \, a digit, or a left parenthesis (see next paragraph) produces undefined results; you may or may not get an error, and if you don't, what you do get is undefined. The arguments do not have to come from re-match, though that is the primary intended use; they can come from anywhere, and N can be greater than 10. To refer to v10 and higher, put parentheses around the digits, as in \(14) to substitute v14. Note that N and the v values are left undisturbed on the stack. Examples: "three" "two" "one" "zero" 4 "<\\1><\\3>" re-subst -> "three" "two" "one" "zero" 4 "" "d" 0 -5 "a" 4 "\\\\--\\0\\3\\0--/" re-subst -> "d" 0 -5 "a" 4 "\\---ada---/" "d" 0 -5 "a" 4 "\\0\\2\\0" re-subst -> an error (Note that \ characters are doubled in the arguments above; this is because you must write \\ between quotes in your MUF program to get a single \ into a string. Be aware also that debugging output does not invert this transformation. Experiment with strings containing \ characters if you're not sure how this works.) &&& read read ( -- s ) Returns a string read from the player. The program must be being run by a player rather than a daemon, or an error is generated. The program stops running and waits until the player types a line of input. This line of input is pushed on the stack as a string, and the program resumes execution at the point just after the read call. (Currently, this does not work in a program being run as part of testing a lock.) &&& recycle recycle ( d -- ) Recycles the dbref, like the @recycle command. The object must be owned by the effective player, even for wizard programs. The object also must not be the program the recycle call appears in, nor any of the programs in its chain of callers. You also can't recycle the global environment or player start rooms, or any daemon, player, or garbage object. &&& regexp? regexp? ( x -- i ) Returns 1 if its argument is a compiled regular expression object, 0 otherwise. &&& remove_prop remove_prop ( d s -- ) Removes the specified property from the specified dbref. If a property with the specified name existed, it is removed; otherwise, nothing happens. &&& remprop-if remprop-if ( d s1 s2 -- i ) If d already has a string-valued property s1 whose value is s2, it is removed and 1 is pushed; otherwise, no property changes occur and 0 is pushed. This operation is atomic with respect to all other property manipulations. &&& repeat repeat is equivalent to loop; it terminates a for, while, or do loop. See `man for', `man while', and `man do'. &&& rexplode rexplode ( sA sB -- s1 ... sN N ) rexplode ( sA i -- s1 ... sN N ) Just like explode, except that the pieces are pushed in the other order. For example, "this is a test" " " explode => "test" "a" "is" "this" 4 "hello" 1 explode => "o" "l" "l" "e" "h" 5 but "this is a test" " " rexplode => "this" "is" "a" "test" 4 "hello" 1 rexplode => "h" "e" "l" "l" "o" 5 &&& rexplode1 rexplode1 ( sA sB -- sA1 sA2 1 ) [or] ( sA sB -- sA 0 ) Breaks sA at the last occurrence of sB within it. The part before the break (sA1) is pushed, then the part after the break (sA2), then 1. If sB does not occur within sA, sB is popped but sA is not, and 0 is pushed. Note carefully how the return values are defined in comparison to explode1. &&& rimplode rimplode ( s1 ... sN N sB -- sA ) rimplode concatenates the list of strings s1 through sN, placing sB between them. Thus, this is the converse of rexplode, though there is no requirement that s1...sN are in fact what would be produced by rexploding sA with sB; in particular, "" rimplode can be used as a multi-string strcat. &&& rinstr rinstr ( s1 s2 -- i ) Finds s2 within s1, returning the offset of the last such occurrence, or 0 if s2 does not occur within s1. (The returned offset is 1-origin, so that, for example, if s2 occurs only at the very beginning of s1, the returned value is 1.) &&& rinstring rinstring ( s1 s2 -- i ) Just like rinstr, except that the matching is done case-independent. &&& rmatch rmatch ( d s -- d ) Matches the string in the context of the dbref, returning the result of the match. The dbref must be a player, room, or thing; in any case, the string is matched against the exits attached to the dbref, and in the case of a player or room, against the inventory or contents as well. Unfortunately "here" and "me" and "home" don't work; also, if the dbref is a player, the player's location and its parent rooms are not searched. &&& roll roll ( xN ... x1 N M -- xM ... x1 xN ... xM-1 ) Rotates the top N elements of the stack M places. If N is less than zero, an error occurs; if N is 0, nothing is done but popping N and M off the stack. Otherwise, there must be at least N additional elements on the stack (or an error occurs); the top M of them are removed and inserted below the others. M is taken modulo N, so the effective M value is always 0 through N-1; the M value actually found on the stack may be any integer, positive, negative, or zero. &&& room? room? ( x -- i ) Returns 1 if the argument is dbref that refers to a room, or is #-3. Otherwise 0 is returned. &&& rot rot ( x1 x2 x3 -- x2 x3 x1 ) Rotates the top three elements of the stack. This is equivalent to `3 rotate'. (See also -rot.) &&& rotate rotate ( x1 x2 ... xN N -- x2 ... xN x1 ) ( x1 ... xN-1 xN -N -- xN x1 ... xN-1 ) Rotates the top N elements of the stack. If the argument is positive, pulls an element from N elements down on the stack and puts it on top; with a negative argument, performs the converse operation, moving the top element to a lower place on the stack. Thus, 3 rotate is identical in effect to rot, and 2 rotate (or -2 rotate) is identical in effect to swap. &&& round round ( f -- i ) Converts a float to an integer, rounding to nearest. &&& royalty? royalty? ( d -- i ) Returns true if its argument has royalty privileges. Precisely what this means is a compile-time option, but it is typically equivalent to something like `dup wizard? over "r" flag? or swap "q" flag? not and'. &&& set set ( d s -- ) Sets or clears a flag on a dbref. The string must be one of the valid flag names, or such a name with a ! prefixed to it. (Abbreviations are accepted.) This sets the flag, or with the ! prefix, clears it, on the dbref. Except for wizard programs, the effective player must own the dbref. Some flags cannot be set or cleared from MUF at all; as of this writing, they are Wizard, Mucker, Visual, Unseen, Quell, and God. In addition, non-wizard programs are not allowed to set or clear the Dark bit on anything but a room or program. &&& setdesc setdesc ( d s -- ) Sets the description string for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setdrop setdrop ( d s -- ) Sets the drop message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setfail setfail ( d s -- ) Sets the fail message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setilimit setilimit ( i -- ) [wizard] Sets the iteration limit. If a MUF program attempts to run for more than this many cycles, it will be aborted with an error. (If this is set to too small a number, MUF will be useless until the muck is shut down and restarted; no check is made for this. If it is more than about 3, though, a program can be written that will set it back.) Note that if the program does a sleep, the count of iterations it has used is reset to zero. &&& setname setname ( d s -- ) Sets the name of the dbref. Except for wizard programs, the effective player must own the dbref. Only wizard programs are allowed to use this when the dbref is a player. &&& setodrop setodrop ( d s -- ) Sets the odrop message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setofail setofail ( d s -- ) Sets the ofail message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setosucc setosucc ( d s -- ) Sets the osuccess message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& setprop setprop ( d s k v ["perm" p] -- ) This sets or replaces the property named by s on dbref d. The type of the property is given by k, which must be one of the three strings "string", "dbref", or "any". If k is "string", v must be a string, and this is operationally equivalent to addprop. If k is "dbref", v must be a dbref, and this sets a dbref-valued property. If k is "any", v may be anything, and this sets an anyval property. If the "perm" keyword and p are specified and the property did not previously exist, p specifies the permissions for the new property; when creating a property without specifying permission bits, or when specifying them as zero (which is not otherwise useful), they are based on the property name, as outlined in `man propinfo'. Any previous property on the dbref with the same name is replaced. &&& setpropperm setpropperm ( d s q -- ) If no property with the specified name exists on the specified dbref, or if BIT-C permission is denied, an error occurs. Otherwise, the permissions are changed to those specified. &&& setsucc setsucc ( d s -- ) Sets the success message for the dbref. Except for wizard programs, the effective player must own the dbref. &&& sin sin ( n -- f ) Computes the sine of its argument, in radians. &&& sincos sincos ( n -- fs fc ) Computes the sine and cosine of its argument, in radians. This is equivalent to "dup sin swap cos", but is likely to be more efficient. &&& sinh sinh ( n -- f ) Computes the hyperbolic sine of its argument. &&& sleep sleep ( i -- ) sleep ( d -- ) Sleep with an integer argument causes the current program to sleep for i seconds. With a dbref as an argument, it sleeps until some (other) program uses the wakeup primitive on the same dbref. Technical information: When a player starts a program and that program does a sleep call, a daemon [see @ps, @kill for more info] is spawned that will continue executing the program at the designated time. If the program does another sleep, it will extend the life of the daemon. An example program: : main do me @ "test" notify 60 sleep loop ; This will run an endless loop that notifies you every 60 seconds with the "test" message. To stop the program use @kill on the dbref of the daemon. &&& sqrt sqrt ( n -- f ) Computes the square root of its argument. &&& strcat strcat ( s1 s2 -- s ) Concatenates two strings, returning the result. For example, `"foo" "bar" strcat' will leave the string "foobar" on top of the stack. &&& strcmp strcmp ( s1 s2 -- i ) Compares two strings, returning an integer that is less than, equal to, or greater than zero, as s1 is less than, equal to, or greater than s2. Upper/lower case distinctions are significant, and machine character values are used to determine what constitutes less than or greater than. &&& strcspn strcspn ( s1 s2 -- sA sB) Finds the longest possible initial substring of s1 consisting entirely of characters not in s2. sA is that substring; sB is the remainder of s1. If s1 contains no characters from s2, sA will be s1 and sB will be "". &&& strcut strcut ( s i -- s1 s2 ) Cuts a string, cutting the first i characters into s1 and the rest into s2. If i is less than zero, it has s's length added to it; if i is still less than zero, s1 is "" and s2 is s. If i is greater than s's length, s1 is s and s2 is "". &&& string? string? ( x -- i ) Returns 1 if its argument is a string, 0 otherwise. &&& stringcmp stringcmp ( s1 s2 -- i ) Compares two strings, returning an integer that is less than, equal to, or greater than zero, as s1 is less than, equal to, or greater than s2. Both strings are mapped to lower case for purposes of the comparison, with machine character values used to determine what constitutes less than or greater than after the mapping. &&& stringncmp stringncmp ( s1 s2 n -- i ) Compares two strings. At most the first n characters are compared; otherwise identical to stringcmp. &&& strlen strlen ( s -- i ) Returns the length of its string argument. &&& strncmp strncmp ( s1 s2 n -- i ) Compares two strings. At most the first n characters are compared; this is otherwise identical to strcmp. &&& strspn strspn ( s1 s2 -- sA sB) Finds the longest possible initial substring of s1 consisting entirely of characters from s2. sA is that substring; sB is the remainder of s1. If the whole of s1 consists of characters from s2, sB will be "". &&& subst subst ( s sA sB -- s' ) Performs substitution. The returned string s' is just the same as s, except that wherever sB occurs in it, it is replaced with sA. sB must not be "", but either of the other two arguments may be. In case multiple occurrences of sB overlap, the ones that are replaced are the ones found in a simple left-to-right scan. When a replacement occurs, the left-to-right scan starts afresh; characters before the match point and characters coming from sA are not considered when looking for possible occurrences of sB. Some examples: "xaabaabaax" "cha" "aabaa" subst => "xchabaax" "xaabaaabaax" "cha" "aabaa" subst => "xchaabaax" "xcabaabaax" "cha" "aabaa" subst => "xcabchax" "axxyxyx" "" "xyx" subst => "axyx" &&& substr substr ( s i1 i2 -- s ) Selects a substring of a string. The substring begins at a point i1 characters into the string and is i2 characters long; thus, in simple cases, this is similar to "-rot strcut swap pop swap strcut pop". If either argument is less than zero, it has the string's length added to it. If the substring requested begins after the end of the string, "" is returned; if it begins within the string but extends past the end of the string, it is truncated. If the substring requested begins before the beginning of the string, (ie, if i1 is negative even after adding the string's length), i1 is increased and i2 decreased to bring the beginning point to the beginning of the string. If the length is still negative after adding the string's length, the returned string is "". &&& succ succ ( d -- s ) Returns the success message for the dbref. &&& swap swap ( x1 x2 -- x2 x1 ) Exchanges the top two elements of the stack. &&& sys-lseek ( o i1 i2 -- i ) Performs an lseek(2) on an open file. i1 is the offset, i2 specifies where it is relative to (see `man SEEK_SET', `man SEEK_CUR', and `man SEEK_END'). &&& sys-open ( s i -- o ) Opens a file. The name is given by the string; the integer specifies how the open is to be done and should include one of O_RDONLY, O_RDWR, or O_WRONLY, with zero or more of O_CREAT, O_TRUNC, and O_EXCL ORed in (see `man |'; see also the `man' entries for the individual constants). &&& sys-read ( o -- s ) ( o -- 0 ) Reads a line from an open file. Reads up to a newline, packaging the characters as a string and returnign it. On EOF (or error), returns the integer zero (note that "" can occur if the file contains an empty line). If the line is too long, it is forcibly broken; there is no way to tell the difference between this and a line that is exactly the maximum length. &&& sys-write ( o s -- ) Writes a line to an open file. The string is written, followed by a newline. If the string is longer than the maximum file line length, an error occurs. &&& systime systime ( -- i ) Returns the current system time, which presently is an integer number of seconds since 00:00:00 GMT, Jan 1, 1970. &&& t-p-abort t-p-abort is internal to the implementation of timed-prompt. See "man timed-prompt-info" for more. &&& t-p-read t-p-read is internal to the implementation of timed-prompt. See "man timed-prompt-info" for more. &&& tan tan ( n -- f ) Computes the tangent of its argument, in radians. &&& tanh tanh ( n -- f ) Computes the hyperbolic tangent of its argument. &&& then See `man if'. &&& thing? thing? ( x -- i ) Returns 1 if the argument is a dbref that refers to a thing, or 0 otherwise (if the argument isn't a dbref, or is a dbref of some other type). &&& time time ( -- is im ih ) Returns the current time of day, in seconds, minutes, and hours. Note that this is the time of day in the timezone the muck is running in, which doesn't necessarily bear any relation to the timezone any particular player is in. &&& time_created time_created ( d -- i ) Returns the time the dbref was created, in seconds since 00:00:00 GMT, Jan 1, 1970. &&& time_modified time_modified ( d -- i ) Returns the time the dbref was last modified, in seconds since 00:00:00 GMT, Jan 1, 1970. &&& time_used time_used ( d -- i ) Returns the time the dbref was last used, in seconds since 00:00:00 GMT, Jan 1, 1970. &&& timed-prompt timed-prompt ( s i -- s / 0 ) This works like prompt (see "man prompt"), except that if no input is received after the number of seconds given by the second argument, 0 is returned instead, and the program continues without reading anything. (The string argument may be "" to get the timeout effect without actually printing anything, much as prompt degenerates to read when "" is given.) There are implementation details, which may change if timed-prompt is reimplemented. They are nevertheless necessary to understand debug output from programs that use timed-prompt and some error conditions that can arise. See "man timed-prompt-info" for them. &&& timed-prompt-info timed-prompt is implemented with the help of two otherwise inaccessible primitives and a daemon. This would not be worth mentioning, except that if the program is set D(ebug), the debug trace will contain some otherwise incomprehensible lines; also, there are a few error conditions possible if someone meddles with the daemon. Specifically, when timed-prompt is executed, a daemon is created to do the timeout. If input is received, you will see T-P-READ executed with the daemon's dbref on the stack just underneath the string; this special primitive amounts to "swap kill", to clean up the dameon. If no input is received, the daemon will execute T-P-ABORT, with a stack holding the player's dbref and nothing else; this primitive handles the cleanup in the converse case, setting up the stack so that timed-prompt returns zero and arranging for MUF execution to pick up again without waiting for input. There are numerous error checks when T-P-READ and T-P-ABORT are executed. Most of them are can't-happen checks; if you get an error not listed below from T-P-READ or T-P-ABORT, please consider it a bug in the muck and report it as such. T-P-READ: Non-daemon argument. This indicates that the daemon dbref is no longer a daemon. The only way this can happen, aside from bugs in the server, is if someone uses @kill or MUF kill to kill off the daemon. T-P-READ: Daemon owner changed. This indicates that the daemon dbref is a daemon, but its owner is wrong. This means that either someone has used @chown on the daemon, or else it was killed off as in the previous paragraph and another daemon, owned by someone else, reused the dbref. It is possible for the daemon to be killed off and then another daemon owned by the same player to reuse the dbref. If this happens, the timeout will never happen and the new daemon will be destroyed when input is received. &&& timemerge timemerge ( i i i i i i i i -- i ) Converts a split-up time (see `man timesplit') to a timestamp value, interpreting the arguments as being in the timezone the muck is running in. &&& timesplit timesplit ( i -- i i i i i i i i ) Splits a timestamp value into a split-up time, converting it to the appropriate values for the timezone the muck is running in. A split-up time is eight integers on the stack. From bottom to top, they are seconds (0-60), minutes (0-59), hours (0-23), day-of-month (1-31), month (1-12), year (eg, 1992), day-of-week (1-7, 1=Sunday), and day-of-year (1-366). &&& tolower tolower ( s -- s ) Returns the argument string, with all uppercase characters converted to the corresponding lowercase characters. &&& touch touch ( d -- ) This sets the last-used time of the dbref to the current time. &&& toupper toupper ( s -- s ) Returns the argument string, with all lowercase characters converted to the corresponding uppercase characters. &&& trig trig ( -- d ) Returns the dbref that triggered the program run; normally this will be an exit, but may be something else, particularly when dbrefs are locked to programs. This is always the value initially stored in the trigger variable; normally, trigger @ is to be preferred over trig, because the former can be changed. &&& trigger-exit trigger-exit ( d s -- ) The argument dbref must be an exit; it is triggered, as if the effective player had triggered an exit linked to it. (In particular, this means that the restrictions that apply to exits triggering other exits are in effect; for example, links that link to rooms or players are ignored.) The string given is used as the "rest of the command line" value; the exit is run as if the verb typed to trigger it were a zero-length string. &&& true-royalty? true-royalty? ( d -- i ) This is just like royalty?, in that it makes the same basic test, and any difference is a compile-time option. Normally, it is just like royalty? except that it ignores any Q flag on its argument. &&& true-wizard? true-wizard? ( d -- i ) This is just like wizard?, in that it makes the same basic test, and any difference is a compile-time option. Normally, it is just like wizard? except that it ignores any Q flag on its argument. &&& trunc trunc ( f -- i ) Converts a float to an integer, rounding towards zero. &&& uid uid ( -- d ) This returns the effective player's dbref. &&& unlink unlink ( d -- ) Unlinks a room or exit. If the argument is an exit, it is unlinked from everything it is linked to. If the argument is a room, its drop-to, if any, is removed. Other argument types produce an error. The program must be able to build, and except for wizard programs, the effective player must own the thing being unlinked. &&& unlock unlock ( d -- ) Unlocks a dbref. Except for wizard programs, the effective player must own the dbref. &&& unparse_flags unparse_flags ( d -- s ) Returns the flags of the dbref as a string. This returns the same information flagstr does, but in the long, human-readable, form, like Type: PLAYER Flags: Mucker Builder or Type: ROOM Flags: NoInventory Jump_OK Haven Visual &&& unparse_lock unparse_lock ( d -- s ) Returns the lock of the dbref as a string. If the dbref is not locked, "*UNLOCKED*" is returned. The string is intended to be human-readable and it is not acceptable as the second argument to lock; see also lockstr. &&& unparse_object unparse_object ( d1 d2 -- s ) Returns the name of d1 as it would be seen by d2. d2 must be a player, and checks for control and Author flags and all similar things are performed just as they would be by the muck itself, if it were to generate the name of d1 to be displayed to d2. &&& until until ( x -- ) until can be used to terminate a loop opened with do or begin; it is functionally equivalent to "if break then loop". &&& var var word This declares the following word as a variable. All variable declarations must appear outside all : definitions in a program. Unfortunately the variable allocation scheme is rather badly broken; you are probably better off avoiding variables altogether, except for the three built-in ones (me, loc, trigger). &&& var? var? ( x -- i ) Returns 1 if its argument is a variable, 0 otherwise. &&& variable variable ( i -- v ) Given a variable number, returns the corresponding variable object. Variable allocation in MUF is rather badly broken; you are probably better off avoiding variables altogether, except for the three builtin ones (me, loc, trigger). &&& wakeup wakeup ( d -- ) This wakes up any daemons that are sleeping on the given dbref. No indication is given of how many daemons are awakened, or indeed if any are. (All daemons sleeping on the dbref are awakened, not just one.) &&& while while ( x -- ) Conditionally exits from the smallest enclosing do or for loop. This is functionally equivalent to "not if break then", but can often be compiled more compactly. &&& wizard? wizard? ( d -- i ) Returns true if its argument has wizard privileges. Precisely what this means is a compile-time option, but it is typically equivalent to something like `dup god? over "w" flag? or swap "q" flag? not and'. &&& yield yield ( -- ) The muck timeshares among all currently-executing programs. When a player or daemon has executed enough, it is suspended and others are given a chance to run. The yield primitive allows a thread to voluntarily give up the rest of its time-slice. &&& { { ... } ( -- ptr ) Writing a sequence of code inside { } generates a pointer to the compiled code, as if a word were defined with that code as its body and ' used to generate a pointer to it, except that no word is actually defined, and the code is written inline instead of being removed to elsewhere. &&& | | ( n n -- n ) Returns the bitwise OR of its operands. See "man bit-types" for more. &&& } See "man {". &&& ~ ~ ( n -- n ) Returns the bitwise complement of its operand. The operand must be an integer or a quad; the return value has the same type. &&& MARKER - end of descriptions &&& moveto-player Restrictions on moving a player with moveto: The destination must be a room or #-3. For wizard programs, this is the only restriction. Otherwise, the room the player is being moved from must either be set J(ump_OK) or be owned by the effective player; the same must be true of the destination room, unless it's #-3, which is always allowed. &&& moveto-thing Restrictions on moving a thing (or program) with moveto: The destination must be a room or player. For wizard programs, this is the only restriction. Otherwise, a rather strange algorithm is applied. If the effective player owns the destination, then the condition below must be true of it; otherwise, if the effective player owns the current location of the thing being moved, the condition below must be true of that. If neither the current location nor the destination is owned by the effective player, no further condition applies (this is the really peculiar part). The condition referred to above is that the location in question must either be set J(ump_OK) or be owned by the effective player. &&& moveto-room Restrictions on moving a room with moveto: The destination must be a room. The room being moved must not be the global environment room (usually #0). If the destination is #-3, the effective destination is the global environment room and no further checks are done. The destination must not be contained in the room being moved, either directly or indirectly. For non-wizard programs, the the effective player must own the room being moved and must be able to link to the destination. &&& moveto-exit Restrictions on moving an exit with moveto: The destination must be a room, player, or thing. For non-wizard programs, the effective player must own the exit being moved and must be able to link to the destination. &&& cmp-types The numeric comparison operators (<, <=, >, >=, =, !=) can take integers, floats, quads, dbrefs, and variables, with dbrefs and variables treated as if they had "int" applied to them first. If either argument is a float, the other is converted to a float and a floating comparison is done; otherwise, if either is a quad, the other is converted to a quad and a quad comparison is done. Otherwise they must both be integers and an integer comparison is done. &&& bit-types The bitwise operators (&, |, ^) can take integers and quads, but nothing else. If either operand is a quad, both operands are converted to quads if necessary and a quad operation is done, returning a quad; otherwise, they must both be integers, and an integer operation is done, returning an integer.