Programmer Help (#24) ===================== # @display @grep @property ; @display-options help @prospectus @add-feature @displayoptions @kill regular-expressions ajuda @edit language @remove-feature @args @egrep @list @rmproperty bilingual error-handling mail @rmverb bilingue errors precedence scattering @chmod eval prepositions @setenv @clearproperty examina prog-index @show @copy examine @prog-options statements correio expressions @program tasks @dbsize features .program truth @disinherit @forked programar utilities @disown functions programming @verb # = #<string>[.<property>|.parent] [exit|player|inventory] [for <code>] returns information about the object (we'll call it <thing>) named by string. String is matched in the current room unless one of exit|player|inventory is given. If neither .<property>|.parent nor <code> is specified, just return <thing>. If .<property> is named, return <thing>.<property>. .parent returns parent(<thing>). If <code> is given, it is evaluated, with the value returned by the first part being substituted for %# in <code>. For example, the command #JoeFeedback.parent player for tonum(%#) will return 26026 (unless Joe has chparented since writing this). @ADD-FEATURE/@REMOVE-FEATURE ============================ Note to programmers: @add-feature and @remove-feature are front-ends for player:add_feature and :remove_feature. :add_feature returns * E_PERM unless caller == this || $perm_utils:controls(caller_perms()) * E_INVARG if feature is not an object or is invalid * E_PERM if the object is not feature_ok * a true value otherwise and calls feature:feature_add, if the verb exists. :remove_feature returns * E_PERM unless caller == this || $perm_utils:controls(caller_perms()) || caller_perms() == feature.owner * a true value otherwise and calls feature:feature_remove, if the verb exists. @ARGS ===== Syntax: @args <object>:<verb-name> <dobj> @args <object>:<verb-name> <dobj> <prep> @args <object>:<verb-name> <dobj> <prep> <iobj> Changes the direct object, preposition, and/or indirect object specifiers for the named verb on the named object. Any specifiers not provided on the command line are not changed. The direct and indirect object specifiers (<dobj> and <iobj>) must be either 'none', 'this', or 'any'. The preposition specifier (<prep>) must be either 'none', 'any', or one of the prepositional phrases listed in `help prepositions'. BILINGUAL/BILINGUE ================== MOOsaico began as a bilingual MOO but is now it is a multilingual MOO. Please do "help multilingual". @CHMOD ====== Syntax: @chmod <object> <object-permissions> @chmod <object>.<prop-name> <property-permissions> @chmod <object>:<verb-name> <verb-permissions> Changes the permissions of an object, property or verb, to those given. The following table shows what permission bits are allowed for each form of the command: <object-permissions> r, w, f <property-permissions> r, w, c <verb-permissions> r, w, x, d See the LambdaMOO Programmer's Manual for their meanings. To clear all of the permissions for an object, verb, or property, use "" as the second argument. @chmod also accepts +, !, and - as modifiers for a single permission to add or subtract that permission from the current set. (! and - are the same.) Examples: Set a verb to be Readable and Callable: @chmod chair:sit rx Set a verb to be not Callable, without changing its other permissions: @chmod cookies:eat !x Set an object to be Writeable in addition to any current bits: @chmod table +w @CLEARPROPERTY ============== Syntax: @clearproperty <object>.<prop-name> This clears <object>'s <prop-name> property. That is the property value becomes `clear' and all further references to this property will use the value of the same property on the parent object. Note that you can only clear inherited properties. Nor is this the same as removing a property; the property continues to exist. `@clearproperty' can be abbreviated as `@clearp'. Example: @create #1 named foo You now have foo with object number #42 and parent Root Class (#1). [foo, as a child of #1 has a .description property which starts out clear] ;#1.description => "" ;#1.description = "You see nothing special" => "You see nothing special" ;#42.description => "You see nothing special" ;#42.description = "Something special" => "Something special" [foo.description is now no longer clear; it has a value of its own] ;#1.description = "Boring" => "Boring" ;#42.description => "Something special" @clearp foo.description Property #42.description cleared; value is now "Boring". [foo.description is now clear again] ;#1.description = "" => "" ;#42.description => "" @COPY ===== Syntax: @copy <object>:<verb> to [<newobject>][:<newverb>] Copies the code of the named verb to the new object and verbname. Permissions, and arguments of the new verb are set to match those of the old verb in the event that the new verb does not already exist. One of <newobject> or :<newverb> must be supplied. If no new verbname is given, the old name is retained. Likewise, <newobject> defaults to <object> if not given. Examples: @copy me:verbname to myobject @copy me:test_verb to myobject:real_verb In general, @copy'ing verbs is a bad idea. In the vast majority of cases, the desired effect can be accomplished with parenting (i.e., having <object> be an ancestor of <newobject>), which has the advantage that if a verb is updated or fixed, this immediately becomes available to child objects that inherit this verb. In such a case, copies that were made using @copy have to be tracked down and fixed by hand. This facility is provided for those rare occasions where one has no choice but to actually copy the verb. @DBSIZE ======= Syntax: @dbsize @dbsize goes through the entire database, counting the valid and invalid objects, giving a summary at the end. This information can be useful, but because this command is cpu intensive, it should be used sparingly. @DISINHERIT/@DISOWN =================== Syntax: @disinherit <object> @disinherit <object> [from <parent>] Synonym: @disown This command is used to remove an unwanted child from an object you own. If you owned said child, you could use @chparent; this command is to cover the other case, namely where you don't own the child. Both forms of this command chparent <object> to its grandparent, provided you own the parent. The second form matches the string you supply for <object> against the list of children of the given <parent>. Turning off the fertile bit (.f) for a particular object prevents others from creating children of it or chparenting to it (see `help @chmod'). Note also that, though the name might seem to indicate otherwise, this command does not change the ownership of any object. @DISPLAY ======== Syntax: @display <object>.[property] ,[inherited_property] :[verb] ;[inherited_verb] @display is a fancy version of @show. As @show, it can select individual verbs or properties to display. In addition, it can display all the verbs or properties defined on an object, or all the verbs or properties defined on any of the object's ancestors. Don't specify a property or verbname after the punctuation mark to get the "all" feature. Its display is more compact than that of @show (it uses a one-line format, and truncates values that don't fit in the value field). You may mix properties and verbs on the command line, but the parser may become confused. (E.g. @display object,: displays all properties including inherited ones plus all locally defined verbs on the object.) Examples: Individual property: @display poolsweep.count .count yduJ (#68) r c 8 Individual verb: @display poolsweep:tell #3560:tell yduJ (#68) rxd this none this All properties, including one truncated value: @display poolsweep. poolsweep (#3560) [ readable ] Owned by yduJ (#68). Child of generic thing (#5). Location The Pool (#1428). .gagged yduJ (#68) r c 0 .count yduJ (#68) r c 8 .messages yduJ (#68) r c {"The poolsweep stir.. .index yduJ (#68) r c 2 .quantum yduJ (#68) r c 20 Inherited verbs, edited for brevity, showing verbs from various parents, with owners, permissions, and argument lists. @d poolsweep; poolsweep (#3560) [ readable ] #3560:tell yduJ (#68) rxd this none this #3560:description yduJ (#68) rxd this none this #5:"g*et t*ake" Haakon (#2) rxd this none none #5:"d*rop th*row" Haakon (#2) rxd this none none #5:moveto Haakon (#2) rxd this none this #1:description Haakon (#2) rxd this none this #1:look_self Haakon (#2) rxd this none this Some aspects of @display can be customized (see `help @display-options'). @DISPLAY-OPTIONS/@DISPLAYOPTIONS ================================ Syntax: @display-option @display-option <option> Synonym: @displayoption The display options customize the behavior of the @display command to your particular taste. The first form of this command displays all of your display options. The second form displays just that one option, one of the flags listed below. The remaining forms of this command are for setting your display options: @display-option +<flag> @display-option -<flag> @display-option !<flag> (equivalent to -<flag>) These respectively set and reset the specified flag -blank_tnt Show the verb args on all verbs. +blank_tnt Don't show the verb args on `this none this' verbs. -shortprep Use full prepositions (e.g., "on top of/on/onto/upon") +shortprep Use short prepositions (e.g., "on") -thisonly Specifying . (:) to retrieve all properties (verbs) will go up the ancestor chain until it finds a readable object with properties (verbs) defined on it. +thisonly Specifying . (:) to retrieve all properties (verbs) will only display properties (verbs) defined on the object itself. @EDIT ===== ERROR-HANDLING ============== This is part of 'help statements'. TRY statements-0 ; EXCEPT variable-1 (codes-1) statements-1 ; EXCEPT variable-2 (codes-2) statements-2 ; ... (up to 255) ENDTRY Each of the `statements-x' may be any number or combination of MOO statements and function calls. Each of the `codes-x' may be either the keyword `ANY' or else a comma-separated list of expressions that yield error codes. If the execution of `statements-0' raises an error listed in the `codes-x', then the statements associated in that EXCEPT clause where the code was listed are executed. When this occurs, `variable-x' is assigned this information about the error being raised: {<error code>, <error message>, <value>, <traceback>}. If the error raised is not listed in any EXCEPT clause (which means the `ANY' keyword was not used), then the error continues to be raised. TRY statements-0 ; FINALLY statements-last ; ENDTRY In this construct, `statements-0' are executed. Then, whether an error was raised by their execution or not, `statements-last' are executed. If `statements-0' transfers control somewhere else, that transfer is interrupted so that `statements-last' can be run. If `statements-last' transfers control, then that overrides the first transfer. (Transfers include raising an error, returning from this verb, terminating the current iteration of a surrounding loop). `Statements-last' will always be executed, providing a good place for necessary cleanup code that will run even if `statements-0' doesn't simply run normally to completion. ERRORS ====== The complete list of error codes: E_NONE No error E_TYPE Type mismatch E_DIV Division by zero E_PERM Permission denied E_PROPNF Property not found E_VERBNF Verb not found E_VARNF Variable not found E_INVIND Invalid indirection E_RECMOVE Recursive move E_MAXREC Too many verb calls E_RANGE Range error E_ARGS Incorrect number of arguments E_NACC Move refused by destination E_INVARG Invalid argument E_QUOTA Resource limit exceeded EVAL/; ====== Syntax: eval <MOO-code> ; <MOO-code> eval-d <MOO-code> Evaluates the given piece of MOO code and prints the resulting value. If the MOO code begins with one of the MOO language keywords ('if', 'for', 'while', 'fork', or 'return') or with the character ';', then the entire piece of code is treated as the program for a verb, with ';' appended to the end. Otherwise, 'return' is appended to the front and ';' is appended to the end and that string is treated as the code for a verb. In either case, the resulting verb is invoked and whatever value it returns is printed. For programmers, this is such a mind-bogglingly useful thing to do that there is a simple abbreviation for this command; any command beginning with a semicolon (';') is treated as a use of 'eval'. Eval treats specially a duplicated semicolon at the beginning. It enables you to make multi-statement programs within eval (but does not by default print the return value). Eval-d (no ";" abbreviation for this) evaluates the following text exactly as eval, except that the "d" debug flag (see programmer's manual for explanation) is turned off. Thus errors will cause an error return value rather than a traceback. If you set the player property .eval_time to 1, then eval will print out how many ticks and seconds the program required. Examples: eval 3 + 4 => 7 ;3+4 => 7 ;for x in (player.aliases) player:tell(x); endfor Haakon Wizard ArchWizard => 0 ;;l = {}; for i in [1..10] l = {@l, i}; endfor return l => {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} eval-d 8 + "foo" => E_TYPE (Type mismatch) You may customize your evaluation environment. The player property .eval_env may contain statements to be executed prior to any evaluated program. Two caveats: This will throw off the tick count. You can account for additional ticks inserted by your environment with the .eval_ticks property; just set it to the number of ticks you'd like subtracted from the total. Additionally, if you make a syntax error in your program, the line reported will be wrong (it will count those initial statements), and if you make an error in the eval_env itself, you can be in deep trouble. Despite these drawbacks, the eval_env property can be quite useful. The following is a sample: Eval_env: "me=player;here=player.location;" eval_ticks: 3 See also @setenv. You can also define textual substitutions in a separate property, called eval_subs. These are discouraged, however, for anything that can be done with variable assignments, because the overhead of replacing the strings in the evaluated program is significant. However, some things, such as substituting characters which can't be typed easily on one keyboard (e.g. "[]" is difficult to type on some IBM keyboards), can only be done by textual substitutions. Note that the eval substitutions are also interpreted by the verb editor when "eval_subs" is selected in your .edit_options property (see `help editors'). This adds to their overhead, but again, makes it possible for people to program who otherwise can't type the full character set. Remember: Don't use eval_subs unless you really have to! EXAMINE/EXAMINA =============== [Note to programmers: the 'obvious' verbs are those that can be invoked as commands and are not specified by the :hidden_verbs verb. The default definition of "hidden" is "not readable". You can override this definition with a :hidden_verbs verb that gets the default list with pass(@args) and then alters that list.] EXPRESSIONS =========== The following kinds of expressions exist in the MOO programming language: number # number # - number "character string" error-name Literal expressions return the obvious values: numbers (floating-point or integers), object numbers, strings, and errors. { expression , expression , ... , expression } The list-construction expression evaluates the each of the expressions in turn and returns a list whose elements are the results of those expressions. Any of the expressions may be prefixed with an at-sign ('@'); in this case, that expression must return a list and, rather than that list becoming an element of the final list, its elements are spliced into the final list. name Variable expressions return the current value of the named variable. Variable names must start with a letter or underscore ('_') and contain only letters, digits, and underscores. The following variables are predefined: OBJ, STR, LIST, ERR, INT, FLOAT, NUM (same as INT) player, caller, this, verb, args argstr, dobj, dobjstr, prepstr, iobj, iobjstr Their initial values are described in detail in the LambdaMOO Programmer's Manual. expression . name expression . ( expression ) $ name Property-reading expressions return the current value of a named property on the object that is the value of the first subexpression. In the second form, the second subexpression must return a string, the name of the property to be read. The third form is an abbreviation for '#0.name'. expression : name ( arguments ) expression : ( expression ) ( arguments ) Verb-call expressions invoke a named verb on the object that is the value of the first subexpression, passing the given arguments. In the second form, the second subexpression must return a string, the name of the verb to invoke. The syntax and semantics of arguments is exactly as in the list-construction expression but no initial or final curly-braces ('{' or '}') are used. function ( arguments ) The function-call expression invokes one of the MOO primitive functions, as listed in 'help functions', passing the given arguments. expression [ expression ] The indexing expression first evaluates the two subexpressions; call their values S and N, respectively. S must be a string or a list and N must be a number between 1 and the length of S, inclusive. The Nth element of S is returned. The elements of a string are themselves one-character strings. The special character `$' maybe used for N as shorthand for the length of the string or list S. expression [ expression .. expression ] The subsequence expression first evaluates the three subexpressions; call their values S, N1, and N2, respecitively. S must be a string or a list and N1 and N2 must be numbers. If N1 <= N2, then both must be between 1 and the length of S, inclusive; the subsequence of S beginning at index N1 and continuing through index N2 is returned. If N1 > N2, the empty sequence of the same type as S is returned, either "" or {}. name = expression expression . name = expression expression . ( expression ) = expression $ name = expression Assignment expressions give new values to variables and object properties. For the second and third forms, the expressions on the left-hand side of the '=' are evaluated first. Then the right-hand side expression is evaluated and result is stored in the indicated variable or object property. There is a special kind of assignment involving lists on the left hand side. See `help scattering' for details. expression + expression expression - expression expression * expression expression / expression expression % expression - expression expression ^ expression The arithmetic expressions evaluate the subexpressions, all of which must return numbers of the same type (integer or floating-point), and then perform addition, subtraction, multiplication, division, remaindering, negation, or raising to a power, respectively. For addition, the subexpressions may both return strings as well; in this case, the result is the concatenation of the two strings. For the last operation, raising to a power, if the first expression is an integer, the second must also be an integer. But if it is floating-point, then the second can be either floating point or an integer. This is the only type mixing permitted. You must do explicit type conversions with built-in functions (toint(), tofloat()) before evaluation mixed expressions on the other operations. expression == expression expression != expression expression < expression expression <= expression expression > expression expression >= expression The comparison expressions evaluate the subexpressions and then test whether or not the first result is equal to, unequal to, less than, less than or equal to, greater than, or greater than or equal to the second result, respectively. If the indicated relation holds then they return 1 and otherwise they return 0. Comparisons of strings are performed case-insensitively, those of lists are performed on an element-by-element basis, objects are compared by their object numbers, and errors by an ordering given in the LambdaMOO Programmer's Manual. expression ? expression | expression expression && expression expression || expression ! expression The logical expressions each return results based upon the truth value of their first subexpression; call the value of this expression X. The first of these returns the value of the second subexpression if X is a true value and that of the third expression if X is a false value; the unused subexpression is not evaluated. The definitions of 'true value' and 'false value' are given in 'help truth'. The expression 'E1 && E2' is an abbreviation for 'E1 ? E2 | E1' except that E1 is only evaluated once. The expression 'E1 || E2' is an abbreviation for 'E1 ? E1 | E2' except that E1 is only evaluated once. The expression '! E' is an abbreviation for 'E ? 0 | 1'. expression IN expression The list-membership expression first evaluates both subexpressions; call their values E and L, respectively. L must be a list. If E is an element of L, then the index of the first occurence of E in L is returned. If E is not an element of L, then 0 is returned. `expression-1 ! codes => expression-2' NOTE: the open- and close-quotation marks are really part of the syntax; they must be typed in. `Codes' is either the keywoard ANY or a comma-separated list of expressions that when evaluated should yield a list of error codes to be caught if they're raised. If `expression-1' is evaluated without raising an error, then its value is the value of the entire expresion. If it raises an error that is listed in `codes', it is caught. If the `=> expression-2' part was included (it is optional), then it is evaluated and its value is the result of the entire expression. If `expression-2' was omitted, then the error is the value of the expression. If the error was not listed and caught, then the error contines to be raised. The method for disambiguating the meaning of a complex MOO expression in the absence of sufficient parentheses is described in 'help precedence'. FEATURES ======== Note to programmers: In order to be available for general use as a feature, an object must have a verb or property named "feature_ok" which returns a true value. When a feature is added to a player's features list, feature:feature_add is called, if it exists, with the player in question as its argument. Likewise, when a feature is removed, feature:feature_remove is called. @FORKED ======= Syntax: @forked Gives a list of all of the forked tasks you own, along with detailed information about each one. The information includes the following: Queue ID: A numeric identifier for the task, for use in killing it (see 'help @kill'). Start Time: The time after which the task will begin execution. Owner: The player whose permissions under which the task is running. Unless you are a wizard, @forked will show only your tasks. Verb: The object and verb-name of the code that forked the task. Line: The line number of the first statement that the task will execute when it starts. Note that the code for the verb in question may have changed since the task was forked; the forked task will use the version that was being executed when it was forked. This: The value of `this' for the forked task, in the case that it is different from (i.e., is a descendant of) the object on which the verb code lives. FUNCTIONS ========= There are many, many built-in functions available to MOO programmers. The following list gives a brief summary of the arguments and purpose of each function; for more information, see the LambdaMOO Programmer's Manual. pass(arg, ...) -- calling a verb defined on this object's parent eval(string) -- parsing and executing strings as MOO code notify(player, string) -- sending text to a player's terminal read() -- reading a line of input from the player (*) output_delimiters(player) -- return {prefix,suffix} set by PREFIX/SUFFIX cmds typeof(value) -- determining the data type of a value tostr(value, ...) -- converting any set of values into a string tonum(value) -- converting any non-list value into a number toobj(value) -- converting any non-list value into an object length(value) -- returns the length of a string or list listappend(list, value [, index]) -- adding an element at the end of a list listinsert(list, value [, index]) -- adding an element at the head of a list listset(list, value, index) -- updating a list at some index listdelete(list, index) -- removing an element from a list setadd(list, element) -- adding an element to a set represented as a list setremove(list, element) -- removing an element from such a set min(n1, n2, ...) -- minimum of n1,n2,... max(n1, n2, ...) -- maximum of n1,n2,... abs(n) -- absolute value of n sqrt(n) -- square root of n, rounded down random(n) -- random integer between 1 and n inclusive time() -- current time in seconds since midnight GMT, 1 Jan 70 ctime([time]) -- time (or current time) converted to a human-readable string index(str1, str2 [, case-matters]) -- index of first str2 in str1 rindex(str1, str2 [, case-matters]) -- index of last str2 in str1 strcmp(str1, str2) -- case-sensitive string comparison strsub(subject, what, with [, case-matters]) -- substitution in a string crypt(string [, salt]) -- one-way string encryption match(str1, str2 [, case-matters]) -- match first regular expr str2 in str1 rmatch(str1, str2 [, case-matters]) -- match last regular expr str2 in str1 substitute(template, subs) -- perform substitutions on template valid(object) -- testing whether an object exists create(parent [, owner(*)])-- creating a new MOO object recycle(object) -- destroying a MOO object move(object, where) -- altering the object-containment hierarchy chparent(object, new-parent) -- altering the object-inheritance hierarchy parent(object) -- object's parent in the inheritance hierarchy children(object) -- object's children in the inheritance hierarchy max_object() -- the highest-numbered object in the MOO renumber(obj) -- changes an object's number to lowest available one (*) reset_max_object() -- resets max_object() to the largest valid object (*) properties(object) -- a list of the properties defined on an object add_property(object, prop-name, value, info) -- add a new property delete_property(object, prop-name) -- remove a property property_info(object, prop-name) -- {owner, perms} info on a property set_property_info(object, prop-name, info) -- setting same is_clear_property(object, prop-name) -- find out if a property is "clear" clear_property(object, prop-name) -- make a property "clear" verbs(object) -- a list of the verbs defined on an object add_verb(object, info, args) -- add a verb to an object delete_verb(object, verb-name) -- remove a verb from an object verb_info(object, verb-name) -- {owner, perms, names} info for a verb defn. verb_args(object, verb-name) -- {dobj, prep, iobj} argument info for a verb verb_code(object, verb-name [, fully-paren [, indent]]) -- program listing set_verb_info(object, verb-name, {owner, perms, names}) set_verb_args(object, verb-name, {dobj, prep, iobj}) set_verb_code(object, verb-name, {line, line, ...}) is_player(object) -- testing whether or not object is a player players() -- a list of all players, active or not connected_players() -- a list of all currently-connected players idle_seconds(player) -- seconds since given player typed anything connected_seconds(player) -- seconds given player has been logged in boot_player(player) -- disconnect player from the MOO immediately(*) set_player_flag(player, value) -- set/clear player bit; boot player if clear(*) connection_name(player) -- a server-assigned name for player's connection open_network_connection(@args) -- open a connection to another network site caller_perms() -- the player whose permissions your caller was using set_task_perms(player) -- changing permissions of the running task (*) callers() -- list of {obj, verb, owner, vloc, player}: this task's stack suspend(secs) -- suspending the current task for a number of seconds seconds_left() -- number of seconds left in the current task ticks_left() -- number of ticks left in the current task task_id() -- a random number representing the currently-running task queued_tasks() -- list of {id,start,0,20000,owner,obj,verb,line,this} kill_task(id) -- delete one of your tasks from the queue server_log(string) -- add a comment to the server log file server_version() -- a string of three numbers "major.minor.release" memory_usage() -- {{blocksize, nused, nfree}, ...}, the server's memory stats shutdown(msg) -- print msg and kill the server (*) dump_database() -- what it says (*) (*) => as you might have expected, these usually require wizard permissions. @GREP/@EGREP ============ Syntax: @grep <string> in <object> @grep <string> in {<objectlist>} @egrep <regexp> in <object> @egrep <regexp> in {<objectlist>} These are named for the corresponding unix utilities. @grep searches the given object(s) for verbs whose verbcode contains the given string as a substring of one of its lines. @egrep searches the given object(s) for verbs whose verbcode contains a substring matching the given regular expression (see `help regular-expressions'). HELP/AJUDA ========== For programmers, the help system provides the following additional forms: help object:verbname -- prints any documentation strings that are present at the beginning of the program for that verb. help $<whatever>_utils -- prints general information about one of the $..._utils objects (e.g., $string_utils, $list_utils, etc...), which are all libraries of generally used verbs. help builtin() -- prints documentation from the programmers manual about the named primitive, for example length() For information about how the help system itself works and about how to associate local help databases with specific rooms or player classes, see `help $help'. @KILL ===== Syntax: @kill task_id @kill [object]:[verb] @kill soon [number-of-seconds] @kill all @kill %trailing_id Immediately kills one or more forked tasks. The '@forked' command is useful for finding out what tasks you have pending; see 'help @forked' for details. Only the owner of a task may kill it. @kill task_id kills only the task with that id. @kill object:verb kills all tasks which were scheduled by the object running the verb named. Both object and verb are optional: @kill object: kills all tasks scheduled by that object, and @kill :verb kills all tasks which were scheduled by any object running that verb. This can be useful if you have several similar objects which are running tasks from similarly named verbs. (Perversely, @kill : kills all tasks... Any object running any task.) @kill soon kills all tasks scheduled within the next minute. @kill soon number kills all tasks scheduled within that number of seconds, e.g. @kill soon 300 would kill all tasks scheduled within the next five minutes. This can be useful if you have a runaway task you want to quickly remove, but don't want to kill you later tasks. @kill all kills all tasks. Like @kill soon, but more dramatic. @kill %trailing_id expects you to specify the last few digits of a task id. It then kills all tasks that end with those digits. Example: @forked 1359083655 Sep 16 21:45:00 1991 yduJ #5803:heartbeat (10) [#68] @kill %655 Killed: task 1359083655, verb #5803:heartbeat, line 10, this==#68 LANGUAGE ======== The MOO programming language is described in excruciating detail in the LambdaMOO Programmer's Manual, available for FTP from parcftp.xerox.com in the file pub/MOO/ProgrammersManual.txt or ftp.ci.uminho.pt in the file /pub/net/moo/manuals/ProgrammersManual.*.gz. The online help consists of a few quick reference guides here in the help system under the following topics: statements -- the syntax and semantics of the various kinds of MOO statements expressions -- the same for the various kinds of MOO expressions functions -- a list of the primitive functions available to MOO programs @LIST ===== Syntax: @list <object>:<verb> @list <object>:<verb> [with|without parentheses|numbers] @list <object>:<verb> <dobj> <prep> <iobj> @list <object>:<verb> <start>..<end> Prints out the code for the MOO program associated with the named verb on the named object. Normally, the code is shown with each line numbered and with only those parentheses that are necessary to show the meaning of the program. You can e.g., specify `without numbers' to have the numbers omitted or `with parentheses' to include all parentheses or even `with parentheses without numbers' to do both. The 3rd form of the verb lists the verb matching the given dobj/prep/iobj specification if such exists. The 4th form prints only those lines in the specified range. Example: Type `@list $room:@move' to see the code for the `@move' command, or even `@list $prog:@list' to see the code implementing @list itself... The 2nd-4th forms may be combined, e.g., @list frobule:burfle this in front of any without numbers 1..10 which would be useful if `frobule' had more than one `burfle' verb and we wanted to see the first 10 lines of the one having `this' `in front of' `any' as its respective dobj/prep/iobj specifiers. MAIL/CORREIO ============ - - - - - See `help mail-system' for a description of the programming interface to the mail system. In particular, see `help $mail_recipient' for information on creating new mail collections. PRECEDENCE ========== The table below gives the relative precedence of all of the MOO operators; operators on higher lines in the table have higher precedence and those on the same line have identical precedence: ! - (without a left operand) * / % +- == != < <= > >= in && || ... ? ... | ... (the conditional expression) = Thus, the horrendous expression x = a < b && c > d + e * f ? w in y | - q - r would be grouped as follows: x = (((a < b) && (c > (d + (e * f)))) ? (w in y) | ((- q) - r)) PREPOSITIONS ============ The complete list of prepositions recognized by the command-line parser: with/using at/to in front of in/inside/into on top of/on/onto/upon out of/from inside/from over through under/underneath/beneath behind beside for/about is as off/off of @PROG-OPTIONS ============= Syntax: @prog-option @prog-option <option> Synonyms: @progoption, @programmer-option @programmeroption The first form displays all of your programmer options The second displays just that one option, which may be one of the flags listed below. The programmer options control various annoying details of your programming commands (e.g., @list, eval, @copy, ...) The remaining forms of this command are for setting your programmer options: @prog-option +<flag> @prog-option -<flag> @prog-option !<flag> (equivalent to -<flag>) These respectively set and reset the specified flag -list_all_parens @list shows only necessary parentheses by default +list_all_parens @list shows all parentheses by default -list_no_numbers @list gives line numbers by default +list_no_numbers @list does not give line numbers by default -eval_time eval does not show ticks/seconds consumed. +eval_time eval shows ticks/seconds consumed. -copy_expert @copy prints warning message. +copy_expert @copy prints no warning message. All flags default to the `-' settings. Finally, we have @prog-option verb_args [is] <dobj> <prep> <iobj> @prog-option verb_args="<dobj> <prep> <iobj>" @prog-option -verb_args (equivalent to verb_args="none none none") @prog-option +verb_args (equivalent to verb_args="this none this") which all serve to specify the (direct/indirect)-object and preposition to use in a @verb command for which these are not given at all. @PROGRAM ======== Syntax: @program <object>:<verb-name> @program <object>:<verb-name> <dobj> <preposition> <iobj> Changes the MOO program associated with the named verb on the named object. If you provide <dobj> <preposition> and <iobj> as in the second form of this command, then it is the first verb with matching direct object, preposition and indirect object specifiers that is the one getting the new program. This is useful if you have several verbs matching the same name. Typing the @program command always puts the server into a line-reading mode, in which each line you type is saved away without any action unless said line is one of the following: . @abort .<text> A period on a line by itself ends the line-reading mode and continues with the command, in this case, the saved lines are considered as a program, checked for syntax errors and, if no errors are found, installed as the new program for the specified verb. @abort causes the command to terminate immediately with no change to any verb's program. .<text> enters <text> literally as one of the lines to be saved, which is used for when, e.g., you want to enter the line `.' or the line `@abort'. Note that this command *always* enters the line-reading mode, even if the indicated verb is not found. In this case, lines of text are still read but they are ignored. After any @program command, you always need to type a period or `@abort' to get back into the normal command-reading mode. PROGRAM ======== Syntax: .program <object>:<verb-name> : : <lines of MOO code> : : . Provides or changes the MOO program associated with the named verb on the named object. This command is mostly obsolete. Use @program instead. The only reason this command still exists is that it is a server builtin command that will continue to work in the (unlikely) event that @program gets trashed ... This command works differently from most other MOO commands, in that it actually changes how the server will interpret later lines that you type to it. After typing the '.program' line, you are in 'programming mode'. All lines that you type in this mode are simply saved away in the server until you type a line containing only a single period ('.'). At that point, those lines are interpreted as a MOO program and are checked for syntax errors. If none are found, a message to that effect is printed and the code you typed is installed as the program for the verb in question. In any case, after typing the '.' line, you are returned to the normal input-handling mode. PROGRAMMING/PROGRAMAR ===================== MOO contains a rich programming language for the creation of interesting rooms, exits, and other objects. Help is available on the following topics concerning programming in MOO: language -- a brief reference for the syntax and semantics of the MOO language tasks -- a brief description of MOO tasks and their resource limits @property -- adding a property to an object @rmproperty -- removing a property from an object @verb -- adding a verb to an object @rmverb -- removing a verb from an object @args -- changing the syntax of a verb @copy -- copying a verb from one object to another program/@program -- entering the program for a verb @list -- printing a listing of the program for a verb @edit -- editing verb code @show -- looking at all the details of an object, a property, or a verb @parents -- listing the ancestors of an object @kids -- listing the children of an object @contents -- listing the contents of an object @chmod -- changing the permissions on an object, a property, or a verb @chparent -- changing the parent of an object @rename -- changing the name of a verb or object eval -- executing MOO statements and expressions without writing a verb @PROPERTY ========= Syntax: @property <object>.<prop-name> @property <object>.<prop-name> <initial-value> Adds a new property named <prop-name> to the named object. The initial value is given by the second argument, if present; it defaults to 0. Normally, a property is created with permissions 'rc' and owned by whoever types the command. However, you may also specify these explicitly @property <object>.<prop-name> <initial-value> <permissions> @property <object>.<prop-name> <initial-value> <permissions> <owner> Only wizards can create properties with owners other than themselves. '@property' can be abbreviated as '@prop'. @PROSPECTUS =========== Usage: @prospectus player [from number] [to number] Like @audit, but displays more information. The optional from and to arguments are for restricting the display to specific object numbers, if you happen to know the player only owns objects in the included range. Example: Objects owned by Frand (from #0 to #54949): P[ 23] #47 Frand [Hyperspace Hovel] T #152 Frand's trio of shoes [Frand] KfT[ 10] #391 Frand's notifier class [Nowhere] T[ 8] #393 Frand's chessboard [The Dining Room] KfT[ 11] #775 Frand's generic game board [Nowhere] T[ 6] #893 Ghost game [The Dining Room] T[ 16] #894 Frand's mind bender [The Dining Room] C #997 polka-dot hole [Hyperspace Hovel] R[ 1] #1002 Hyperspace Hovel E #11958 out Monster Cage->*Dr. Empirico's Lab ... The K in the first column indicates that the object has children owned by other players. A lowercase k indicates the object has children but owned only by the player. The second column indicates whether the object is publicly readable or publicly parentable. An r indicates readability. A lowercase f indicates the object is both readable and allows children (is fertile). An uppercase F indicates the object is not readable, yet allows children to be created. (This is usually an error.) If the object is readable by the issuer of the @prospectus command (that is, publicly readable or owned by the issuer), then the number in brackets indicates the number of verbs which have been defined on this object (not including any verbs from any parents). The third column indicates what type of object this is. T Thing E Exit R Room C Container N Note P Player p Parent object appropriate for players ("Player class") blank Other REGULAR-EXPRESSIONS =================== Regular expression matching allows you to test whether a string fits into a specific syntactic shape. You can also search a string for a substring that fits a pattern. See also the built-in function match()/rmatch(). A regular expression describes a set of strings. The simplest case is one that describes a particular string; for example, the string `foo' when regarded as a regular expression matches `foo' and nothing else. Nontrivial regular expressions use certain special constructs so that they can match more than one string. For example, the regular expression `foo%|bar' matches either the string `foo' or the string `bar'; the regular expression `c[ad]*r' matches any of the strings `cr', `car', `cdr', `caar', `cadddar' and all other such strings with any number of `a''s and `d''s. Regular expressions have a syntax in which a few characters are special constructs and the rest are "ordinary". An ordinary character is a simple regular expression that matches that character and nothing else. The special characters are `$', `^', `.', `*', `+', `?', `[', `]' and `%'. Any other character appearing in a regular expression is ordinary, unless a `%' precedes it. For example, `f' is not a special character, so it is ordinary, and therefore `f' is a regular expression that matches the string `f' and no other string. (It does *not*, for example, match the string `ff'.) Likewise, `o' is a regular expression that matches only `o'. Any two regular expressions A and B can be concatenated. The result is a regular expression which matches a string if A matches some amount of the beginning of that string and B matches the rest of the string. As a simple example, we can concatenate the regular expressions `f' and `o' to get the regular expression `fo', which matches only the string `fo'. Still trivial. The following are the characters and character sequences that have special meaning within regular expressions. Any character not mentioned here is not special; it stands for exactly itself for the purposes of searching and matching. `.' is a special character that matches any single character. Using concatenation, we can make regular expressions like `a.b', which matches any three-character string that begins with `a' and ends with `b'. `*' is not a construct by itself; it is a suffix that means that the preceding regular expression is to be repeated as many times as possible. In `fo*', the `*' applies to the `o', so `fo*' matches `f' followed by any number of `o''s. The case of zero `o''s is allowed: `fo*' does match `f'. `*' always applies to the *smallest* possible preceding expression. Thus, `fo*' has a repeating `o', not a repeating `fo'. The matcher processes a `*' construct by matching, immediately, as many repetitions as can be found. Then it continues with the rest of the pattern. If that fails, it backtracks, discarding some of the matches of the `*''d construct in case that makes it possible to match the rest of the pattern. For example, matching `c[ad]*ar' against the string `caddaar', the `[ad]*' first matches `addaa', but this does not allow the next `a' in the pattern to match. So the last of the matches of `[ad]' is undone and the following `a' is tried again. Now it succeeds. `+' is like `*' except that at least one match for the preceding pattern is required for `+'. Thus, `c[ad]+r' does not match `cr' but does match anything else that `c[ad]*r' would match. `?' is like `*' except that it allows either zero or one match for the preceding pattern. Thus, `c[ad]?r' matches `cr' or `car' or `cdr', and nothing else. `[ ... ]' `[' begins a "character set", which is terminated by a `]'. In the simplest case, the characters between the two brackets form the set. Thus, `[ad]' matches either `a' or `d', and `[ad]*' matches any string of `a''s and `d''s (including the empty string), from which it follows that `c[ad]*r' matches `car', etc. Character ranges can also be included in a character set, by writing two characters with a `-' between them. Thus, `[a-z]' matches any lower-case letter. Ranges may be intermixed freely with individual characters, as in `[a-z$%.]', which matches any lower case letter or `$', `%' or period. Note that the usual special characters are not special any more inside a character set. A completely different set of special characters exists inside character sets: `]', `-' and `^'. To include a `]' in a character set, you must make it the first character. For example, `[]a]' matches `]' or `a'. To include a `-', you must use it in a context where it cannot possibly indicate a range: that is, as the first character, or immediately after a range. `[^ ... ]' `[^' begins a "complement character set", which matches any character except the ones specified. Thus, `[^a-z0-9A-Z]' matches all characters *except* letters and digits. `^' is not special in a character set unless it is the first character. The character following the `^' is treated as if it were first (it may be a `-' or a `]'). `^' is a special character that matches the empty string -- but only if at the beginning of the string being matched. Otherwise it fails to match anything. Thus, `^foo' matches a `foo' which occurs at the beginning of the string. `$' is similar to `^' but matches only at the *end* of the string. Thus, `xx*$' matches a string of one or more `x''s at the end of the string. `%' has two functions: it quotes the above special characters (including `%'), and it introduces additional special constructs. Because `%' quotes special characters, `%$' is a regular expression that matches only `$', and `%[' is a regular expression that matches only `[', and so on. For the most part, `%' followed by any character matches only that character. However, there are several exceptions: characters that, when preceded by `%', are special constructs. Such characters are always ordinary when encountered on their own. No new special characters will ever be defined. All extensions to the regular expression syntax are made by defining new two-character constructs that begin with `%'. `%|' specifies an alternative. Two regular expressions A and B with `%|' in between form an expression that matches anything that either A or B will match. Thus, `foo%|bar' matches either `foo' or `bar' but no other string. `%|' applies to the largest possible surrounding expressions. Only a surrounding `%( ... %)' grouping can limit the grouping power of `%|'. Full backtracking capability exists for when multiple `%|''s are used. `%( ... %)' is a grouping construct that serves three purposes: 1. To enclose a set of `%|' alternatives for other operations. Thus, `%(foo%|bar%)x' matches either `foox' or `barx'. 2. To enclose a complicated expression for a following `*', `+', or `?' to operate on. Thus, `ba%(na%)*' matches `bananana', etc., with any number of `na''s, including none. 3. To mark a matched substring for future reference. This last application is not a consequence of the idea of a parenthetical grouping; it is a separate feature that happens to be assigned as a second meaning to the same `%( ... %)' construct because there is no conflict in practice between the two meanings. Here is an explanation of this feature: `%DIGIT' After the end of a `%( ... %)' construct, the matcher remembers the beginning and end of the text matched by that construct. Then, later on in the regular expression, you can use `%' followed by DIGIT to mean "match the same text matched by the DIGIT'th `%( ... %)' construct in the pattern." The `%( ... %)' constructs are numbered in the order that their `%(''s appear in the pattern. The strings matching the first nine `%( ... %)' constructs appearing in a regular expression are assigned numbers 1 through 9 in order of their beginnings. `%1' through `%9' may be used to refer to the text matched by the corresponding `%( ... %)' construct. For example, `%(.*%)%1' matches any string that is composed of two identical halves. The `%(.*%)' matches the first half, which may be anything, but the `%1' that follows must match the same exact text. `%b' matches the empty string, but only if it is at the beginning or end of a word. Thus, `%bfoo%b' matches any occurrence of `foo' as a separate word. `%bball%(s%|%)%b' matches `ball' or `balls' as a separate word. For the purposes of this construct and the five that follow, a word is defined to be a sequence of letters and/or digits. `%B' matches the empty string, provided it is *not* at the beginning or end of a word. `%<' matches the empty string, but only if it is at the beginning of a word. `%>' matches the empty string, but only if it is at the end of a word. `%w' matches any word-constituent character (i.e., any letter or digit). `%W' matches any character that is not a word constituent. @RMPROPERTY =========== Syntax: @rmproperty <object>.<prop-name> Removes the named property from the named object. '@rmproperty' may be abbreviated as '@rmprop'. @RMVERB ======= Syntax: @rmverb <object>:<verb-name> @rmverb <object>:<verb-name> <dobj> <prep> <iobj> @rmverb# <object>:<verb-number> Removes the named verb from the named object. If there is more than one verb matching the given verb-name, this removes the most recently defined one. With the 2nd form of the command the verb removed is the most recent one matching both the given verb-name *and* the given dobj/prep/iobj specifiers. To remove the ambiguity in verbs with the same name, @rmverb# is provided where you can specify the verb by its 1-based index in the verbs() list output. Use of this form is strongly encouraged. SCATTERING ========== It is often the case in MOO programming that you will want to access the elements of a list individually, with each element stored in a separate variables. This desire arises, for example, at the beginning of almost every MOO verb, since the arguments to all verbs are delivered all bunched together in a single list. In such circumstances, you could write statements like these: first = args[1]; second = args[2]; if (length(args) > 2) third = args[3]; else third = 0; endif This approach gets pretty tedious, both to read and to write, and it's prone to errors if you mistype one of the indices. Also, you often want to check whether or not any extra list elements were present, adding to the tedium. MOO provides a special kind of assignment expression, called `scattering assignment' made just for cases such as these. A scattering assignment expression looks like this: {<target>, ...} = <expr> where each <target> describes a place to store elements of the list that results from evaluating <expr>. A <target> has one of the following forms: `variable' This is the simplest target, just a simple variable; the list element in the corresponding position is assigned to the variable. This is called a `required' target, since the assignment is required to put one of the list elements into the variable. `?variable' This is called an `optional' target, since it doesn't always get assigned an element. If there are any list elements left over after all of the required targets have been accounted for (along with all of the other optionals to the left of this one), then this variable is treated like a required one and the list element in the corresponding position is assigned to the variable. If there aren't enough elements to assign one to this target, then no assignment is made to this variable, leaving it with whatever its previous value was. `?variable' = `default-expr' This is also an optional target, but if there aren't enough list elements available to assign one to this target, the result of evaluating `default-expr' is assigned to it instead. Thus, `default-expr' provides a default value for the variable. The default value expressions are evaluated and assigned working from left to right -after- all of the other assignments have been performed. `@variable' By analogy with the @ syntax in list construction, this variable is assigned a list of all of the `leftover' list elements in this part of the list after all of the other targets have been filled in. It is assigned the empty list if there aren't any elements left over. This is called a `rest' target, since it gets the rest of the elements. There may be at most one rest target in each scattering assignment expression. If there aren't enough list elements to fill all of the required targets, or if there are more than enough to fill all of the required and optional targets but there isn't a rest target to take the leftover ones, then E_ARGS is raised. Here are some examples of how this works. Assume first that the verb me:foo() contains the following code: b = c = e = 17; {a, ?b, ?c = 8, @d, ?e = 9, f} = args; return {a, b, c, d, e, f}; Then the following calls return the given values: me:foo(1) error--> E_ARGS me:foo(1, 2) => {1, 17, 8, {}, 9, 2} me:foo(1, 2, 3) => {1, 2, 8, {}, 9, 3} me:foo(1, 2, 3, 4) => {1, 2, 3, {}, 9, 4} me:foo(1, 2, 3, 4, 5) => {1, 2, 3, {}, 4, 5} me:foo(1, 2, 3, 4, 5, 6) => {1, 2, 3, {4}, 5, 6} me:foo(1, 2, 3, 4, 5, 6, 7) => {1, 2, 3, {4, 5}, 6, 7} me:foo(1, 2, 3, 4, 5, 6, 7, 8) => {1, 2, 3, {4, 5, 6}, 7, 8} Using scattering assignment, the example at the begining of this section could be rewritten more simply, reliably, and readably: {first, second, ?third = 0} = args; It is good MOO programming style to use a scattering assignment at the top of nearly every verb, since it shows so clearly just what kinds of arguments the verb expects. @SETENV ======= Syntax: @setenv <environment string> Defines the environment for eval (property player.eval_env). See "help eval" for more information. This is mostly useful when one's .eval_env is broken and prevents one from using eval to reset it. @SHOW ===== Syntax: @show <object> @show <object>.<prop-name> @show <object>:<verb-name> Displays quite detailed information about an object, property or verb, including its name, owner, permission bits, etc. The information displayed for an object can be quite long. See also @display, which displays different information and is controlled differently. STATEMENTS ========== The following kinds of statements exist in the MOO programming language: ; The null statement does nothing. expression ; The expression statement evaluates the expression and then discards the value. IF ( expression ) statements ENDIF IF ( expression ) statements ELSE statements ENDIF IF ( expression ) statements ELSEIF ( expression ) statements ... ELSE statements ENDIF The conditional statement evaluates each expression in turn and executes the statements associated with the first one to return a true value; the ELSE statements are executed if none of the expressions returns a true value. There can be any number of ELSEIF clauses and the ELSE part is optional. See 'help truth' for the definition of 'true value'. FOR name IN ( expression ) statements ENDFOR The list iteration statement first evaluates the expression, which must return a list. It then executes the statements once for each element of that list, each time with the named variable having the value of the corresponding list element. FOR name IN [ expression .. expression ] statements ENDFOR The numeric iteration statement first evaluates the two expressions, both of which must return numbers; call those numbers N1 and N2, respectively. The statements are then executed once for each integer I such that N1 <= I <= N2, in increasing order; each time, the named variable has the corresponding value of I. WHILE ( expression ) statements ENDWHILE WHILE name ( expression ) statements ENDWHILE The indefinite iteration statement repeatedly evaluates the expression and, each time it returns a true value, executes the statements. The loop stops the first time that the expression returns a false value. The definitions of 'true' and 'false' values is in 'help truth'. BREAK ; BREAK name ; Each `break' statement indicates a specific surrounding loop; if <name> is not given, the statement refers to the innermost one. If it is given, <name> must be the name appearing right after the `for' or `while' keyword of the desired enclosing loop. When the `break' statement is executed, the indicated loop is immediately terminated and executing continues just as if the loop had completed its iterations normally. CONTINUE ; CONTINUE name ; Allows you to terminate just the current iteration of a loop, making it immediately go on to the next one if any. RETURN ; RETURN expression ; The return statement evalautes the expression, if any, and returns the resulting value (or 0 if there is no expression) to the verb that called the current one. Execution of the current verb is immediately terminated. TRY statements-0 ; EXCEPT variable-1 (codes-1) statements-1 ; EXCEPT variable-2 (codes-2) statements-2 ; ... (up to 255) ENDTRY Each of the `statements-x' may be any number or combination of MOO statements and function calls. Each of the `codes-x' may be either the keyword `ANY' or else a comma-separated list of expressions that yield error codes. If the execution of `statements-0' raises an error listed in the `codes-x', then the statements associated in that EXCEPT clause where the code was listed are executed. When this occurs, `variable-x' is assigned this information about the error being raised: {<error code>, <error message>, <value>, <traceback>}. If the error raised is not listed in any EXCEPT clause (which means the `ANY' keyword was not used), then the error continues to be raised. TRY statements-0 ; FINALLY statements-last ; ENDTRY In this construct, `statements-0' are executed. Then, whether an error was raised by their execution or not, `statements-last' are executed. If `statements-0' transfers control somewhere else, that transfer is interrupted so that `statements-last' can be run. If `statements-last' transfers control, then that overrides the first transfer. (Transfers include raising an error, returning from this verb, terminating the current iteration of a surrounding loop). `Statements-last' will always be executed, providing a good place for necessary cleanup code that will run even if `statements-0' doesn't simply run normally to completion. FORK ( expression ) statements ENDFORK FORK name ( expression ) statements ENDFORK The fork statement first executes the expression, which must return a number; call that number N. It then creates a new MOO task that will, after at least N seconds, execute the statements. When the new task begins, all variables will have the values they had at the time the FORK statement was executed. The task executing the FORK statement immediately continues execution. If a variable name is given after the FORK keyword, then it is assigned the 'queue ID' of the newly-created task. The value of this variable is visible both to the task executing the fork statement and to the statements in the newly-created task. See 'help tasks' for more information about forked tasks. TASKS ===== A task is an execution of a MOO program. There are five ways for tasks to be created in LambdaMOO: + Every time a player types a command, a task is created to execute that command; we call these 'command tasks'. + Whenever a player connects or disconnects from the MOO, the server starts a task to do whatever processing is necessary, such as printing out 'Munchkin has connected' to all of the players in the same room; these are called 'server tasks'. + The FORK statement in the programming language creates a task whose execution is delayed for at least some given number of seconds; these are 'forked tasks'. + The suspend() function suspends the execution of the current task. A snapshot is taken of whole state of the execution, and the execution will be resumed later. These are called `suspended tasks'. + The read() function also suspends the execution of the current task, in this case waiting for the player to type a line of input. When the line is received, the task resumes with the read() function returning the input line as result. These are called `reading tasks'. The last three kinds of tasks above are collectively known as `queued tasks' or `waiting tasks', since they may not run immediately. To prevent a maliciously- or incorrectly-written MOO program from running forever and monopolizing the server, limits are placed on the running time of every task. One limit is that no task is allowed to run longer than 15 seconds; this limit is, in practice, never reached. The reason is that there is a second limit on the number of operations a task may execute. The server counts down 'ticks' as any task executes. Roughly speaking, it counts one tick for every expression evaluation (other than variables and literals), one for every `if', `fork' or `return' statement, and one for every iteration of a loop. If the count gets all the way down to zero, the task is immediately and unceremoniously aborted. All tasks begin or resume with an store of 30,000 ticks; this is enough for almost all normal uses. Because queued tasks may exist for long periods of time before they begin execution, there are commands to list the ones that you own and to kill them before they execute. These commands are covered in the following help topics: @forked -- listing the forked tasks that you own @kill -- killing a particular forked task TRUTH ===== Several kinds of statements, expressions, and functions in the MOO programming language use a notion that some MOO values are 'true' and others 'false'. The only values that are considered true are non-zero numbers, non-empty strings, and non-empty lists. All other values (i.e., 0, "", {}, objects, and errors) are considered false. UTILITIES ========= The core database has a number of objects serving as libraries of useful verbs. More detailed information can be obtained for (some of) these, via `help $whatever_utils' $building_utils -- $code_utils -- parsing and manipulating verb code $command_utils -- reporting matching errors to the player $gender_utils -- managing gendered objects $list_utils -- list manipulation $set_utils -- set manipulation $lock_utils -- key expression manipulation $match_utils -- $object_utils -- object information (inheritance/location hierarchy, verb/property lists) $perm_utils -- permissions $string_utils -- string manipulation $time_utils -- time (numeric and verbal) manipulation $trig_utils -- trigonometric and other numerical utilities $language_utils -- @VERB ===== Syntax: @verb <object>:<verb-name(s)> @verb <object>:<verb-name(s)> <dobj> [<prep> [<iobj>]] Adds a new verb with the given name(s) to the named object. If there are multiple names, they should be separated by spaces and all enclosed in quotes: @verb foo:"bar baz mum*ble" The direct and indirect object specifiers (<dobj> and <iobj>) must be either 'none', 'this', or 'any'; their meaning is discussed in the LambdaMOO Programmer's Manual. The preposition specifier (<prep>) must be either 'none', 'any', or one of the prepositional phrases listed in `help prepositions' (a prepositional phrase with more than one word must be enclosed in quotes ("")). All three specifiers default to 'none'. It is also possible to specify the new verb's permissions and owner as part of the same command (rather than having to issue separate @chmod/@chown commands) @verb <object>:<verb-name(s)> <dobj> <prep> <iobj> <permissions> @verb <object>:<verb-name(s)> <dobj> <prep> <iobj> <permissions> <owner> <permissions> are as with @chmod, i.e., must be some subset of "rwxd". They default to "rd" (specifying "w" for a verb is highly inadvisable). The owner defaults to the player typing the command; only wizards can create verbs with owners other than themselves. You may also use "tnt" in place of "this none this" for the dobj prep iobj arguments. "this none this" is used to indicate non-command verbs, since the parser can't possibly interpret a command as "this none this". For these verbs, the permissions default to "rxd"; the "x" bit is set so that they can be called from other programs. (If they couldn't be used as commands, and they couldn't be called from programs, they wouldn't be good for anything!)