Programmer Help

#

Syntax: #<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).

&-pointers

Programmer Notes
---------- -----

The &-pointer system was implemented primarily to separate the core-object extraction system from the server-supported $-pointer system. Since the latter is directly supported by the server, its major function is to establish literals that may be used MOO lanaguage programming.

However, there may be times when it is useful to refer to an object by &-pointer within MOO language code, even though the server doesn't support that directly. In these cases, programmers may use the construct "$id.<pointer_name>" as a reference. For instance, the object &improved_room may be referenced as "$id.improved_room" in code.

The basic reasons why the &-pointer system was created were to:
  1. dissociate the server-supported $-pointer system, from the in-DB core extraction system
  2. cut down on properties added to #0, for efficiency reasons
  3. share the &-pointer convention used at other MOOs to mean "the local version of an object named <pointer>"

Also see: &-pointers in General Help

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

;

See: eval

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

Also see: @add-feature in General Help

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

@chatmode

Programmers note:
Verbs with perms that control a person's MOO character can call their
@chatmode verb to invoke it. When invoked as an executable verb, the
value of arg[1] has meaning as follows:
  0 = warnings and user can escape (default)
  1 = warnings and user can NOT escape
  2 = no warnings and user can escape
  3 = no warnings and user can NOT escape
Note that the only way a user can escape from chat mode when invoked
with option 1 or 3 is to disconnect and reconnect.

Also see: @chatmode in General Help

@check-chparent

Syntax: @check-property <object>.<propname>
@check-chparent <object> to <newparent>

You cannot add a new property to an object if an ancestor or a descendant already defines a property with the same name. @check-property will give you the list of all descendants of <object> that that define .<propname>.

Likewise you cannot chparent an object to a new parent if the new parent has a property that is also defined on the object or some descendant. Use @check-chparent to find out all instances of conflicting properties that would interfere with @chparent in this manner.

Note that @check-property requires either that you own the object or that it be writeable, the same conditions that need to hold if you are to create new properties on the object. Similarly, @check-chparent requires that you own the object and that the new parent is either fertile or likewise owned by you.

For objects with large numbers of descendants, these commands can be time-consuming.

@check-property

See: @check-chparent

@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
  => ""

@compare

Syntax: @compare <objectA>:<verbA> to <objectB>:<verbB>
@compare <objectA>:<verbA> to <objectB>
@compare <objectA>:<verbA> to

This command compares two verbs, and gives a list of instructions for changing the first verb to be identical to the second. If no second verb is specified (the second usage), then a verb of the same name as the first is assumed.

If you omit the object to compare to, you'll be prompted to enter the lines of code you want compared to <objectA>:<verbA>.

The time stamp line (a last line beginning with "Last modified") is ignored.

Related Topics:
@list -- list a verb

@copy

Syntax: @copy <object>:<verb> to [<newobject>][:<newverb>]
@copy <object>.<prop> to [<newobject>][.<newprop>]

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
  @copy me.test_prop to .newtest_prop

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.

Similarly, you can use this command to copy properties, hopefully followed by deleting the original.

@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

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.

@displayoptions

See: @display-options

@document

Syntax: @document <object>:<verb>

This is a quick-and-dirty command to add documentation lines to a verb (these lines are displayed when someone asks for help on the verb). It will prompt you for the lines to add as documentation. If the verb already has documentation, it will query before overwriting it.

This command is only available to programmers.

@drawing

A note to Programmers:
If you have hacked a specialized :look_self() that does not pass() to
the parent verb you need to add the following lines wherever you
want the drawing to appear (for instance):
    if (player:drawings_ok())
      player:tell_lines(this.drawing);
    else
      player:tell_lines(this.nodrawing_txt);
    endif

Also see: @drawing in General Help

@dump

Syntax: @dump <object> [with [id=#<id>] [noprops] [noverbs] [create] [recreate] [port]]

This spills out all the properties and verbs on an object, calling suspend at appropriate intervals.
   id=#<id> - specifies an idnumber to use in place of the object's actual id (for porting to another MOO)
   noprops - don't show properties.
   noverbs - don't show verbs.
   create - indicates that a @create command should be generated and all of the verbs be introduced with @verb rather than @args; the default assumption is that the object already exists and you're just doing this to have a look at it.

@edit

Additional Usage for Programmers

Syntax: @edit <object>:<verb-name> [<dobj> [<prep> [<iobj>]]]

  This format moves you into the verb editor.

Related Topics:
$generic_editor -- the base upon which MOO editors are built

Also see: @edit in General Help

@egrep

See: @grep

@eval-env

Syntax: @eval-env

Displays your eval environment. The Eval environment is a string of MOO program code which is executed before any of the code in your eval is executed, and by default is set to the string "me=player;here=player.location", to set the variable "me" to the value of the user's object number, and the variable "here" to the object number of the location. You can add other variable definitions to it, using the commands below.

Syntax: @eval-env <name> is <object or MOO code>
@eval-env-string <name> is <MOO code>
@rmeval-env <name>

Adds or removes codes to your programmer's eval environment. <Name> is any string which can be a valid MOO program variable, and <object or MOO code> can be either an object or a string which is a valid expression for a MOO code assignment expression. If @eval-env is used, and if <object or MOO code> is recognized as an object or player name, the variable <name> is assigned that object number. If it isn't recognized as an object, the user is asked if it is all right to add it as a string. If @eval-env-string is used, it is always added as a string of MOO code. @eval-env or @eval-env-string adds or changes the assignment for variable <name>, and @rmeval-eval deletes it.

For example, '@eval-env su is $string_utils' gives the variable "su" the value of the object number of $string_utils, so you can use "su" in your evals, instead of $string_utils.

The eval environment code is executed every time you do an eval, regardless of whether the variable is actually needed. Therefore, it is inefficient to have superfluous code in your eval_env, though in practice the overhead is trivial. The number of ticks this takes is the "eval overhead", which is also displayed by the @eval-env output. This is subtracted from the actual number of ticks when the total number of ticks of an eval is output (if you set eval_time to true).

Related help topics:
eval -- about the eval command in general and its options
@setenv -- about an alternate method to set the eval environment

@eval-env-string

See: @eval-env

@examine

Note for programmers:
  The 'obvious' verbs are those that are readable and that can be
invoked as commands. To keep a verb off this list, either make it
unreadable (see 'help @chmod') or, if it shouldn't be used as a
command, give it 'args' of 'this none this' (see 'help @args').

Also see: @examine in General Help

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

Related Topics:
@tasks -- a less spammy version essential when the @forked list is huge
@kill -- kill a particular forked task
@killtasks -- a quick task killer for a specified person or object:verb
forked-interpretation -- a primer on understanding @forked list management

@gethelp

Syntax: @gethelp [<topic>] [from <db or dblist>]

Prints the raw text of <topic> from the appropriate help db. With no
argument, gets the blank ("") topic from wherever it lives. Text is
printed as a script for changing this help topic or porting it to a
new MOO (somewhat like @dump...).

@grep

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

Related Topics:
@killgrep -- kill a running @grep or @egrep search

@kill

Syntax: @kill task_id
@kill [object]:[verb]
@kill soon [number-of-seconds]
@kill all [who]
@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 all <who> kills all the tasks owned by <who>.

@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

@killgrep

Syntax: @killgrep

Synonym: @ungrep

Used to kill a running @grep or @egrep search. It will prompt you with info about each @grep running and ask if you want to kill that one.

Related Topics:
@grep -- search for a text string in verbs
@egrep -- search for a regular expression in verbs

@lastedit

See: @lastmodified

@lastmodified

Syntax: @lastmodified <object name or number>
@lastedit <object name or number> [obsolete name]

Will take a look at an object you own and display the date and time of
its last modification. If there are verbs defined on the object and they
are tagged with a Last modified line, that information will be given.

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

@prog-options

Syntax: @prog-option .. to show all options
@prog-option <option> .. to show a selected option
@prog-option +<option> .. to select an option
@prog-option -<option> .. to un-select an option
@prog-option !<option> .. (same as above)

The programmer options customize how various programmer verbs and utilities
work. The default in each case is for the option to be un-selected.

Currently implemented options are as follows:

-grep-full Verb @grep's show the first occurrance of the search
                  pattern (default)
+grep-full Verb @grep's show all occurrances of the search pattern.

-duplicate-verbs @verb will not allow you to add a verb with the same name
                  and args as an existing one on the same object (default).
+duplicate-verbs @verbs will allow you to add a verb with the same name and
                  args as an existing one on the same object.

-default-args @verb and @verbprog require that the verb arguments be
                  specified.
+default-args @verb and @verbprog use 'none none none ' If no verb
                  arguments are given.

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

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

@propset

@propset <object>.<property> <value>|<keyword> [perms owner]

Adds a property to an object and sets its value, perms, and owner. If the property already exists, changes the value, perms, or owner, if given.
Note: This always updates the object's .last_modified property. Does not work for additional owners.

<Value> can be string decodable as a legal MOO value. As an alternative, one of the following keywords can be used to get a prompt for input of the property value on subsequent lines.

       'value' ... reads value in single line.
      'string' ... reads string in single line for string property.
       'text' ... read in lines of for list of strings. Terminated by
                         line with only ".".
     'wrap-text' ... read in lines for list of strings in wrap-for-dump
                         format. New lines must start with "'", continuation
                         lines start with "&".
  'multi-line-value' ... reads value on multiple lines. Lines appended to
                         make a single string, which is then evaluated.
         '.' ... same as above.

Updates the object's .last_modified property. Therefore, should only be used for 'significant' property value changes. Use @set to change a property value without modifying the .last_modified property.

This is primarily designed for restoring from backups. Normally @prop is used to create a property and set its initial value, and @set is used to change the value of an existing property.

@prospectus

Syntax: @prospectus <person> [from number] [to number]
@prospectusDB <person> [from <start>] [to <end>]

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 person 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 people. A lowercase k indicates the object has children but owned only by the person. 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 Person
        p Parent object appropriate for characters ("Person class")
        blank Other

The @prospectusDB form presents the same information, but is less efficient since it scans the entire DB for objects the person owns, instead of using their character's .owned_objects property.

@prospectusDB

See: @prospectus

@remove-feature

See: @add-feature

@rename

Additional Varients for Programmers

Syntax: @rename <object>:<verb> to <new-verb-name>
@rename <object>.<prop> to <new-prop-name>

These forms of the @rename command is for use by programmers, to
change the name of a verb or property they own. If the
<new-verb-name> contains spaces, the verb will have multiple names,
one for each space-separated word. Embedding spaces in property
names is not generally recommended.

Also see: @rename in General Help

@residents

Hints for programmers: The verb $room:accept_for_abode is called by
@sethome. By overriding this verb you can give different criteria
to @sethome. It should return 1 for allowed and 0 for denied.

Also see: @resident in Builder Help

@rmeval-env

See: @eval-env

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

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.

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

@tasks

Syntax: @tasks

Displays a summary of the number of tasks running under your perms;
as well as a summary of total running tasks.

Related Topics:
@forked -- listing forked tasks
@kill -- killing a particular forked task

@taskstack

Syntax: @taskstack task_id

This reports the task stack for a suspended task. Note that forked tasks that have not yet run don't have a task stack to report.

Related Topics:
@forked -- list forked and suspended tasks
@tasks -- quick version of @forked
@kill -- kill a forked or suspended task

@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 person 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!)

@verbprog

 @verbprog <object>:<verb-name(s)> <dobj> <prep> <iobj> [<perms> <owner>]
 <verb code>
 .

@verbprog conbines the functions of both @verb and @prog. It creates a new verb if no verb with the same name (or alias of the specified name) and args exists, or over-writes an existing one if such a verb already exists. If different alias names, permissions, or owner are specified, then these are changed. (Note that only wizards can specify verb onwers other than themselves.) Then it takes input of the verb code, like @prog. If the first character of the first line of verb code is a "'", then long lines can be wrapped, with the "'" characer being used to indicate the start of a new none, and a "&" character being used to indicate the start of a continuation of a wrapped line. (The latter feature is useful for restoring from backups.)

The verb arguments must be given unless the player has 'default-args' in his/her .prog_options, in which case the default of 'none none none' are used.

binary-strings

"Binary strings" are special strings that can be used to represent
arbitrary bytes in MOO code, including non-printing characters. The
only non-printing characters usually permitted in MOO strings are
spaces and tabs. Binary strings are generally used for binary input
and output through appropriately set network connections.

In a binary string, any byte that isn't an ASCII printing character
or the space character is represented as the three-character
substring "~XX" where XX is the hexidecimal representation of the
byte. The input character "~" is represented by the three-character
substring "~7E" in this notation.

This special notation is used by the functions encode_binary() and
decode_binary() and by the functions notify() and read() with network
connections that are in binary mode.

Related Topics:
set_connection_option() - setting a network connection as binary
encode_binary() -- converts a list of values to binary string format
decode_binary() -- returns a list of values represented by a binary
                   string

documentation

  It is critical that programmers document their work. Even if noone else will ever use your code, YOU will probably want to look back at it some time in the future and having to spend time figuring out your own code is a waste.
  There are four important ways to document your code, and all four should be used.

SELF-DOCUMENTING CODE
  This refers to using variable and verb names that are highly descriptive. Well-written self-documenting code should make sense when read out loud as a set of instructions. Avoid using single letter variables. Avoid abbreviating variables down to the point their function is no longer obvious. Lastly, make sure your verb names describe their function well. There's no shame in naming a verb "strip_off_spaces" instead of just "strip" and it will make your code far simpler to understand.
  Making code "read well" includes chosing verb names that make sense when read as a series of instructions. Sometimes that means they should describe the process (eg. "this:open_window") but other times they should be named after the result of the process (eg. "this:window_opened") depending on which makes more sense in the context used. If in doubt, read your code out load and use the version that makes more sense, also considering it may be called elsewhere in different contexts.
  One useful method for documenting code involving tables is to use a name as an index instead of a number. For instance, if each element in the list is a list, and the first item of each element is the user name, try something like this:
  user_name=1;
  for record in (this.user_info)
    if (record[user_name]=="noone")
      ...
The text "record[user_name]" is much more understandable than "record[1]" which would require looking up a key to the index meanings somewhere.

HEADER LINES
  These are lines of text at the beginning of the verb. The header is all the string literal lines ("this is a comment line";) until the first line that is not one.
Command line verbs should have header lines in the format:
  "Usage: <command name> <arguments....>";
  "Short description of comand's function.";
while non-command line verb headers (eg. ones with args "this none this") should have the format:
  "verb_name( arg1 {type1, type2...}[, arg2 {type1,...}, ...]) -> result {type1, ...}";
  "Short explanation of verb's function";
where the components are as follows:
  verb_name - If the verb is corified, precede it with $ to indicate that.
  arg1 - Use the same name here as you will be assigning arg1 to (make it DESCRIPTIVE!).
  {type1, type2,...} - This is the list of acceptable variable types for this argument. If there is only one type, the curly braces may be omitted.
  [, arg2 ...] - These are additional optional arguments.
  Note that arg1, arg2, result etc. should subsequently appear within the verb, and that type1, etc., should be selected from the available variable types (NUM, STR, ...), or BOOL (meaning an undefined type, to be used only in true/false testing). Don't use "arg1" or "result" as variable names; substitute in some descriptive name.
  An example: "sample_verb(who OBJ, display {LIST, STR}) -> reply STR";
  This header syntax does not completely specify the acceptable arguments if any are of type LIST, since it doesn't specify what type the elements of that LIST must be. This will be implemented in future refinements of the header documentation system.

INTERNAL COMMENTS
  Use internal comment lines to 1. identify separate functional units of code, 2. make clear an operation that is not made obvious from the self-documenting aspect. Internal comment lines are string literals like header lines, with the format:
    "this is an internal comment line";

USER HELP TEXTS
  There are two places where user help text may be added to objects. An "about_text" property should describe for the owner of child objects how to set up the object, and may also contain information for programmers. A "help_msg" property should describe how the object is used.
  For instance, the "about_text" would include a list and explanation of the message texts that can be set on an object, since this is important for the owner but not for other users. The "help_msg" property would have a list of user commands and what they do, since anyone using the object would need these.

ADVANCED HELP ASPECTS
  If you wish to add context-sensitive help texts, you can add "help_msg" and/or "about_text" verbs to your objects. By default, these simply return the value of the equivalently named properties.
  Another nice addition is to use a "hidden_verbs" verb on your object to make the "examine" command's obvious verbs list context sensitive. See $thing:hidden_verbs for an example.

ADDITIONAL NOTES
    1. Don't use the term "player" in your documentation unless you mean the MOO variable of that name and are writing specifically for programmers.
    2. Don't use the term "verb" unless you are referring to a verb that can't be called as a command, or are writing specifically for programmers. Non-programmers will understand the term "command" much better.
    3. Don't make specific references using the MOO's name if you expect your work to be ported to other MOOs.

domain-system

Programmers may wish to note:

$room:in_domain() and $room:in_domains() (same verbs on $domain)
$room:get_ascii_map() and $domain:get_ascii_map()
$building_utils:trace_domain_via_out()

Also see: domain-system in Builder Help

editors

Notes for Programmers

Syntax:
@edit <object>:<verb> invokes the Verb Editor (edits verb code)

Advanced Features:
A person may have her or his own .edit_options property which is a list containing one or more (string) flags from the following list

  quiet_insert
      suppresses those annoying "Line n added." or "Appended..." messages
      that one gets in response to 'say' or 'emote'. This is useful if you're
      entering a long list of lines, perhaps via some macro on your client,
      and you don't want to see an equally long list of "Line n added..."
      messages. What you do want, however is some indication that this all
      got through, which is why the "." command is an abbreviation for insert.

  eval_subs
      Enables the verb editor to process your eval_subs property when
      compiling your verb. See `help eval' for more information about
      the eval_subs property.

Also see: editors in General Help

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
    E_FLOAT Floating-point arithmetic error

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 character 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 $prog 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!

The $no_one:eval verb is available as a safe way to test possibly dangerous code. It is particularly useful for calling from verbs with wizardly permissions, but finds other uses where security issues are important.

eval-d

See: eval

examine

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

Also see: examine in General Help

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

        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.

        expression + expression
        expression - expression
        expression * expression
        expression / expression
        expression % expression
        - expression
The arithmetic expressions evaluate the subexpressions, all of which must return numbers, and then perform addition, subtraction, multiplication, division, remaindering, or negation, respectively. For addition, the subexpressions may both return strings as well; in this case, the result is the concatenation of the two strings.

        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.

The method for disambiguating the meaning of a complex MOO expression in the absence of sufficient parentheses is described in 'help precedence'.

features

Notes for Programmers

This text describes how to program a feature object, so that you can make new MOO commands available to yourself and others. It assumes you are already familiar with the @create command and with using feature objects.

1. Create a feature object: @create $feature named "my features",features
2. Add the FO to your list of features: @add-feature features
3. Add your command to the FO: @verb features:yawn none none none
4. Program the new verb: @edit features:yawn
5. Set the verb +x so it can be called by the FO system: @chmod features:yawn +x
6. Test your new command: yawn
7. Document the command (described in more detail below).

Once you have created a working FO, anyone can use the commmands on it by adding that feature with the @add-feature command. Note that you do not need to make the FO "fertile." If, in fact, you DON'T want people to be able to add the FO to their list, use `@set features.feature_ok to 0' after you have added it to your own FO list.

There are two ways you can document the commands on your FO. The simplest is to edit the FO's `help_msg' property. When someone uses `help <feature number>' they are presented with that text. In addition, FO's with no `help_msg' set have an automatic system for returning the header lines from each "registered" command. If each of your command verbs has header lines describing its function, this can serve as the FO's documentaion. Use the @add_feature_verb command on the FO to register a verb.

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. The $feature is useful since it has these and also some other convenient verbs and properties.

When a feature is added to a person's features list, feature:feature_add is called, if it exists, with the person in question as its argument. Likewise, when a feature is removed, feature:feature_remove is called.

A useful way for FO's to store information specific to a given character is the $player.feature_info property. Any FO in a user's FO list can store data that way, using <user>:set_feature_info or <user>:get_feature_info to set or get the data, respectively.

Related Topics:
$feature:@add_feature_verb - register an FO verb as a command
$player:set_feature_info - store data to <user>.feature_info
$player:get_feature_info - get data from <user>.feature_info

Related Topics:
$feature -- other notes for programmers

Also see: features in General Help

forked-interpretation

  The @forked command generates a list of all currently forked or
suspended tasks. This text describes how to understand the @forked
list, and also how it can be used by MOO administrators to help
maintain good MOO operations. It is widely believed that having
large numbers of forked or suspended tasks can cause MOO server lag,
which is good motivation to understand what's on the MOO's @forked
list, and keep it minimal.
  The @forked list displays the task-id, scheduled start time, owner,
verb and object, and line in the verb, for each task. If a task was
scheduled for a time in the past but has not yet run, then a time in
the format "... X seconds ago" is displayed instead of the usual
ctime() format. If you see many tasks scheduled that should have
already run, especially if they should have run more than a second or
two ago, the MOO is experiencing server lag. That can be caused by
some other non-MOO process hogging CPU resources, in which case there
is little you can do from within the MOO. However, it can also be
caused by CPU-intensive MOO usage, especially by verbs not programmed
in a polite fashion. Examples are forkbombs (scheduling hundreds of
forked tasks continually), or extensive processing tasks that
suspend(0), instead of for a longer suspend time. The latter can also
use up a lot of CPU time, and cause other scheduled MOO tasks to run
late.
  Note: If a huge number of tasks pile up, they can so overload the
system that the @forked command itself will run out of ticks, or
display so much spam that you can't continue analysis. The best
defense is to use the @tasks command first before @forked if ever you
suspect the MOO is lagging due to forked tasks. In the post-server
1.8.0 age, such immense forked task lists shouldn't happen unless
someone has set .queued_task_limit values foolishly.
  One easily recognizable problem is when a verb is always sitting
near the top of the @forked list (to be run within a second), and
never leaves. Genernally, endlessly running tasks should suspend for
longer than zero seconds to be polite. Any task that sits near the
top of the list and stays should be investigated for appropriate
behavior. If the MOO is lagging, and there is a new task stuck near
the top of the list, that can be a strong indication that the problem
lies there.
  The most valuable method for administrators to insure they can
quickly recognize when some MOO task is using an inappropriate amount
of CPU time, is to become familiar with that's routinely on the
@forked list. If you then know that something is lagging the MOO,
and see a new unrecognized task, that task can be specifically
investigated. MOOs that have so many scheduled tasks that it's not
possible to really track them all should probably be considering
using some sort of scheduler, an object that runs scheduled tasks and
subsumes tasks it has been assigned under a single forked or
suspended task run on the scheduler itself.
  The most useful tools for investigating specific @forked list
tasks, is the @taskstack and @list commands. Typically, you can just
use @list to read the code for the stated verb on the @forked list,
look for the current line in the code (given in parentheses after
the verb name in the @forked list). If the code contains some
obvious problem, like an endlessly repeating loop with a suspend(0)
in it, the task should just be killed (@killtask <task-id>). Other
more subtle problems will be recognized by experienced programmers.
  Sometimes, the verbs listed for a task in the @forked list aren't
the ones causing the problem, since in some cases the earlier verbs
in the task aren't listed. In those cases, using "@taskstack
<task-id" will usually display the full list of reposnsible verbs,
and you can start tracking back in the list to find the source of the
problems.

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(who,string) - sending text to a person's terminal
read() - reading a line of input from the user (*)
output_delimiters(who) - return {prefix,suffix} set by PREFIX/SUFFIX cmds
call_function(x,@args) - call built-in fuction x with args
function_info(x) - description of built-in function x

 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 integer (depricated)
   toint(value) - convert any non-list value into an integer
 tofloat(value) - convert a proper string value into a float
floatstr(n,x) - float n into a string with x precision
toliteral(value) - return a string that evaluated would be equal to value
  toobj(value) - converting any non-list value into an object
 length(value) - return the length of a string or list
value_bytes - the number of bytes to store value in the DB
equals(x,y) - true if x is identical to y; case-matters

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
is_member(element, list) - returns true is element is in list (ignores case)

min(n1, n2, ...) - minimum of n1,n2,...
max(n1, n2, ...) - maximum of n1,n2,...
ceil(n) - the smallest integer not less than X (float)
trunc(n) - trucate a float at the decimal point (float)
floor(n) - the largest integer not greater than X (float)
abs(n) - absolute value of n
sqrt(n) - square root of n (float)
random(n) - random integer between 1 and n inclusive
log(n) - natural log of n (float)
log10(n) - base 10 log of n (float)
exp(n) - e raised to the power of n (float)
acos(n) - arc-cosine of n (float)
asin(n) - arc-sine of n (float)
atan(n) - arc-tangent of n (float)
cos(n) - cosine of n (float)
sin(n) - sine of n (float)
tan(n) - tangent of n (float)
cosh(n) - hyperbolic cosine of n (float)
sinh(n) - hyperbolic sine of n (float)
tanh(n) - hyperbolic tangent of n (float)

 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
string_hash(string) - returns 32-character hex string encoding the string
value_hash(value) - same string as string_hash(toliteral(value))
binary_hash(string) - same as string_hash but expects a binary string
encode_binary(value) - binary string from a list of string and int values
decode_binary(value) - list of string and int values from a binary string

   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
object_bytes(object) - size in bytes of object in database
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 user character
          players() - a list of all user characters, connected or not
connected_players() - a list of all currently-connected people
     idle_seconds(who) - seconds since given person typed anything
connected_seconds(who) - seconds given person has been logged in
    boot_player(who) - disconnect person from the MOO immediately(*)
set_player_flag(who, value) - set/clear player bit; boot person if clear(*)
connection_name(who) - a server-assigned name for character's connection (*)
connection_options(who) - returns the current options settings (*)
connection_option(who,x) - returns the setting for option x (*)
set_connection_option(who,x,value) - sets option x to value (*)
open_network_connection(@args) - open a connection to another network site (*)
buffered_output_length(who) - number of bytes currently buffered for output (*)
listen(x,port) - start listening on port with x as listening object (*)
unlisten(port) - stop listening on port
listeners() - what objects are listening on what ports (*)
flush_input(who) - remove pending input lines from queue (*)
force_input(who,str) - insert str into input stream of who (*)

caller_perms() - the character whose permissions your caller was using
set_task_perms(who) - changing permissions of the running task (*)
callers() - list of {obj, verb, owner, vloc, player}: this task's stack
task_stack(id) - like callers() but for any task id
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}
queue_info([who]) - list of people with queued tasks or number of tasks for who
raise(err) - raise err and end the task (if not caught)
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 (*)
db_disk_size() - the size on disk of the last checkpoint result

(*) => as you might have expected, these usually require wizard permissions.

gopher

$gopher -- programmer's details on the gopher slates

Also see: gopher in Builder Help

help

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 character classes, see `help $help'.

Also see: help in General Help

key-representation

The representation of key expressions is very simple and makes it easy to construct new keys on the fly.

Objects are represented by their object numbers and all other kinds of key expressions are represented by lists. These lists have as their first element a string drawn from the following set:
        "&&" "||" "!" "?"
For the first two of these, the list should be three elements long; the second and third elements are the representations of the key expressions on the left- and right-hand sides of the appropriate operator. In the third case, "!", the list should be two elements long; the second element is again a representation of the operand. Finally, in the "?" case, the list is also two elements long but the second element must be an object number.

As an example, the key expression
        #45 && ?#46 && (#47 || !#48)
would be represented as follows:
        {"&&", {"&&", #45, {"?", #46}}, {"||", #47, {"!", #48}}}

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

local-editing

Programmers notes:

The local editing system uses a set of commands on $player that are nominally available as command line verbs, but are intended only for use by the local editing system. These are:
@set-note-string
@set-note-text
@@sendmail
@set-section-string
@set-section-text

Additional verbs used are:
$generic_editor:invoke
<editor>:local_editing_info
<editor>:invoke_local_editor

Also see: local-editing in General Help

locking

Note to programmers:
The interface between these two sides is the verb
x:is_unlocked_for(y), which is called by x to determine if it is
locked for the object y. The way in which 'is_unlocked_for' is
implemented is entirely independent of the ways in which x uses its
results. Note that you can play on either side of this interface
with your own objects, either defining new implementations of
'is_unlocked_for' that match your particular circumstances or having
your objects interpret their being locked in new ways.

Also see: locking in Builder Help

mail

Programmers topics:

mail-system -- description of the programming interface to the mail
               system
$mail_recipient -- information on creating new mail collections and
                   details on how they work

Also see: mail in Builder Help

messages

Note to programmers:
  This class of commands automatically applies to any property whose
name ends in '_msg'. Thus, in the example above, the command is
setting the 'leave_msg' property of the named exit. You can get
such a command to work on new kinds of objects simply by giving the
appropriate properties names that end in '_msg'.
  Additionally, in many cases the _msg property is accompanied by a
_msg verb, which defaultly returns the named property, but which is
available to be customized in more complex ways than allowed by
simple string substitution. You should check for the particular
property you're considering whether the verb form exists (typically
with @display).

Also see: messages in Builder Help

porting-objects

Before saying anything else about porting MOO objects, note that the first rule is: GET THE CREATOR'S PERMISSION. The MOO world has a firm history of sharing code, and most programmers will be flattered that you asked. Generally, you should use `examine' to determine an object's creator and then send them MOO mail requesting permission to port their object.

In order to port objects, you'll need to be a programmer in both the source and the destination MOO. In addition, the object must usually be readable in the source MOO. Finally, if the object has verbs that must run under wizard permissions, you'll either need to be a wizard in the destination MOO or have a wizard there help you.

Although it helps to be a sufficiently skillful programmer that you understand the code you're porting, it isn't absolutely necessary. However, note that bad coding can open nasty security holes that can lead to damage up to and including allowing a malicious programmer to recycle your character. Porting code you don't understand is a serious risk.

You will generally need to be using a client that allows logging of sessions and pasting of files into an active session. Although some raw telnet programs have these features, this will usually require using some kind of MUD/MOO client. Most of the better clients can perform these functions.

Several commands are available to assist programmers with porting
objects between MOOs. These are:

@display -- the `@display <object>.:' format give a summary of verbs,
            properties, and their associated settings.
@dump -- the primary tool for generating complete listings of MOO
         objects' code

Step by Step Procedure for Porting MOO Objects

    1. check if the object is readable and uses non-wizard permissions in the source MOO with the `@display <object>.:' command. Note that all the verbs are named (not numbered as they would be if unreadable), and that the header at the top includes "readable" among its characteristics. Also, note the permissions for each verb to confirm none are wizardly. If all the verb and property owners are not the same, you have a complicated object that will not be ported successfully by the simple procedure described here.
    2. Get permission from the object's owner to port it. If the object isn't readable, or one or more verbs aren't, you will also need to get the code for these directly from the author.
    3. Create an object in the destination MOO with the same name as the original object. Note its object number.
    4. Connect to the source MOO and start session logging. Type `@linelen 500' and `@wrap off' to suppress the MOO's line wrapping.
    5. Type `@dump <object> id=<number> with recreate' where <object> is the name of the object to port, and <number> is the object number (with "#" included) of the object you just created in the destination MOO.
    Some MOO's don't have a "recreate" option, in which case you should use "create" instead.
    6. Stop logging the session, to close the file.
    7. Open the file containing the @dump in your favorite word processor. Remove the `@dump' line at the top and also the `@create' line if one is present. Check the list of properties (the top section) for a `key' property and an `object_size' property and delete them if present.
    If other lines are present that have `E_PERM' or `Permission denied' as values, these may be unreadable properties. They may interfere with your ability to port the object, but not necessarily.
    8. Connect to the destination MOO.
    9. Perform the `paste file' or other command that causes the edited @dump listing to be entered into your MOO session.
    10. Use `@display <object>.:' to check that all the properties and verbs have been added properly. Some, like `aliases' and `description' might not show on the list, which is alright.
    11. Test the ported object thoroughly.

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

#@eval-env-string@setenvlocal-editing
&-pointers@examine@showlocking
.program@forked@tasksmail
;@gethelp@taskstackmessages
@add-feature@grep@verbporting-objects
@args@kill@verbprogprecedence
@chatmode@killgrepbinary-stringsprepositions
@check-chparent@lasteditdocumentationprog-index
@check-property@lastmodifieddomain-systemprog-summary
@chmod@listeditorsprogrammer-summary
@clearproperty@prog-optionserrorsprogramming
@compare@programevalpronouns
@copy@propertyeval-dscattering
@display@propsetexaminestatements
@display-options@prospectusexpressionstasks
@displayoptions@prospectusDBfeaturestruth
@document@remove-featureforked-interpretationutilities
@drawing@renamefunctionsvalue-types
@dump@residentsgopherverb-references
@edit@rmeval-envhelpweb
@egrep@rmpropertykey-representationweb-programming
@eval-env@rmverblanguage

prog-summary

See: programmer-summary

programmer-summary

  This text summarizes some of the common commands available to
programmers. Some of of the commands are only usable if you also
have your "progbit" set, but others only require that your character
be a child of $prog. The listing is roughly in order of general usefulness.

@display -- by far the most useful tool for getting info on objects, verbs, and properties
@list -- list the code of a programmed verb
@verb -- add a verb to an object
@rmverb -- removes a verb
@property -- add a property to an object
@rmproperty -- removes a property
@chmod -- change the "permissions" on an object, property, or verb
# -- a deceptively simple tool for quickly checking objects and property values
@args -- change the arguments a verb can be called with
@tasks -- a less spammy varient of @forked
@forked -- show a list of forked or otherwise suspended tasks you own
@kill -- kill one or more forked or otherwise suspended tasks
@copy -- copy a verb or property
@program -- enter lines of code for a verb
@dump -- lists all properties and verb code on an object
eval -- run a program entered on the command line
eval-d -- like "eval" but runs equivalently to a -d verb
@clearproperty -- set a property to "clear"
@grep -- search the verbs on specified objects for a given text
@egrep -- like @grep but takes regular-expressions
@document -- a quick way to add header documentation to a verb
@lastmodified -- display the timestamps for an object and all its verbs
@taskstack -- see the stack for a suspended task
@prospectus -- a version of @audit with some additional information
@gethelp -- displays the raw text of a help topic from a specified help database
@prospectusDB -- a less efficient version of @prospectus that bypasses the person's .owned_objects property
@show -- shows various detailed info about an object; superceeded by the superior @display command
@check-property -- checks an objects ancestors for the presence of a property
@setenv -- a tool for adjusting one's eval environment
web-programming -- tips on how to make MOO objects "web aware"

programming

The 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 -- entering the program for a verb
.program - (same as @program but bypassing the MOO's in-DB system)
@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

pronouns

Notes for programmers:

Messages are indicated on objects as properties ending in "_msg" which flags them for
  the @messages command and the message setting system. For instance, the "explode"
  message would appear as <object>.explode_msg, and people could set it with: @explode
  <object> is "here is the explode text"

 In programs, you should use $string_utils:pronoun_sub() to perform the various
  substitutions documented here.

One, obscure aspect: %n actually calls player:title() while %(name) refers to
  player.name directly.

Also see: pronouns in General Help

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

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

        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.

        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 person types a command, a task is created to execute that command; we call these 'command tasks'.
   + Whenever a person 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 people 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 person 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 person
$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

value-types

The following types of variables are defined in MOO language:

Type Abbreviation (abbreviation value)
---- ---------------------------------
Integer number INT (0)
Objects OBJ (1)
String STR (2)
Error ERR (3)
List LIST (4)
Floating point number FLOAT (9)

The abbreviation "NUM" for an integer number is outdated and should
not be used, although the server supports it for reasons of backward
compatibility.

There is a special kind of string used in MOO for representing
arbitrary bytes, and generally used for binary input and output.
These appear to MOO code as being of type STR, just like ordinary
strings. See `help binary-strings' for more information.

See the LambdaMOO Programmer's Manual for more details on MOO values.

Obscure trivia:Types with values of 5 to 8 are used internally by the
MOO server code.

verb-references

The built-in functions that manipulate or report on MOO verbs accept numeric verb references in addition to references by name. The first verb defined on an object is verb number one, with later verbs numbered incrementally.

For instance, if
verbs(object)=={"first","second","third"}
then
verb_info(object,"second")==verb_info(object,2)

Note that previous version of the LambdaMOO server allowed numeric strings as verb references. In addition, "0" was a synonym for the first verb defined on an object. This lead to ambiguous references when verbs were named with numeric strings. Numeric string verb references are no longer permitted under server version 1.8.0 or later. The built-in functions that accepted numeric strings now will accept numbers instead.

The following built-in functions accept numeric verb referenes: verb_info(), verb_code(), delete_verb(), verb-args(), set_verb_info(), set_verb_args(), set_verb_code().

web

Additional topics for programmers:
web-system -- details on web system objects
web-programming -- how to make MOO objects "web aware"

Also see: web in General Help

web-programming

Web programming is usually performed by modifying objects such that
they provide special information when people interact with them using
the $standard_webviewer. Note that only the $standard_webviewer and
other viewers that are only for authenticated transactions can
interact with the object this way (ie. the Web Ghost Viewer,
$anon_webviewer, cannot).

To make an object "web aware," add custom verbs to it that accept
information from the $std_webviewer and returns a

The relevent verbs are:

  :html() - returns the object's description or other "what you
see" text.
  :do_post() - called when a POST transaction is directed at the
object
  :more_info_for_web() - additional information appended to the
object's "what you see" section
  :verbs_for_web() - commands and other user-interaction can go here,
and is the last portion presented

By default, the #1:html verb returns the object's description,
and the #1:more_info_for_web and #1:verbs_for_web return nothing. To
see an example of a :more_info_for_web verb, check out
$container:more_info_for_web, which presents the list of objects
inside the container. An example of :verbs_for_web is on $note,
where it presents the "read" command.

The :do_post verb is called when an HTTP transaction of type POST is
pointed at the object. These transactions have an accompanying web
form line that encodes information from the HTML form that contained
the link. An object can have a single verb with both "html" and
"do_post" aliases.

When focused on using a web browser, and object's :html or do_post
verb is called as:

  html/do_post(who OBJ, rest STR, search STR [,line STR])

Where "line" is only supplied if the transaction is a POST. The
"who" value is only included for backward compatibility and is not
defined. The verb is called with `player' and caller_perms() set to
the object number the transaction's authentication assigned it to.

The "REST" and "SEARCH" strings are derived from the URL:

  http://moo.du.org/99webpass/code/what/REST?SEARCH

Where "what" is the object number without the "#" and "code" is the
code for the web application being used ("view" in the case of the
$std_webviewer).

The "REST" and "SEARCH" portions of the URL can be used to send
information to the object, including commands. For instance, if
"REST" is "open" it might tell the object to open.

To create a link including embeded information, include a line in the
:html verb like:

code = $web_utils:user_webviewer:get_code();
line = tostr("<A HREF=\"http://&LOCAL_LINK;/",code,"/",
        tonum(this),"/open\">Select to open</A>");

which would (if the object is #5555, and the viewer is the
$std_webviewer), produce the HTML text:

<A HREF="http://&LOCAL_LINK;/view/5555/open">Select to open</A>

When the MOO outputs this, it will convert the &LOCAL_LINK; string to
a value pointing back to the MOO and including authentication
information if needed. When the user selected this link, another
call to #5555:html would be made, but this time the value of "REST"
would be "open" and the verb could act appropriately.

If the reference was for a form, it would look like:

<FORM METHOD="POST" ACTION="http://&LOCAL_LINK;/view/5555">
<INPUT TYPE="TEXT" NAME="example">
<INPUT TYPE="SUBMIT">
<FORM>

When the person selects the "submit" button on the form, a call will
be made to #5555:do_post and the "line" argument will be the encoded
information the user entered into the text field. This data could be
extracted with $web_utils:parse_form. For example, if the user
enters "my text" then:

$web_utils:parse_form(line) -> {{"example","my text"}}