! ( x v -- ) | localvar | lvar | var |
variable | variable operators |
abort | background | foreground | fork |
ispid? | kill | mode | pid |
pr_mode | preempt | queue | setmode |
sleep |
and | dbcmp | logical operators | math operators |
not | number? | or | smatch |
strcmp | stringcmp | stringpfx | strncmp |
address? | dbref? | exit? | flag? |
int? | lock? | ok? | player? |
string? | thing? |
begin | break | call | continue |
execute | exit | if | interp |
jmp | public | repeat | until |
while |
depth | dup | over | pick |
pop | put | rot | rotate |
swap |
desc | drop | fail | name |
odrop | ofail | osucc | setdesc |
setname | succ | truename |
date | gmtoffset | systime | time |
timefmt | timesplit |
atoi | dbref | int | intostr |
addprop | envprop | envpropstr | getprop |
getpropstr | getpropval | nextprop | parseprop |
propdir? | remove_prop | setprop |
notify | notify_except | notify_exclude | read |
awake? | conboot | concount | condbref |
condescr | conhost | conidle | connotify |
contime | conuser | descr_setuser | descrcon |
descriptors | nextdescr | online |
explode | instr | instring | pronoun_sub |
rinstring | strcat | strcut | strdecrypt |
strencrypt | strip | striplead | striptail |
strlen | subst | tolower | toupper |
unparseobj |
getlockstr | locked? | parselock | prettylock |
setlockstr | testlock | unparselock |
bitand | bitor | bitshift | bitxor |
credits | directives | flags | libraries |
loops | miscellaneous | mucker levels | multitasking |
me @and
0 variable @will do the same thing (returning the user's dbref). User-defined variables are numbered sequentially starting at 3 by the compiler. Note that these variable numbers can be used even if variables have not been formally declared, making implementation of such things as arrays conveniently easy. See @, !, and VAR.
Programmer error. Please tell Revar the following message: #1234 (line 23) ABORT: Bad vibes.
A
?matches any single character.
A
*matches any number of any characters.
{word1|word2|etc}will match a single word, if it is one of those given, separated by | characters, between the {}s. A word ends with a space or at the end of the string. The given example would match either the words
"word1", "word2",or
"etc".
{} word patterns will only match complete words:
"{foo}*"and
"{foo}p"do not match
"foop"and
"*{foo}"and
"p{foo}"do not match
"pfoo".
{} word patterns can be easily meaningless; they will match nothing if they: (a) contain spaces, (b) do not follow a wildcard, space or beginning of string, (c) are not followed by a wildcard, space or end of string.
If the first char of a {} word set is a '^', then it will match a single word if it is NOT one of those contained within the {}s. Example:
{^Foxen|Fiera}will match any single word EXCEPT for Foxen or Fiera.
[aeiou]will match a single character as long as it is one of those contained between the []s. In this case, it matches any vowel.
If the first char of a [] char set is a '^', then it will match a single character if it is NOT one of those contained within the []s. Example:
[^aeiou]will match any single character EXCEPT for a vowel.
If a [] char set contains two characters separated by a '-', then it will match any single character that is between those two given characters. Example:
[a-z0-9_]would match any single character between 'a' and 'z', inclusive, any character between '0' and '9', inclusive, or a '_'.
The
\character will disable the special meaning of the character that follows it, matching it literally.
Example patterns:
"d*g" matches "dg", "dog", "doog", "dorfg", etc. "d?g" matches "dog", "dig" and "dug" but not "dg" or "drug". "M[rs]." matches "Mr." and "Ms." "M[a-z]" matches "Ma", "Mb", etc. "[^a-z]" matches anything but an alphabetical character. "{Moira|Chupchup}*" matches "Moira snores" and "Chupchup arghs." "{Moira|Chupchup}*" does NOT match "Moira' snores". "{Foxen|Lynx|Fier[ao]} *t[iy]ckle*\?" Will match any string starting with 'Foxen', 'Lynx', 'Fiera', or 'Fiero', that contains either 'tickle' or 'tyckle' and ends with a '?'.
Returns 1 if object d is a program, otherwise returns 0. If the dbref is that of an invalid object, it will return 0. See also player?, room?, thing?, exit?, ok?. ~ ~ ROOM? room? ( d -- i )
Returns 1 if object d is a room, otherwise returns 0. If the dbref is that
of an invalid object, it will return 0. A dbref of #-3 (HOME) returns 1.
See also player?, program?, thing?, exit?, and ok?.
Example of JMP as a tail-recursion optimization:
: countforever ( i -- ) 1 + dup intostr .tell 'countforever jmp ; A better ways to do the same thing with looping primitives would be:Tests can be repeated multiple times by following the test with a number. ie:: countforever ( i -- ) begin 1 + dup intostr .tell repeat ;
PUBLIC
Declares a previously defined function to be public for execution by other programs. This is a compile-time directive, not a run-time primitive. To call a public function, put the dbref of the program on the stack, then put a string, containing the function name, on the stack, then use CALL. For example:
#888 "functionname" CALL
repeat ( -- )
Jumps execution to the instruction after the BEGIN in a BEGIN-REPEAT loop. Marks the end of the current loop. See also, LOOPS.
until (i -- )
If the value on top of the stack is false, then it jumps execution back to the instruction after the matching BEGIN statement. (BEGIN-UNTIL, BEGIN-REPEAT, and IF-ELSE-THEN's can all be nested as much as you want.) If the value is true, it exits the loop, and executes the next instruction, following the UNTIL. Marks the end of the current loop. See also, LOOPS.
while (i -- )
If the value on top of the stack is false, then this causes execution to jump to the instruction after the UNTIL or REPEAT for the current loop. If the value is true, however, execution falls through to the instruction after the WHILE. See also, LOOPS.
Stack Manipulation Primitives
Belongs in this section: dup pop swap over rot rotate pick put depthdepth ( -- i )
Returns the number of items on the stack.
dup ( x -- x x )
Duplicates the item at the top of the stack.
over ( x y -- x y x )
Duplicates the second-to-top thing on the stack. This is the same as 2 pick.
pick ( ni ... n1 i -- ni ... n1 ni )
Takes the i'th thing from the top of the stack and pushes it on the top. 1 pick is equivalent to dup, and 2 pick is equivalent to over.
put ( nx...n1 ni i -- nx...ni...n1 )
Replaces the i'th thing from the top of the stack with the value of ni. 1 put is equivalent to swap pop Example:
"a" "b" "c" "d" "e" 3 putwould return on the stack:"a", "e", "c", "d"
pop ( x -- )
Pops the top of the stack into oblivion.
rot ( x y z -- y z x )
Rotates the top three things on the stack. This is equivalent to 3 rotate.
rotate ( ni ... n1 i -- n(i-1) ... n1 ni )
Rotates the top i things on the stack.
"a" "b" "c" "d" 4 rotatewould leave"b" "c" "d" "a"on the stack. Using a negative rotational value rotates backwards. ie:"a" "b" "c" "d" -4 rotatewould leave"d" "a" "b" "c"on the stack.
swap ( x y -- y x )
Takes objects x and y on the stack and reverses their order.
Message Management Primitives
Belongs in this section: desc succ fail name truename setdesc setsucc setfail setname drop osucc ofail odrop setdrop setosucc setofail setodropdesc ( d -- s )
Takes object d and returns its description (@desc) string field.
drop ( d -- s )
Takes object d and returns its drop (@drop) string field.
fail ( d -- s )
Takes object d and returns its fail (@fail) string field.
name ( d -- s )
Takes object d and returns its name (@name) string field.
odrop ( d -- s )
Takes object d and returns its odrop (@odrop) string field.
ofail ( d -- s )
Takes object d and returns its ofail (@ofail) string field.
osucc ( d -- s )
Takes object d and returns its osuccess (@osucc) string field.
succ ( d -- s )
Takes object d and returns its success (@succ) string field s.
truename ( d -- s )
Takes object d and returns its true name string field. This is the same as name if the MUCK doesn't use anoniminity.
setdesc setsucc setfail setdrop setosucc setofail setodrop (d s -- )
Takes object d, and sets the string field specified to s. A program may only set string fields of objects that are owned by the effective user of the program, or any object if the program is Wizard. These are all actually $defines to addprop with the appropriate property name. They are effectively defined as:
$define setdesc "_/de" swap 0 addprop $enddef $define setsucc "_/sc" swap 0 addprop $enddef $define setfail "_/fl" swap 0 addprop $enddef $define setdrop "_/dr" swap 0 addprop $enddef $define setosucc "_/osc" swap 0 addprop $enddef $define setofail "_/ofl" swap 0 addprop $enddef $define setodrop "_/odr" swap 0 addprop $enddefSee also set, setname, addprop, getpropstr, remove_prop, desc, succ, fail, drop, osucc, ofail, and odrop.
setname ( d s -- )
Takes object d, and sets the name to s. A program may only set the names of objects that are owned by the effective user of the program, or any object if the program is Wizard. The name of a player can never be set, since that would normally require a password. See also set, name, and setdesc.
Time Primitives
Belongs in this section: date gmtoffset systime time timesplit timefmtdate ( -- i i i)
Returns the monthday, month, and year. ie: if it were February 6, 1992, date would return
6 2 1992as three integers on the stack.
gmtoffset ( -- i)
Returns the machine's offset from Greenwich Mean Time in seconds.
time ( -- s m h )
Returns the time of day as integers on the stack, seconds, then minutes, then hours.
systime ( -- i )
Returns the number of seconds from Jan 1, 1970. This is compatible with the system timestamps and may be broken down into useful values through 'timesplit'.
timesplit ( i -- is im ih id im iy iw iyd )
Splits a systime value into 8 values in the following order: seconds, minutes, hours, monthday, month, year, weekday, yearday. Weekday starts with sunday as 1, and yearday is the day of the year (1-366).
timefmt (s i -- s)
Takes a format string and a SYSTIME integer and returns a string formatted with the time. The format string is ascii text with formatting commands:
%% -- "%" %a -- abbreviated weekday name. %A -- full weekday name. %b -- abbreviated month name. %B -- full month name. %C -- "%A %B %e, %Y" %c -- "%x %X" %D -- "%m/%d/%y" %d -- month day, "01" - "31" %e -- month day, " 1" - "31" %h -- "%b" %H -- hour, "00" - "23" %I -- hour, "01" - "12" %j -- year day, "001" - "366" %k -- hour, " 0" - "23" %l -- hour, " 1" - "12" %M -- minute, "00" - "59" %m -- month, "01" - "12" %p -- "AM" or "PM" %R -- "%H:%M" %r -- "%I:%M:%S %p" %S -- seconds, "00" - "59" %T -- "%H:%M:%S" %U -- week number of the year. "00" - "52" %w -- week day number, "0" - "6" %W -- week# of year, starting on a monday, "00" - "52" %X -- "%H:%M:%S" %x -- "%m/%d/%y" %y -- year, "00" - "99" %Y -- year, "1900" - "2155" %Z -- Time zone. "GMT", "EDT", "PST", etc.
Data Conversion Primitives
Belongs in this section: atoi intostr dbref intatoi ( s -- i )
Turns string s into integer i. If s is not a string, then 0 is pushed onto the stack.
dbref ( i -- d )
Converts integer i to object reference d.
int ( x -- i )
Converts variable or object x to integer i.
intostr ( x -- s )
x must be an integer or a dbref. Converts x into string s.
Property Management Primitives
Belongs in this section: getprop getpropval getpropstr addprop remove_prop envprop envpropstr nextprop propdir? parseprop setpropaddprop ( d s1 s2 i -- )
Sets property associated with s1 in object d. Note that if s2 is null "", then i will be used. Otherwise, s2 is always used. All four parameters must be on the stack; none may be omitted. If the effective user of the program does not control the object in question and the property begins with an underscore `_', the property cannot be changed. The same goes for properties beginning with a dot `.' which cannot be read without permission. If you store values, you must ensure that it they are never zero. Otherwise, when the user stores a non-zero number into the string field, (users may only access string fields) the next time TinyMUCK is dumped and loaded up again, the value field will be replaced with atoi(string field). If it is necessary to store zero, it is safer to just add 1 to everything.
envprop ( d s -- d ? )
Takes a starting object dbref and a property name and searches down the environment tree from that object for a property with the given name. If the property isn't found, it returns #-1 and a null string. If the property is found, it will return the dbref of the object it was found on, and the value it contained.
envpropstr (d s -- d s )
Takes a starting object dbref and a property name and searches down the environment tree from that object for a property with the given name. If the property isn't found, it returns #-1 and a null string. If the property is found, it will return the dbref of the object it was found on, and the string value it contained.
GETPROP (d s -- ?)
Gets the value of a given property, and puts it on the stack. This can return a lock, a string, a dbref, or an integer, depending on the type of the property. Permissions are the same as those for GETPROPSTR. This primitive returns 0 if no such property exists, of if it is a valueless propdir. Also see SETPROP, ADDPROP, REMOVE_PROP, GETPROPSTR, GETPROPVAL, INT?, DBREF?, STRING?, and LOCK?.
getpropstr ( d s -- s )
s must be a string. Retrieves string associated with property s in object d. If the property is cleared, "" (null string) is returned.
getpropval ( d s -- i )
s must be a string. Retrieves the integer value i associated with property s in object d. If the property is cleared, 0 is returned.
nextprop (d s -- s)
This takes a dbref and a string that is the full propdir pathname of a property and returns the full pathname of the next property in the given object's given propdir, or returns a null string if that was the last property in the propdir. To *start* the search, give it a propdir name ending in a '/', or a blank string. For example,
#10 "/" NEXTPROPreturns the name of the first property in the root propdir of object #10, and#28 "/letters/" NEXTPROPwould return the name of the first property in the 'letters/' propdir on object #28. A blank string is the same as "/". If you try to do a Nextprop on a non-existent property, you will have a null string returned to you. Nextprop will skip properties if they would not be readable by the program with the given permissions and effective user id. (Requires Mucker Level 3)
parseprop (d s s i -- s)
Returns the string output of the MPI Parser, given an object, a property name to parse, an input string for the {&how} variable, and an integer that should either be 1, for when you want {delay} messages to be sent to the player only, or 0, when you want the rest of the players in the room to get the omessages. NOTE: for security reasons, you cannot use PARSEPROP with a mucker level of less than 3.
propdir? (d s -- i)
Takes a dbref and a property name, and returns a boolean integer that tells if that property is a propdir that contains other props. (Requires Mucker Level 3)
remove_prop ( d s -- )
Removes property s from object d. If the property begins with an underscore, `_' or a dot `.', and the effective user does not have permission on that object, the call fails.
setprop (d s ? -- )
Stores a lock, dbref, integer, or string into the named property on the given object. Permissions are the same as for ADDPROP. Also see SETPROP, ADDPROP, REMOVE_PROP, GETPROPSTR, and GETPROPVAL.
Input/Output Primitives
Belongs in this section: read notify notify_except notify_excludenotify ( d s -- )
d must be a player object. s must be a string. Tells player d message s. If s is null it will print nothing. This primitive will trigger the _listen'er property on the object the message is sent to, unless the program that would be run is the same as one one currently running.
notify_except ( d1 d2 s -- )
d1 must be a room object, s must be a string. Tells everyone at location d1 except object d2 message s. If object d2 is not a player or NOTHING (#-1) all players are notified. If s is null it prints nothing. NOTE: notify_except is now only an inserver $define. It is translated to '1 swap notify_exclude'. Please see the man sections on NOTIFY_EXCLUDE and DIRECTIVES for more information.
notify_exclude (d dn ... d1 n s -- )
Displays the message s to all the players (or _listening objects), excluding the n given players, in the given room. For example:
#0 #1 #23 #7 3 "Hi!" notify_excludewould send"Hi!"to everyone in room #0 except for players (or objects) #1, #7, and #23. _listener's will not be triggered by a notify_exclude if the program they would run is the same as the current program running.
read ( -- s )
Reads a string s from the user. This command should not be used in a program that is locked (as opposed to linked) to an object, as the lock will always fail and print the fail messages at read time. It cannot be used in a program associated with a room object.
Connection Management Primitives
Belongs in this section: awake? online concount condescr condbref conhost conuser contime conidle connotify descriptors nextdescr descrcon descr_setuser conbootawake? ( d -- i )
Passed a players dbref, returns the number of connections they have to the game. This will be 0 if they are not connected.
conboot (i -- )
Takes a connection number and disconnects that connection from the server. Basically @boot for a specific connection. (wizbit only)
concount ( -- i)
Returns how many connections to the server there are. (Requires Mucker Level 3)
condbref (i -- d)
Returns the dbref of the player connected to this connection. (Requires Mucker Level 3)
condescr ( i -- i )
Takes a connection number and returns the descriptor number associated with it. (Requires Mucker Level 3) See DESCRIPTORS, DESCRCON.
conhost (i -- s)
Returns the hostname of the connection. (wizbit only)
conidle (i -- i)
Returns how many seconds the connection has been idle. (Requires Mucker Level 3)
connotify (i s -- )
Sends a string to a specific connection to the server. (Requires Mucker Level 3)
contime (i -- i)
Returns how many seconds the given connection has been connected to the server. (Requires Mucker Level 3)
conuser (i -- s)
Returns the username of the connection. (wizbit only)
descrcon (i -- i)
Takes a descriptor and returns the associated connection number, or 0 if no match was found. See DESCRIPTORS, CONDESCR. (Requires Mucker Level 3)
descriptors (d -- ix...i1 i)
Takes a player dbref, or #-1, and returns the range of descriptor numbers associated with that dbref (or all for #-1)with their count on top. Descriptors are numbers that always stay the same for a connection, while a connection# is the relative position in the WHO list of a connection. See DESCRCON, CONDESCR.
descr_setuser ( i d s -- i )
Reconnects descriptor i to the player with dbref d and password s. It first disconnects from the old dbref, then connects the new one, as if QUIT was typed then the new character was logged in. If the password doesn't match the player's password, then it gives a permission denied error. This returns a 1 if successful or a 0 if the given descriptor wasn't found. Wizbit only.
nextdescr (i -- i)
Takes a descriptor number, and returns the next connected descriptor number. To get the first descriptor number, use '1 condescr'. Between these, you can step through the descriptors list. If you try to use nextdescr on an invalid descriptor, it will return 0. If you have reached the end of the descriptor list, it returns 0. (Requires Mucker Level 3)
online ( -- d ... i )
Returns a dbref for every connection to the game, and lastly the number of connections.
String Handling Primitives
Belongs in this section: toupper tolower instring rinstring instr rinstr striplead striptail strip unparseobj strlen strcat strcut subst explode pronoun_subexplode ( s1 s2 -- ... i )
s2 is the delimiter string, and s1 is the target string, which will be fragmented, with i pushed on top of the stack as the number of strings s1 was broken into. For instance:
"Hello world" " " explodewill result in"world" "Hello" 2on the stack. (Note that if you read these items off in order, they will come out "Hello" first, then "world".) For TinyMUCK 2.2, s2 may be any length. But "" (null string) is not an acceptable string for parameter s2.
instr ( s s1 -- i )
Returns the first occurrence of string s1 in string s, or 0 if s1 is not found. See also rinstr.
instring ( s s1 -- i )
Returns the first occurrence of string s1 in string s, or 0 if s1 is not found. Non-case sensitive. See also RINSTRING, INSTR, and RINSTR. This is an inserver define to 'tolower swap tolower swap instr'
strcat ( s1 s2 -- s )
Concatenates two strings s1 and s2 and pushes the result s = s1s2 onto the stack.
pronoun_sub ( d s -- s' )
Takes database object d and substitutes string s according to o-message rules. For example:
me @ "%N has lost %p marbles." pronoun_subwould return:"Igor has lost his marbles."if the player's name was Igor and his sex were male. d does not have to be a player for the substitutions to work. The substitutions are%a/%A for absolute possessive (his/hers/its, His/Hers/Its) %s/%S for subjective pronouns (he/she/it, He/She/It) %o/%O for objective pronouns (him/her/it, Him/Her/It) %p/%P for possessive pronouns (his/her/its, His/Her/Its) %r/%R for reflexive pronouns (himself/herself/itself,Himself/Herself/Itself) %n/%N for the player's name.if it comes across a %X substitution, where X is any character not listed in the above substitutions table, it will search down the environment tree from d to try to find the appropriate %X property for use in substitution.
rinstring ( s s1 -- i )
Returns the last occurrence of string s1 in string s, or -1 if s1 is not found. Non-case sensitive. See also INSTRING, INSTR, and RINSTR. This is an inserver define to 'tolower swap tolower swap rinstr'
strcut ( s i -- s1 s2 )
Cuts string s after its i'th character. For example,
"Foobar" 3 strcutreturns"Foo" "bar"If i is zero or greater than the length of s, returns a null string in the first or second position, respectively.
strdecrypt ( s1 s2 -- s3 )
Takes the encrypted string s1, and decrypts it, using the key s2, returning the plaintext string s3. Also see STRENCRYPT.
strencrypt ( s1 s2 -- s3 )
Takes the plaintext string s1, and encrypts it, using the key s2, returning the encrypted string s3. Note: s3 will be 2 characters longer than s1. Also Note: The longer your key string is, the more secure the data will be, up to the length of the data itself. The encryption technique used here is pretty simple, so I highly doubt it breaks any laws to take it outside the USA. By the same token, it probably shouldn't be trusted with any really important data. I'm not an expert at cryptography, so this ain't DES. Also see STRDECRYPT.
strip (s -- s)
This is a built in $define. It is interpreted as "striplead striptail" It strips the spaces from both ends of a string.
striplead (s -- s)
Strips leading spaces from the given string.
striptail (s -- s)
Strips trailing spaces from the given string.
strlen ( s -- i )
Returns the length of string s.
subst ( s1 s2 s3 -- s )
s1 is the string to operate on, s2 is the string to change all occurrences of s3 into, and s is resultant string. For example:
"HEY_YOU_THIS_IS" " " "_" substresults in"HEY YOU THIS IS"s2 and s3 may be of any length.
tolower (s -- s)
Takes a string and returns it with all the letters in lowercase.
toupper (s -- s)
Takes a string and returns it with all the letters in uppercase.
unparseobj ( d -- s )
Returns the name-and-flag string for an object. It always has the dbref and flag string after the name, even if the player doesn't control the object. For example:
"One(#1PW)"
Lock Handling Primitives
Belongs in this section: locked? getlockstr setlockstr parselock unparselock testlock prettylockgetlockstr ( d -- s )
Returns the lock expression for the given object in the form of a string. Returns "*UNLOCKED*" if the object doesn't have a lock set.
locked? (d d -- i)
Takes, in order, the dbref of the player to test the lock against, and the dbref of object the lock is on. It tests the lock, running programs as necessary, and returns a integer of 0 if it is not locked against them, or 1 if it is.
PARSELOCK (s -- l)
Parses a lock string into a lock. If the parsing failed, then the lock returned will be a TRUE_BOOLEXP, which is logically false to an 'if' test. Also see UNPARSELOCK, LOCK?, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR, and LOCKED?.
PRETTYLOCK (l -- s)
Unparses a lock into a string fit for players to see. Also see LOCK?, PARSELOCK, UNPARSELOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR, and LOCKED?.
setlockstr (d s -- i)
Tries to set the lock on the given object to the lock expression given in the string. If it was a success, then it will return a 1, otherwise, if the lock expression was bad, it returns a 0. To unlock an object, set its lock to a null string.
TESTLOCK (d l -- i)
Tests the player dbref against the given lock. If the test was successful, then this returns a 1. If the test failed, then this returns a 0. Also see LOCK?, PARSELOCK, UNPARSELOCK, PRETTYLOCK, GETLOCKSTR, SETLOCKSTR, and LOCKED?
UNPARSELOCK (l -- s)
Unparses a lock into a string fit for program editing. Also see LOCK?, PARSELOCK, PRETTYLOCK, TESTLOCK, GETLOCKSTR, SETLOCKSTR, and LOCKED?.
Bitwise Operator Primitives
Belongs in this section: bitor bitand bitxor bitshiftbitand (i i -- i)
Does a mathematical bitwise and.
bitor (i i -- i)
Does a mathematical bitwise or.
bitshift (i i -- i)
Shifts the first integer by the second integer's number of bit positions. Same as the C << operator. If the second integer is negative, its like >>.
bitxor (i i -- i)
Does a mathematical bitwise exclusive or.
Misc Primitives
Belongs in this section: set mlevel next checkargs location newroom pennies flag caller force sysparm contents newexit addpennies prog random match version controls newobject timestamps trig stats rmatch getlink setown recycle part_pmatch dbtop exits moveto setlink owner copyobj checkpasswordaddpennies ( d i -- )
d must be a player or thing object. Adds i pennies to object d. Without Wizard permissions, addpennies may only give players pennies, limited to between zero and MAX_PENNIES.
caller ( -- d)
Returns the dbref of the program that called this one, or the dbref of the trigger, if this wasn't called by a program.
checkargs (??? s -- )
Takes a string argument that contains an expression that is used to test the arguments on the stack below the given string. If they do not match what the expression says should be there, then it aborts the running program with an appropriate Program Error Message. The expression is formed from single character argument tests that refer to different argument types. The tests are:
a - function address.
d - dbref. (#-1, #-2, #-3 are okay)
D - valid, non-garbage dbref. (#-1, #-2 NOT allowed. #-3 is okay)
e - exit dbref. (#-1, #-2 allowed)
E - exit dbref. (#-1, #-2 NOT allowed)
f - program dbref. (#-1, #-2 allowed)
F - program dbref. (#-1, #-2 NOT allowed)
i - integer.
l - lock boolean expression.
p - player dbref. (#-1, #-2 allowed)
P - player dbref. (#-1, #-2 NOT allowed)
r - room dbref. (#-1, #-2 allowed) (#-3 is a room)
R - room dbref. (#-1, #-2 NOT allowed) (#-3 is a room)
s - string.
S - non-null string.
t - thing dbref. (#-1, #-2 allowed)
T - thing dbref. (#-1, #-2 NOT allowed)
v - local or global variable.
? - any stack item type.
"i12" checkargswould test the stack for 12 integers.
The last test in the string expression will be done on the top stack item. Tests are done from the top of the stack down, in order, so the last test that fails in a string expression will be the one that the Program Error will be given for. ie:
"sdSi" checkargswill test that the top stack item is an integer, then it tests that the next item down is a non-null string, then it tests the third item from the top to see if it is a dbref, and lastly it tests to make sure that the 4th item from the top is a string.
Spaces are ignored, so
"s d i"is the same as
"sdi"However, multipliers are ignored if they follow a space, so
"s 4d i"is also the same as
"sdi"This is because you are basically telling it to repeat the space 4 times, and since spaces are ignored, it has no effect.
If you have a function that takes a stack item of any type, you can use the "?" test. "?" will match a string, integer, dbref, or any other type.
Since sometimes arguments are passed in ranges, such as the way that the explode primitive returns multiple strings with an integer count on top, there is a way to group arguments, to show that you expect to receive a range of that type. ie:
"{s}" checkargswould test the stack for a set of strings like
"first" "second" "third" "fourth" 4where the top stack item tells how many strings to expect within the range.
Sometimes a function takes a range of paired arguments, such as:
"one" 1 "two" 2 "three" 3 "four" 4 4where the count on the top of the range refers to the number of pairs. To test for the range given above, you would use
"{si}" checkargsto tell it that you want to check for a range of paired strings and integers. You can group as many argument tests together in a range as you would like. ie: you could use
"{sida}"as an expression to test for a range of related strings, integers, dbrefs, and function addresses.
Since the argument multipliers refer to the previous test OR range, you can test for two string ranges with the test '"{s}2" checkargs'. ie: It would succeed on a stack of: '"one" "two" "three" 3 "four" "five" 2'. '"{s2}" checkargs', however, would test for one range of paired strings. ie: It would succeed with a stack of: '"one" "1" "two" "2" "three" "3" 3'.
If, for some reason, you need to pass a range of ranges to a function, you can test for it by nesting the braces. ie: '"{{s}}" checkargs'
Now, as one last example, the primitive notify_exclude, if we were to test
the arguments passed to it manually, would use the test '"R{p}s" checkargs'
to test for a valid room dbref, a range of player dbrefs or #-1s, and a
string.
a) If the object being moved is !JUMP_OK and is it being moved by someone
other than the object's owner, then the moveto fails.
b) If the object being moved is a person and either the source or
destination rooms (if not owned by the person being moved) are
!JUMP_OK, the moveto fails.
c) If the object being moved is not a player, is owned by the owner of
either the source or destination rooms, and either room where the
ownership matches is !JUMP_OK, the moveto fails.
The moveto succeeds under any other circumstances. MOVETO rules follow the
permissions of the current effective userid. MOVETO will run programs in
the @desc and @succ/@fail of a room when moving a player.
Parameters available:
(str) dumpwarn_mesg - Message to warn of a coming DB dump (str) deltawarn_mesg - Message to warn of a coming delta dump (str) dumpdeltas_mesg - Message telling of a delta dump (str) dumping_mesg - Message telling of a DB dump (str) dumpdone_mesg - Message notifying a dump is done (str) penny - A single currency (str) pennies - Plural currency (str) cpenny - Capitolized currency (str) cpennies - Capitolized plural currency (str) muckname - The name of the MUCK (str) rwho_passwd - Password for RWHO servers (Wizbit only) (str) rwho_server - RWHO server to connect to (Wizbit only) (str) huh_mesg - Message for invalid commands (str) leave_mesg - Message given when QUIT is used (str) idle_boot_mesg - Message given to an idle booted user (str) register_mesg - Message for a failed 'create' at login (str) playermax_warnmesg - Message warning off too many connects (str) playermax_bootmesg - Error given when a player cannot connect (time) rwho_interval - Interval between RWHO updates (time) dump_interval - Interval between dumps (time) dump_warntime - Warning prior to a dump (time) monolithic_interval - Max time between full DB dumps (time) clean_interval - Interval between unused object purges (time) aging_time - When an object is considered old and unused (time) maxidle - Maximum idle time allowed (int) max_object_endowment - Max value of an object (int) object_cost - Cost to create an object (int) exit_cost - Cost to create an exit (int) link_cost - Cost to link an exit (int) room_cost - Cost to dig a room (int) lookup_cost - Cost to lookup a player name (int) max_pennies - Max number of pennies a player can own (int) penny_rate - Rate for finding pennies (int) start_pennies - Starting wealth for new players (int) kill_base_cost - Number of pennies for a 100 percent chance (int) kill_min_cost - Minimum cost for doing a kill (int) kill_bonus - Bonus for a successful kill (int) command_burst_size - Maximum number of commands per burst (int) commands_per_time - Commands per time slice after burst (int) command_time_msec - Time slice length in milliseconds (int) max_delta_objs - Max percent of changed objects for a delta (int) max_loaded_objs - Max percent of the DB in memory at once (int) max_process_limit - Total processes allowed (int) max_plyr_processes - Processes allowed for each player (int) max_instr_count - Max preempt mode instructions (int) instr_slice - Max uninterrupted instructions per time slice (int) mpi_max_commands - Max number of uninterruptable MPI commands (int) pause_min - Pause between input and output servicing (int) free_frames_pool - Number of program frames pre-allocated (int) listen_mlev - Minimum MUCKER level for _listen programs (int) playermax_limit - Manimum allowed connections (ref) player_start - The home for players without a home (bool) use_hostnames - Do reverse domain name lookup (bool) log_commands - The server logs commands (Wizbit only) (bool) log_failed_commands - The server logs failed commands (Wizbit only) (bool) log_programs - The server logs programs (Wizbit only) (bool) dbdump_warning - Warn about coming DB dumps (bool) deltadump_warning - Warn about coming delta dumps (bool) periodic_program_purge - Purge unused programs from memory (bool) support_rwho - Use RWHO server (bool) secure_who - WHO works only in command mode (bool) who_doing - Server support for @doing (bool) realms_control - Support for realm wizzes (bool) allow_listeners - Allow listeners (bool) allow_listeners_obj - Objects can be listeners (bool) allow_listeners_env - Listeners can be up the environment (bool) allow_zombies - Zombie objects allowed (bool) wiz_vehicles - Only wizzes can make vehicles (bool) force_mlev1_name_notify - M1 programs forced to show name on notify (bool) restrict_kill - Can only kill KILL_OK players (bool) registration - Only wizzes can create players (bool) teleport_to_player - Allow use of exits linked to players (bool) secure_teleport - Check teleport permissions for personal exits (bool) exit_darking - Players can set exits dark (bool) thing_darking - Players can set objects dark (bool) dark_sleepers - Sleepers are effectively dark (bool) who_hides_dark - Dark players are hidden (Wizbit only) (bool) compatible_priorities - Backwards compatibility for exit priorities (bool) do_mpi_parsing - Parse MPI strings in messages (bool) look_propqueues - Look triggers _lookq propqueue (bool) lock_envcheck - Locks will check the environment (bool) diskbase_propvals - Allow diskbasing of property values (bool) idleboot - Enable or disable idlebooting (bool) playermax - Enable or disable connection limit
Level one MUCKER's are apprentices. Their powers are restricted as they cannot get information about any object that is not in the same room they are. ie: OWNER, NAME, LOCATION, etc all fail if the object isn't in the same room as the player. Level one MUCKER programs always run as if they are set SETUID. NOTIFY, NOTIFY_EXCEPT, and NOTIFY_EXCLUDE will refuse to send messages to rooms the user is not in. Level one programs cannot use ADDPENNIES. Level one programs don't list DARK objects or rooms in the contents of a room, unless they are controlled by the program owner. Additionally, level one programs have an absolute instruction limit that is the same size as the PREEMPT instruction limit. This is usually around 20,000 instructions.
Level two MUCKERs are also called Journeymen. Their permissions are equivalent to the permissions for a normal MUCKER under older versions of the server. Level two programs can run as many as four times the number of instructions that a preempt program could. This is usually around 80,000 instructions.
Level three MUCKERs are referred to as Masters. They can use the con- nection info primitives (ie: CONDBREF, ONLINE, etc.), read the EXITS list of any room, use NEXTPROP on objects, can use NEWROOM, NEWOBJECT, NEWEXIT, and COPYOBJ without limitations, can use QUEUE and KILL, and can override the permissions restrictions of MOVETO. You only give a player MUCKER level 3 if they are very trusted. There is no absolute instruction count limit for level three or above, except for programs running in PREEMPT mode.
A player who is wizbitted is effectively Mucker Level 4. MUCKER level four is required for the RECYCLE primitive, the CONHOST primitive, the FORCE primitive, and the SETOWN primitive. ML4 also allows overriding of permissions of the SET* primitives, and property permissions. Props not listed by NEXTPROP with ML3 are listed with ML4. Programs running ML4 do not even have instruction limits on PREEMPT mode programs.
The MUCKER level permissions that a program runs at is the lesser of it's own MUCKER level and the MUCKER level of it's owner.
If it is owned by a player who is MUCKER level 2, and it is MUCKER level 3, then it runs at Mucker level 2. The one exception to this is programs owned by a Wizard player. They run at Mucker level 2 if the program itself is not wizbit, and at Mucker level 4 if the program IS set wizbit.
Mucker level is referred to in flags lists by M# where the # is the Mucker level. Level zero objects don't show a flag for it. Example:
Revar(#37PM3)
In verbose flags lists, Mucker levels greater than zero are shown by MUCKER# where # is the mucker level.
To set a level on a player or program, use the level number as the flag name. MUCKER is the same as 2, and !MUCKER is the same as 0. Example:
@set Revar=2
A player may set the MUCKER level on a program they own to any level lower than or equal to their own level, and a wizard may set a program or player to any MUCKER level.
When a program is created, it is automatically set to the same MUCKER
level as the creating player. When a program is loaded from an old db,
if it is Mucker Level 0, it is upgraded to Mucker Level 2.
See also FOREGROUND, BACKGROUND, PREEMPT, FORK, QUEUE, KILL, and SLEEP.
$defineBasically the same as C's #define$enddef
$defThis is the same as $define, except that the definition stops at the end of the program line, without using an ending $enddef.
$undefAbout the same as C's #undef
$echoEchos the given string to the screen of the person compiling the program. Runs at compile-time.
__versionA pre-defined macro that contains the current server version. Contains the same string that the VERSION primitive returns.
$ifdefwhere$else $endif $ifndef $else $endif
$ifndef __version>Muck2.2fb3.5 $define envprop .envprop $enddef $endif $define ploc $ifdef proplocs .proploc $else $endif $enddef
$includeSets a bunch of $defines from the properties in the /_defs/ propdir. For example, if object #345 had the following properties:
/_defs/desc: "_/de" getpropstr /_defs/setpropstr: dup if 0 addprop else pop remove_prop then /_defs/setpropval: dup if "" swap addprop else pop remove_prop then /_defs/setprop: dup int? if setpropval else setpropstr thenthen if a program contained
$include #345in it, then all subsequent references to 'desc', 'setpropstr', 'setpropval' and 'setprop' would be expanded to the string values of their respective programs. ie:
descwould be replaced throughout the program with
"_/de" getpropstrNOTE: You cannot have a slash in a definition name. ie: The property
_defs/a/b:foowill NOT make a definition named a/b.
You can now escape a token in MUF so that it will be interpreted literally. ie:
\.pmatchwill try to compile
.pmatchwithout expanding it as a macro. This lets you make special things with $defines such as:
$define addprop over over or if \addprop else pop pop remove_prop $enddefso that all the 'addprop's in the program will be expanded to the definition, but the 'addprop' in the definition will not try to expand recursively. It will call the actual addprop.
you have to do in your program is, at the beginning of it,
$include $lib/
then just use the function name to invoke it later in your program
and it will run as if it were a function in your program.
How to make a library:
1) create a program with several useful generic subroutines.
2) DOCUMENT those subroutines in a commented out header in the prog.
3) @set
prefix of "lib/". ie:
you will need to set properties on the program in the form
_defs/
where
invoke it in their programs,
gave it (ie: lib/strings), and
the function in the program. Example:
Currently standard libraries:
REPEAT will do an unconditional jump to the statement after the BEGIN
statement.
UNTIL checks to see if the value on the stack is false. If it is, it
jumps execution to the statement after the BEGIN statement, otherwise,
it falls through on execution to the statement after the UNTIL.
Within a loop, even within IF-ELSE-THEN structures within the loop
structure, you can place WHILE, CONTINUE, or BREAK statements. There
is no limit as to how many, or in what combinations these instructions
are used.
A WHILE statement checks to see if the value on the stack is false.
If it is, execution jumps to the first statement after the end of
the loop. If the value was true, execution falls through to the
statement after the WHILE.
The CONTINUE statement forces execution to jump to the beginning of
the loop, after the BEGIN.
The BREAK statement forces execution to jump to the end of the loop,
at the statement after the REPEAT or UNTIL, effectively exiting the
loop.
Note: You can nest loops complexly, but WHILE, BREAK, and CONTINUE
statements only refer to the innermost loop structure.
Example of a complex loop structure:
If a program is set DARK (DEBUG), then when it is run, it will print out
a stack trace for each instruction executed, to the player running the
program. This is useful for debugging programs.
On dbload, if a program is set ABODE (AUTOSTART), *AND* it is owned by
a wizard, then it will be placed in the timequeue with a delay of 0 and
a string parm of "Startup". Autostart programs run with the location
NOTHING (#-1) rather than the location of the owner of the program.
If a program has the HAVEN flag set on it (HARDUID) then it runs with
the uid and permissions of the owner of the trigger of the program.
If the program is a timequeue event with trigger of #-1, then it
will run with the permissions and uid of the program owner as in SETUID.
If a program is set both SETUID and HARDUID, and it is owned by a wizard,
then it inherits the uid and mucker level of the program that called it.
If it was not called by a program, then it runs SETUID. This is useful
for writing libraries.
Programs set BUILDER (BOUND) run in preempt mode, regardless of the mode
of the program. ie: a foreground program, while running in a program set
BOUND, will run pre-empt, with the multitasking effectively shut off.
A program that is set WIZARD ignores almost all permissions checking.
The Mucker Level of the program also has a great deal of influence on what
a program can and cannot do. See MUCKER LEVELS for more information.
There is a COMMAND variable, similar to ME, LOC, and TRIGGER, except that
it contains a string. The string contains the command the user typed
that triggered the the program, without the command line arguments. ie:
if there was an exit named
Programs are now compiled when they are run or called instead of when
the database is loaded. They are compiled with the uid of the owner
of the program.
A room or player may have a "_connect" property set that contains the
dbref of a program to run when a player connects. The program must be
either link_ok or must be owned by the player connecting. When the
program is run, the string on the stack will be "Connect", the "loc @"
will be the location of the connecting player, the "me @" will be the
connecting player, and the "trigger @" (and "trig") will be the object
that had the _connect property on it. All programs referred to by
_connect properties on the player, and on rooms down the environment tree
from the player, will be QUEUEd up to run. When a player disconnects,
programs referred to by _disconnect properties will be run in a similar
manner. (connect and disconnect _actions_ are also implemented.)
Programs referred to by props in _depart/_arrive/_connect/_disconnect
propdirs will all be queued up, eliminating the need for a dispatcher
program. An example would be
Thanks WF!
@reg lib-strings=lib/strings
7) Set up the interface for each function on the program. To do this,
@set lib-strings=_defs/.split:"$lib/strings" match "split" call
8) You're done!
$lib/strings Functions for manipulating strings.
$lib/props Routines for searching for properties, or setting them.
$lib/lmgr Standard list manager routines.
$lib/stackrng Routines to handle variable sized ranges on the stack.
$lib/edit String range editing and manipulation routines.
$lib/editor Standard user text editor.
$lib/mesg Standard message manager routines.
$lib/mesgbox Routines for handling lists of messages.
$lib/match Object or string matching routines.
$lib/reflist Dbref-list management routines.
$lib/index Hashed linked list manager with partial key matching.
The BEGIN statement marks the beginning of a loop.
Either the UNTIL or the REPEAT statement marks the end of the loop.
101 begin (BEGIN the outer loop)
dup while 1 - (This WHILE, ...)
dup not if break then (this BREAK, and..)
dup 2 % not if continue then (this CONTINUE refer to the outer loop)
dup 10 % not if
15 begin (BEGIN inner loop)
dup while 1 - (This WHILE, and.. )
dup 5 % not if break then (... this BREAK, refer to inner loop)
repeat (This REPEAT statement ends inner loop.)
then
dup 7 % not if continue then (This CONTINUE, and...)
dup 3 % not if dup 9 % while then (this WHILE refer to the outer loop)
dup intostr me @ swap notify
dup 1 = until pop (This UNTIL ends the outer loop)
Flags that have importance to MUF:
When a message is notify_except'ed or notify_exclude'ed to a room, and
LISTENERS and LISTENERS_ENV are defined, then it will run ALL the
programs referred to in all the _listen properties down the environment
tree, And in all of the objects in the room with LISTENERS_OBJ defined.
Also, the muf NOTIFY primitive was changed to run the _listen program
on an object or player if a message is sent to them that way.
"abracadabra;foo bar;frozzboz"
that was linked to the program, and the user typed in
"foo bar baz"
then the program would run with "baz" on the stack, and "foo bar" in the
global COMMAND variable.
_connect/announce:1234
That would queue up program #1234 when a player connects.
The name ("announce") is not important, and can be anything you want,
but they are queued up in alphabetic order.
Credits:
The people responsible (at fault?) for this manual are:
Foxen (foxen@netcom.netcom.com), who wrote the original terrible docs, and
WhiteFire (kinomon@glia.biostr.washington.edu), who cleaned them up a lot.