& ATTRIBUTE FLAGS
  Attribute flags are set on an object's attributes using @set, or applied to attributes globally using @attribute. Their names (and, when applicable, the character used in examine as shorthand for the flag) are shown below.
  
  These attribute flags restrict access, and are inherited down attribute trees (if FOO is no_command, FOO`BAR is automatically no_command too):

  no_command ($)    Attribute won't be checked for $-commands or ^-listen patterns.
  no_inherit (i)    Attribute will not be inherited by the children of this object.
  no_clone (c)      Attribute will not be copied if the object is @clone'd.
  mortal_dark (m)   Attribute cannot be seen by mortals. This flag can only be set by royalty and wizards. "hidden" is a synonym.
  wizard (w)        Attribute can only be set by wizards. This flag can only be set by royalty and wizards.
  veiled (V)        Attribute value won't be shown on default examine, but is still otherwise accessible (for spammy attribs).
  nearby (n)        Even if the attribute is visual, it can only be retrieved if you're near the object (see 'help nearby()').
  locked (+)        Attribute is locked with @atrlock.
  safe (S)          Attribute can't be modified without unsetting this flag.

  Continued in 'help attribute flags2'
& ATTRIBUTE FLAGS2
  These attribute flags grant access. They are not inherited down attribute trees, and must be set on a branch attribute as well as a leaf to take effect (to make FOO`BAR visual, FOO must be visual too):
  
  visual (v)        Attribute can be seen by anyone via examine, get(), eval(), ufun(), zfun(), and similar functions.
  public (p)        This attribute can be evaluated by any object, even if safer_ufun is in use. DANGEROUS! AVOID!

  These attribute flags alter the way attributes are used in commands and ^-listens. They always only affect the attribute they're set on, regardless of attribute trees:

  debug (b)         Start showing debug output while this attr is evaluated.
  no_debug (B)      Stop showing debug output when this attr is evaluated
  regexp (R)        Match $-commands and ^-listens using regular expressions. See 'help regexps'.
  case (C)          Match $-commands and ^-listens case sensitively.
  nospace (s)       Attribute won't add a space after the object name in @o-* messages. See 'help verbs'.
  noname (N)        Attribute won't show name in @o-* messages.

  Continued in 'help attribute flags3'
& ATTRIBUTE FLAGS3
  aahear (A)        ^-listens on this attribute match like @aahear
  amhear (M)        ^-listens on this attribute match like @amhear
  prefixmatch       When set with @<attrib>, this attribute will be matched down to its unique prefixes. This flag is primarily used internally, but also useful in @attribute/access.
  quiet (Q)         When altering the attribute's value or flags, don't show the usual confirmation message

  These attribute flags are only used internally. They cannot be set, but seen on 'examine' and flags()/lflags(), tested for with hasflag(), etc:
  branch (`)        This attribute is a branch. See: help ATTRIBUTE TREES
  
See also: @set, @attribute, ATTRIBUTE TREES
& ATTRIBUTE TREES
& ATTR TREES
& ATTRIB TREES
& `
  Attributes can be arranged in a hierarchical tree; these are called "attribute trees", and a conceptually similar to the way that files and directories/folders are organized on computer filesystems. Attribute trees can be used to reduce spam when examining and to provide organized control over permissions for related attributes.

  Attribute trees use the backtick (`) character to separate their components (much as filesystems use / or \). For example, the following attribute name would be a couple levels down in its tree:

  CHAR`SKILLS`PHYSICAL

  Attribute names may not start or end with the backtick, and may not contain two backticks in a row.

  All attributes are either branch attributes or leaf attributes. A branch attribute is an attribute that has other branches or leaves beneath it; a leaf attribute is one that does not. Any attribute may act as a branch. If you try to create an unsupported leaf, branch attributes will be created as needed to support it.

See 'help attribute trees2' for more information and examples.
& ATTRIBUTE TREES2
& ATTR TREES2
& ATTRIB TREES2
& `2
  Attribute trees provide two immediate benefits. First, they reduce spam when examining objects. The usual * and ? wildcards for attributes do not match the ` character; the new ** wildcard does. Some examples of using examine:
   examine obj              displays top-level attributes (plus object header)
   examine obj/*            displays top-level attributes
   examine obj/BRANCH`      displays only attributes immediately under BRANCH
   examine obj/BRANCH`*     displays only attributes immediately under BRANCH
   examine obj/BRANCH`**    displays entire tree under BRANCH
   examine obj/**           displays all attributes of object

  The same principles apply to lattr(). @decompile obj is a special case, and displays all attributes.

  Branch attributes will be displayed with a ` in the attribute flags on examine. 

See 'help attribute trees3' for more information and examples.
& ATTRIBUTE TREES3
& ATTR TREES3
& ATTRIB TREES3
& `3
  The second benefit of attributes trees is convenient access control. Attribute flags that restrict attribute access or execution (no_inherit, no_command, mortal_dark, wizard) propagate down attribute trees, so if a branch is set mortal_dark, mortals can not read any of its leaves or subbranches either.

  Attribute flags that grant access (e.g. visual) do NOT propagate down trees.

  These properties make attribute trees ideal for data attributes:
   > &DATA bank = Data for each depositor is stored here, by dbref
   > @set bank/DATA = no_command
   > &DATA`#30 bank = $2000 savings:$1000 loan @ 5%
  etc.

  They're also handy for things like character attributes:
   > @attribute/access CHAR = wizard mortal_dark no_clone no_inherit
   > &CHAR #30 = Character data
   > &CHAR`SKILLS #30 = coding:3 documentation:1 obfuscation:5
  etc.

See 'help attribute trees4' for information about @parent and attribute trees.
& ATTRIBUTE TREES4
& ATTR TREES4
& ATTRIB TREES4
& `4
  Attribute trees interact with @parent in several ways.

  As usual, children inherit attributes from their parent unless the child has its own overriding attribute. However, children that wish to override a leaf attribute must also have their own (overriding) copy of all branches leading to that leaf. This means that when you do:

  > &BRANCH parent = a branch
  > &BRANCH`LEAF parent = a leaf
  > &BRANCH`LEAF child = a new leaf

  In this case, a new BRANCH attribute will be created on the child, so '-[get(child/BRANCH)]-' will return '--'. This may not be what you actually want. In these cases, the pfun() function can be useful:

  > &BRANCH child=pfun(BRANCH)

  If a branch on the parent is set no_inherit, it will not be inherited, regardless of any other flags that may be present. If a branch is inherited, the child object can not loosen any access restrictions to inherited attributes that are set by the parent (although it may loosen access restrictions to its own attributes on the same branch). The child object may impose stricter restrictions, however, and these may prevent access to inherited parent data.
& CHAT
& CHAT SYSTEM
& comsys
& CHANNELS
  CHAT SYSTEM

  PennMUSH has a built-in chat system which allows you to speak to other players who are on the same channel without needing to be in the same room as them. It supports a large number of channels which can be customized and restricted in various ways.

  Many of the chat system commands take a <channel> argument; you don't need to enter the entire channel name, only as many letters as needed to make it distinct from other channels.

  You can list, join, and configure channels using the @channel command.

  To speak on channels, use the @chat command.
  
  There are some aliases in place for players more familiar with the MUX comsys - see 'help muxcomsys' for more details.

See also: @channel, @chat, @cemit, channel functions, CHAN_USEFIRSTMATCH,
  @chatformat, @clock
& @chat
& +
  @chat <channel>=<message>
  +<channel> <message>

  The @chat command is used to speak on channels. Everyone on the channel will see your message, and it will be added to the channel's recall buffer, if it has one. If <message> begins with a ':' or ';' it will be posed (or semiposed) instead of spoken. You will usually need to join a channel before you can speak on it.

  +<channel> <message> is short-hand for the @chat command.

  Example:
  > @chat pub=Hello
  <Public> Mike says, "Hello"
  > +pub :waves
  <Public> Mike waves

See also: @channel, @cemit
& @CHATFORMAT
  @chatformat <object>[=<message>]

  The chatformat attribute is evaluated when an object receives a channel message. If the attribute exists, its evaluated result is shown to the object instead of the default message. If the attribute exists but returns nothing, the object will not see anything.
  
  Registers:
    %0:  The 'type' of the message. It is a single character that will always be set:
           '"', ';' or ':' for say, semipose and pose, respectively.
           '|' for an @cemit.
           '@' for a "system" message - such as "Walker has connected."
    %1:  The channel name. e.g: "Public", "Admin", "Softcode"
    %2:  The message as typed (post-evaluation, if necessary) by the speaker. Be warned, though - if type is '@', then %2 will contain the entire message, and will include the name of the speaker that caused it.
    %3:  The speaker name, unless channel is set NO_NAME.
    %4:  The speaker's channel title, unless none is set, or the channel is NO_TITLE.
    %5:  The default message, as shown when no chatformat is set.
    %6:  The 'say' string for the message. This will usually be "says", unless altered by the SPEECHTEXT mogrifier.

    If the channel is NO_NAME, and the speaker either has no title or the channel is also set NO_TITLE, then %3 will be "Someone".

  Continued in 'help @chatformat2'.
See also: @chat, @pageformat, @message, speak(), mogrify
& @CHATFORMAT2
  Examples:

  Walker's preferred @chatformat, which strips all ansi out, wraps every line to your width and prefixes them with <ChannelName>:

    @chatformat me=<%1> [switch(%0,@,%2,edit(wrap(speak(&[if(%4,%4%b)]%3,%0[stripansi(%2)],%6\,),sub(width(%!),add(4,strlen(%1)))),%r,%r<%1>%b))]

  If you're on a system with chat_strip_quote set to "no", you might want to change the '%0%2' arg to speak() to '[switch(%0,",%2,%0%2)]'

  Suppose you want it just like the old version, but anytime somebody says your name, you want it all in red:

    @chatformat me=ansi(switch(%2,*[name(%!)]*,r,n),%5)

  See 'help @chatformat3' for more examples.
& @CHATFORMAT3
  A popular feature in clients now available in PennMUSH directly: Let's suppose you want "Public" channel chatter to all be green, "Softcode" to be blue and "Admin" to be cyan.

    @chatformat me=ansi(switch(%1,Public,g,Softcode,b,Admin,c,n),%5)

  Maybe you dislike players who re-@name themselves a lot:

    &playernames me=#6061:Walker #7:Javelin #6388:Cheetah
    @chatformat me=<%1> [switch(%0,@,%2,speak(&[if(%4,%4%b)][firstof(after(grab(v(playernames),%#:*),:),%3)],%2,%6\,))]

  Or you're writing a loggerbot, and you want to convert all channel input to HTML:

    @chatformat me=CHAT:%1:[edit(switch(%0,@,%2,speak(if(%4,%4%b)%3,%0%2,%6\,)),&,&amp;,<,&lt;,>,&gt;,%r,<BR>,%b%b,%b&nbsp;)]
     or
    @chatformat me=CHAT:%1:[render(switch(%0,@,%2,speak(if(%4,%4%b)%3,%0%2,%6\,)),html)]

& CHAN_USEFIRSTMATCH
  Flag:  CHAN_USEFIRSTMATCH  (any type)

  Normally, when an object attempts to speak on the channel system with @chat, using an ambiguous channel name produces an error message. With this flag set, it will instead speak on the first channel whose name is a match. Other commands in the chat system are not affected by the flag.

See also: CHAT, @chat, @cemit
& @CEMIT
& @NSCEMIT
& CEMIT()
& NSCEMIT()
  @cemit[/noisy|/silent][/noeval] <channel>=<message>
  @nscemit[/noisy|/silent][/noeval] <channel>=<message>
  cemit(<channel>, <message>[, <noisy>])
  nscemit(<channel>, <message>[, <noisy>])

  @cemit emits <message> on <channel>. It does not include your name. The channel prefix is included if the /noisy switch is given, and omitted if /silent is given - if neither is given, the default behaviour is controlled by the noisy_cemit @config option. The /noeval switch prevents <message> from being evaluated.
  
  You must be able to speak on the channel, or have the See_All and Pemit_All @powers, to @cemit on the channel.

  @nscemit is exactly the same, but does not produce nospoof information when used by players with the Can_spoof @power.

  cemit() and nscemit() work the same as @cemit/silent and @nscemit/silent, respectively. If <noisy> is given as a true value, they work like @cemit/noisy and @nscemit/noisy, respectively, instead.

  @cemit is intended for use in writing extended chat systems. 

See also: @chat
& @channel

  The @channel command is used to add, join, list and modify channels in the chat system. It takes many different switches.

  Help for @channel is split into a number of topics. Please see 'help @channel <topic>' for more, where <topic> is one of the words below. For help on a specific switch to @channel, use 'help @channel/<switch>'.

  Joining    - How to find, join, and leave channels
  Other      - Setting channel titles, recalling previous chat messages
  Admin      - Adding, deleting and modifying channels

See also: CHAT, @chat, @cemit, channel functions
& @CHANNEL JOINING
& @channel/list
& @channel/what
& @channel/who
& @channel/on
& @channel/join
& @channel/off
& @channel/leave
  @channel/list[/on|/off][/quiet] [<prefix>]
  @channel/what [<prefix>]
  @channel/who <channel>
  @channel/on <channel>[=<player>]
  @channel/off <channel>[=<player>]

  @channel/list shows a list of all the channels you can see, along with some basic information such as whether you are on the channel, how it's locked, etc. 'help @channel list' explains the output in detail. If a <prefix> is given, only channels whose names begin with <prefix> are shown. If the /on switch is given, only channels you've joined are shown. If /off is given, channels you are on will not be shown. The /quiet switch shows just a list of channel names, without any extra information.

  @channel/what shows the name, description, owner, priv flags, mogrifier and buffer size for all channels, or all channels whose names begin with <prefix> if one is given.

  @channel/who lists all the players on the given channel.

  @channel/on and @channel/off add or remove you from the given <channel>. You only hear messages for channels you're on, and most channels require you to join them before you can speak on them. /join and /leave are aliases for /on and /off.

  Continued in 'help @channel joining2'.
& @CHANNEL JOINING2
& @channel/gag
& @channel/ungag
& @channel/hide
& @channel/unhide
& @channel/mute
& @channel/combine
& @channel/uncombine
  @channel/gag [<channel>][=<yes|no>]
  @channel/mute [<channel>][=<yes|no>]
  @channel/hide [<channel>][=<yes|no>]
  @channel/combine [<channel>][=<yes|no>]

  @channel/gag allows you to stay on a channel but stop receiving messages on it. Channels are automatically ungagged when you disconnect. You cannot speak on channels you're gagging unless they have the "open" priv.

  Channels without the 'quiet' priv broadcast messages when players connect or disconnect from the MUSH. You can use @channel/mute to suppress these messages if you don't want to see them.

  On channels with the 'hide_ok' priv, @channel/hide lets you hide from the @channel/who list if you pass the channel's @clock/hide.

  Connect and disconnect messages across all channels you have marked with @channel/combine will be combined into a single message with a |-separated list of all channel names. Only players can use this.

  For all four of these commands, you can specify a single channel to affect, or omit <channel> to affect all channels you're on. To undo the gag/mute/hide, either use @channel/<switch> [<channel>]=no or
  @channel/un<switch> [<channel>].
  
See also: @channel/who, cstatus(), cowner(), cflags(), channels(), @channel/privs
& @CHANNEL OTHER
& @channel/title
& @channel/recall
  @channel/title <channel>[=<message>]
  @channel/recall[/quiet] <channel>[=<lines|duration>[, <start line>]]

  @channel/title lets you set a channel title, which is shown before your name whenever you speak on a channel. If =<message> is omitted, your current title on the channel is shown. Use an empty <message> to clear your title.
  The maximum length of titles is set in the 'chan_title_len' @config option.

  @channel/recall shows you the most recent messages on the channel, if it has been given a recall buffer with @channel/buffer. With no extra arguments, the 10 most recent lines are shown. You can specify either a number of <lines> to show, or a <duration> (such as '1h30m') to show only that many lines/messages that recent. If <start line> is given, lines before the <start line>th will not be shown. Timestamps are shown with the messages unless /quiet is given.

See also: crecall(), cbufferadd(), @channel/buffer
& @CHANNEL ADMIN
& @channel/add
& @channel/privs
& @channel/describe
& @channel/buffer
& @channel/decompile
  @channel/add <channel>[=<privs>]
  @channel/privs <channel>=<privs>
  @channel/describe <channel>=<description>
  @channel/buffer <channel>=<lines>
  @channel/decompile[/brief] <prefix>

  @channel/add creates a new channel named <channel>, with the given <privs>. If you don't specify the <privs>, the defaults set in the channel_flags @config option are used. There may be a limit on the number of channels mortals can create, and a charge for doing so; see '@config chat'.

  @channel/privs changes the privs for <channel>. See 'help @channel privs' for an explaination of all the possible priviledges. More specific and/or complex restrictions can be set via @clocks (channel locks).

  @channel/describe sets a description for the channel, which is shown to players in @channel/what. Limited to 256 characters. If the desc includes commas, the whole desc should be enclosed in {}s.

  @channel/buffer sets the maximum number of full-length lines (8192 bytes) that the channel will buffer for @channel/recall. Many more shorter lines may actually be buffered. Setting it to 0 turns off buffering.

  @channel/decompile produces a decompile of all channels whose name begin with <prefix>, showing the commands needed to recreate the channels. If the /brief switch is also given, commands to re-add members of the channel are omitted.

  Continued in 'help @channel admin2'.
& @CHANNEL ADMIN2
& @channel/chown
& @channel/name
& @channel/rename
& @channel/wipe
& @channel/delete
  @channel/chown <channel>=<new owner>
  @channel/rename <channel>=<new name>
  @channel/wipe <channel>
  @channel/delete <channel>

  @channel/chown changes the owner of <channel>. It can only be used by Wizards.

  @channel/rename changes the name of <channel>.

  @channel/wipe removes all players from <channel>.

  @channel/delete completely removes <channel>. It can only be used by Wizards or the owner of <channel>.

  Continued in 'help @channel admin3'.
See also: @clock
& @CHANNEL ADMIN3
& @channel/mogrifier
& chat mogrifying
& @chat mogrifying
& mogrify
& mogrifier
  @channel/mogrifier <channel>=<object>

  @channel/mogrifier sets the mogrifier object for <channel>. <object> must be an object that you control.

  Mogrifiers let you tweak every aspect of a channel's output, before it goes to individual players' @chatformats. 

  Before it begins mogrifying, three mogrifiers that alter the way chats are handled are run, using the same arguments as @chatformat (except that %5 is not set). First, <object>'s MOGRIFY`BLOCK attribute is called. If MOGRIFY`BLOCK returns a non-empty string, then the resultant string is sent back to the player, and no message is broadcast on the channel.
  
  Next, MOGRIFY`OVERRIDE is called. If it returns a true value, player's individual @chatformats will not be called for the message.
  
  The MOGRIFY`NOBUFFER attribute is then called. If it returns a true value, the message will not be included in the channel's recall buffer.

  Continued in 'help mogrify2'.
& mogrify2
  After that, mogrifiers which alter individual portions of the message are called. See 'help mogrify3' for details.
  
  After all these mogrifiers are called, MOGRIFY`FORMAT is evaluated. It has the same use as @chatformat, but on a channel-wide level. It receives all mogrified text (if any), so is generally intended only for reformatting the whole channel text. It is also overriden by individual @chatformats (unless MOGRIFY`OVERRIDE returned true).

  See 'help mogrify3' for info on specific mogrifiers, and 'help mogrify4' for some examples.
See also: cmogrifier()
& mogrify3

  There are mogrify attributes for each individual piece of the channel message. If any evaluate to a non-empty string, they replace that portion of the chat message. Each mogrify attribtute is passed six arguments:

  %0 - (Depends on the mogrifier.)
  %1 - Channel name (unmogrified).
  %2 - Chat type (", :, ;, |, @). See 'help @chatformat' for descriptions.
  %3 - Message.
  %4 - Player chan title*
  %5 - Player name*

  The mogrify attributes available are:
  MOGRIFY`CHANNAME: %0 = default channel display. (e.g: "<Public>").
  MOGRIFY`TITLE: %0 = The player's title, if any.
  MOGRIFY`PLAYERNAME: %0 = The player's name.
  MOGRIFY`SPEECHTEXT: %0 = "says"
  MOGRIFY`MESSAGE: %0 = <the content of the say, pose, semipose or emit>

  * These fields respect the "notitles" and "nonames" channel privs. If both title and name would be empty, the name will default to "Someone".

  See 'help mogrify4' for examples.
& mogrify4
For Talk Like a Pirate Day (Sep 19):

  > @create Pirate Filter
  > @chan/mogrifier public=Pirate Filter
  > &MOGRIFY`BLOCK Pirate Filter=switch(%5,*ninja*,We don't need no ninjas!)
  > &MOGRIFY`TITLE Pirate Filter=switch(poss(%#),her,Wench,Buccaneer)
  > &MOGRIFY`SPEECHTEXT Pirate Filter=yo-hos
  > &MOGRIFY`MESSAGE Pirate Filter=edit(%0,r,rrr)
  > &MOGRIFY`CHANNAME Pirate Filter=(%1-Yarr!)

Output:
  > +public Hello
  (Public-Yarr!) Buccaneer Walker yo-hos, "Hello"

  > +public :thinks it's talk like a pirate day?
  (Public-Yarr!) Buccaneer Walker thinks it's talk like a pirrrate day?

  > +public Pirates suck, Ninjas are better!
  We don't need no ninjas!
  (And the message is blocked, won't be sent out).

  See 'help mogrify5' for more examples.
& mogrify5
For keeping a channel PG and safe, and altering the channel name from
<Public> to [Public], with a green "Public".

  > @create PG Channel Mogrifier
  > @chan/mogrifier public=PG Channel Mogrifier
  > &BADWORDS PG=list of bad words
  > &MOGRIFY`MESSAGE PG=regeditall(%0,\\b([edit(v(badwords),%b,|)])\\b,***)
  > &MOGRIFY`CHANNAME PG=\[[ansi(g,%1)]\]
  > &MOGRIFY`title PG=if(strlen(%0),\(%0\))

  Output: (With a channel title of "Fast") ("Public" is green)
  > +p Hello
  [Public] (Fast) Walker says, "hello"
  > +p what the list is going on bad bad?
  [Public] (Fast) Walker says, "what the *** is going on *** ***?"

  Combine MOGRIFY`FORMAT with speak() and you can have plenty of fun: On-channel language systems and more!

  See 'help mogrify6' for more examples.
& mogrify6
  This example tweaks individual elements of the channel output, and then uses MOGRIFY`FORMAT to recolour the entire string.

  > @chan/mogrifier Public=Mog
  > &MOGRIFY`CHANNAME Mog=\[%1\]
  > &MOGRIFY`PLATERNAME Mog=ucstr(%0)
  > &MOGRIFY`FORMAT Mog=ansi(h,%5)
  
  Stop anything by an admin from being altered by chatformats, and prevent anything said by Wiggles from being recorded in the channel's recall buffer.
  > &MOGRIFY`OVERRIDE Mog=orlflags(%#, Wizard Royalty)
  > &MOGRIFY`NOBUFFER Mog=switch(%#, pmatch(Wiggles), 1, 0)

& @channel list
& channel-list
Here's the legend for reading the @channel/list output:

Channel Name               Num Users Num Msgs  Access Locks     Status   Buf
Sample                             1        0 [DPTWQHo jsmvh*] [On  QHC]   4
                                               ||||||| ||||||   |   |||    |
Channel is DISABLED----------------------------/|||||| ||||||   |   |||    |
Channel allows PLAYERS--------------------------/||||| ||||||   |   |||    |
Channel allows THINGS----------------------------/|||| ||||||   |   |||    |
Channel is Wizard-only (W) or Admin-only (A)------/||| ||||||   |   |||    |
Channel is QUIET-----------------------------------/|| ||||||   |   |||    |
Channel is HIDE_OK----------------------------------/| ||||||   |   |||    |
Channel is OPEN (non-members can speak on it)--------/ ||||||   |   |||    |
Channel has @clock/join set----------------------------||||||   |   |||    |
Channel has @clock/speak set----------------------------/||||   |   |||    |
Channel has @clock/mod set-------------------------------/|||   |   |||    |
Channel has @clock/see set--------------------------------/||   |   |||    |
Channel has @clock/hide set--------------------------------/|   |   |||    |
Player is the owner of the channel--------------------------/   |   |||    |
Player is currently on/off/gagging the channel------------------/   |||    |
If on, player has the channel muted---------------------------------/||    |
If on, player is hiding on the channel-------------------------------/|    |
If on, player has @channel/combined the channel-----------------------/    |
Size of the channel buffer in full-length lines----------------------------/
& @channel privs
& channel-privs
  The <privs> for @channel/add and @channel/privs should be a space-separated
  list of priv names, or a string of priv chars, from the list below:

  * "player" (P) - players may use the channel
  * "object" (O) - non-players may use the channel
  * "admin" (A) - only royalty/wizards/chat_privs may use the channel
  * "wizard" (W) - only wizards may use the channel
  * "quiet" (Q) - channel will not show connection messages
  * "open" (o) - you may speak even if you aren't listening to the channel
  * "hide_ok" (H) - you may hide from the channel who list
  * "notitles" (T) - chantitles are not displayed in channel messages
  * "nonames" (N) - player names are not displayed in channel messages
  * "nocemit" (C) - @cemit is prohibited on the channel
  * "interact" (I) - Interaction rules (defined in local.c) are applied to the channel
  * "disabled" (D) - noone can join or speak on the channel

  The default privs are determined by the 'channel_flags' @config option.

  Example:
    > @channel/add Public=player quiet open nocemit

See also: cflags(), clflags(), channel functions
& @clock
  @clock/join <channel>[=<key>]
  @clock/speak <channel>[=<key>]
  @clock/see <channel>[=<key>]
  @clock/hide <channel>[=<key>]
  @clock/mod <channel>[=<key>]

  The @clock command modifies the @lock-style lock on a chat channel. If no <key> is specified, the lock is removed. See 'help lockkeys' for an explaination of <key>.

  The "join" lock restricts who can join the channel.
  The "speak" lock restricts who can speak on the channel.
  The "see" lock restricts who can see the channel on @channel/list
  The "hide" lock restricts @channel/hide if the channel is hide_ok.
  The "mod" lock restricts who can modify the channel. If you pass the mod lock on the channel, you can do anything short of deleting it.

  When new channels are added, the mod lock is set to the creator/owner (=<creator>), and all other locks are unlocked.
  
  Continued in 'help @clock2'.
& @clock2
  Locks are checked as if they were set on the object attemping to pass them - for example, in the channel lock:
    > @clock/join Public=test/1
  the attribute "test" will be evaluated on the object trying to join the Public channel.

  You can use indirect @clocks to lock a channel to an @lock on an object. Objects attempting to pass the lock must be able to see the indirect lock, so it's recommended you set either the lock or the object VISUAL. This channel can only be joined by objects which aren't set UNFINDABLE:

  > @clock/join unfindchannel=@#10
  > @lock/user:ChanJoinLock #10=!flag^unfindable
  > @lset #10/ChanJoinLock=VISUAL   OR   @set #10=VISUAL

  @clock                  Corresponding default user: lock for object
  join                    ChanJoinLock
  speak                   ChanSpeakLock
  see                     ChanSeeLock
  hide                    ChanHideLock
  mod                     ChanModLock

  If you want to store different locks for different channels on the same object, you can use a specific indirect lock instead of the default one:

  > @lock/user:onechanneljoin #10=flag^foo
  > @clock/join onechannel=@#10/onechanneljoin
  > @lock/user:anotherchanneljoin #10=flag^bar
  > @clock/join anotherchannel=@#10/anotherchanneljoin

See also: clock(), @lock, @channel/privs
& COWNER()
  cowner(<channel>)

  Returns the dbref of the owner of a channel.
  
See also: @channel/chown, channel functions
& CTITLE()
  ctitle(<channel>, <object>)

  Returns <object>'s @channel/title on <channel>. You must either be able to examine the object, or it must be visibly on <channel>, and you must either be on <channel> on able to join it.
  
See also: @channel/title, channel functions
& CSTATUS()
  cstatus(<channel>, <object>)

  Returns <object>'s status with respect to <channel>, which may be "Off", "On", or "Gag". You must either be able to examine the object, or it must visible be on the channel; "Off" is returned for objects that you cannot see on the channel.
  
See also: cwho(), cflags(), @channel/on, @channel/gag, channel functions
& CDESC()
& CUSERS()
& CMSGS()
& CBUFFER()
  cdesc(<channel>)
  cusers(<channel>)
  cmsgs(<channel>)
  cbuffer(<channel>)

  Return the description (@channel/describe), number of users, number of messages in the recall buffer, or buffer size of <channel>, respectively. This information is also displayed in @channel/list and @channel/what.

See also: cbufferadd(), crecall(), channel functions
& CBUFFERADD()
  cbufferadd(<channel>, <text>[, <spoof>])

  Adds text to a channel buffer without broadcasting it to all people on the channel. If <spoof> is true, it will spoof the enactor (%#).

  This function is only usable by objects that pass the channel's @clock/mod, and who can use the @cemit command (or @nscemit if <spoof> is true).
  
See also: crecall(), cbuffer(), @channel/recall, @channel/buffer, channel functions
& CWHO()
  cwho(<channel>[, <status>[, <skip gagged?>]])
 
  This function returns the dbrefs of objects which are on <channel>. <status> can be one of "on", "off" or "all" to control whether online players, offline players, or all players are returned; it defaults to "on". (Things are always returned.) When used by mortals, hidden/dark players are shown as being offline.
  
  If <skip gagged?> is given, and is true, gagged objects will not be included in the results.

See also: cstatus(), @channel/who, channel functions
& CFLAGS()
& CLFLAGS()
  cflags(<channel>)
  cflags(<channel>, <object>)
  clflags(<channel>)
  clflags(<channel>, <object>)

  With one argument, cflags() returns a list of priv flags set on the given channel, represented as a string of characters. See 'help @channel privs' for the list. You must be able to see the channel to use this function.

  With two arguments, cflags() returns a list of flags for that object on that channel, currently a string consisting of zero or more of "G" (Gag), "Q" (Quiet), "H" (Hide) and "C" (Combine). You must be able to see that channel and to examine the object to use this function. If the object is not on the channel, an error is returned.

  The clflags() versions return a space-separated list of flag names, rather than a string of flag characters.
  
See also: cstatus(), channel functions
& CHANNELS()
  channels([<delimiter>])
  channels(<object>)
  channels(<object>[, <delimiter>])

  With no arguments, channels() returns the list of all channel names which are visible to the player. With two arguments, returns the list of channel names to which the object is listening, delimited by <delimiter>.

  With one argument, the behavior is ambiguous. If the argument matches an object, it returns a space-separated list of channels to which the object is listening. If not, it's treated as a no-argument case with a delimiter.

  If you can examine the object, the function returns all the channels it's on. Otherwise, it will only return those channels you can see that <object> is a member of with @channel/who.
  
See also: @channel/list, @channel/who, cwho(), channel functions
& CLOCK()
  clock(<channel>[/<locktype>][, <new lock>])

  With one argument, returns the value of a lock on a channel, if you own the channel or are See_All. If no locktype is given, "JOIN" is assumed. With two arguments, sets the lock if you would be able to do so via @clock.

See also: @clock, @lock, channel functions
& CRECALL()
  crecall(<channel>[, <lines> [, <start line> [, <osep> [, <timestamps?> ]]]])

  This function is the functional form of @channel/recall, and returns a string containing the recalled lines from the channel, separated by <osep> (which defaults to a space). If <timestamps?> is a true value, the recalled lines will be prefixed with the timestamp; otherwise, timestamps are omitted.
  
  <lines> can be either a number of lines (in which case that many lines will be returned, starting from the <start line>th line), or a duration of time (for example, '5h' or '10m30s'), in which case all lines from the previous <lines> time are returned.

See also: @channel/recall, cbufferadd(), channel functions
& CMOGRIFIER()
  cmogrifier(<channel>)

  Returns the dbref of the mogrifier of a channel.
  
See also: @channel/mogrifier, @chatformat, channel functions
& Channel functions
  Channel functions work with the channel system.

  cbuffer()     cbufferadd()  cdesc()       cemit()       cflags()
  channels()    clflags()     clock()       cmogrifier()  cmsgs()
  cowner()      crecall()     cstatus()     ctitle()      cusers()
  cwho()        nscemit()

See also: CHAT, @channel, @cemit, @clock
& MUXCOMSYS
& MUXCOMM
& ADDCOM
& DELCOM
& @CLIST
& COMTITLE
& COMLIST
  PennMUSH offers some compatability commands for players more familiar with the MUX communication system. For help on PennMUSH's channel system, see 'help channels'. The following commands are available:
  
  addcom <alias>=<channel>
    Join <channel> if you aren't already on it, and add <alias> as an alias for <channel>.
  <alias> WHO
    Alias for @channel/who <channel>
  <alias> OFF
    Alias for @channel/gag <channel>
  <alias> ON
    Alias for @channel/ungag <channel>
  <alias> <message>
    Say <message> on the channel matching <alias>. Does not evaluate <message>. Equivilent to +<channel> <message>.
  delcom <alias>
    Deletes the alias <alias> and, if it's the last alias you have for the matching channel, leave the channel.
  @clist[/full]
    List all channels. Alias of @channel/list. /full does nothing.
  comtitle <alias>=<title>
    Alias of @channel/title <channel>=<title>
  comlist
    Lists all aliases and their matching channels.

  See 'help muxcomsys2' for how to enable MUX com aliases.
  See also: CHANNELS, @channel, @chat
& MUXCOMSYS2
& MUXCOMM2
  To enable the MUX comsys aliases, set use_muxcomm to yes in game/mush.cnf and @shutdown/reboot.
  
  Aliases are stored by "addcom" in attributes on the player, in the format
  
    &CHANALIAS`<alias> <player>=<channel-name>

  Aliases are checked on parents, so you can add them to your ancestor player to have them usable by everyone.
& COMMANDS
Help is available for the following MUSH commands:
 
  ahelp          anews          brief          DOING          drop
  examine        enter          events         follow         get
  give           go             index          leave          LOGOUT
  look           move           news           page           pose
  QUIT           read           rules          say            score
  teach          think          unfollow       use            whisper
  WHO            with           "              :              ;
  +              ]
 
  In addition to these, there are several types of '@' commands. @-commands are usually commands which have permanent effects on the MUSH (such as creating a new object). Here are the help topics on @-commands:
 
  @-ATTRIBUTES   @-BUILDING     @-GENERAL      @-WIZARD
 
  Commands that can only be used by connected players are listed in HELP SOCKET COMMANDS.
& @-ATTRIBUTES
These '@' commands set standard message/action sets on objects. Each comes in 3 versions: @<whatever>, @o<whatever>, and @a<whatever>. Only the @<whatever> version is listed below, but help is available for each:
 
  @death         @describe      @drop          @efail         @enter
  @failure       @follow        @give          @idescribe     @leave
  @lfail         @move          @payment       @receive       @success
  @tport         @ufail         @unfollow      @use           @zenter        
  @zleave

These '@' command set other standard attributes on objects that don't follow the pattern above:

  @aahear        @aclone        @aconnect      @adisconnect   @amail
  @amhear        @away          @charges       @conformat     @cost
  @descformat    @ealias        @exitformat    @filter        @forwardlist
  @haven         @idescformat   @idle          @infilter      @inprefix
  @lalias        @listen        @nameformat    @oxenter       @oxleave
  @oxmove        @oxtport       @prefix        @runout        @sex
  @startup       

See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES
& @-BUILDING
These '@' commands are building-related (they create or modify objects):
 
  @atrlock       @atrchown      @chown         @chzone        @clone         
  @cpattr        @create        @destroy       @dig           @elock         
  @eunlock       @firstexit     @link          @lock          @moniker
  @mvattr        @name          @nuke          @open          @parent        
  @recycle       @set           @undestroy     @ulock         @unlink        
  @unlock        @uunlock       @wipe
  
& @-GENERAL
These '@' commands are general utility and programming commands:

  @@             @alias         @break         @channel       @chat
  @cemit         @command       @config        @decompile     @doing
  @dolist        @drain         @edit          @emit          @entrances
  @find          @force         @function      @gedit         @grep
  @halt          @lemit         @listmotd      @mail          @notify
  @nsemit        @nslemit       @nsoemit       @nspemit       @nsprompt      
  @nsremit       @nszemit       @oemit         @password      @pemit         
  @prompt        @ps            @remit         @restart       @scan          
  @search        @select        @stats         @sweep         @switch        
  @teleport      @trigger       @verb          @version       @wait          
  @whereis       @zemit

& @-WIZARD
These '@' commands are only usable by wizards or privileged players:
 
  @allhalt       @allquota      @boot          @chownall      @chzoneall
  @comment       @dbck          @disable       @dump          @enable
  @flag          @hide          @hook          @http          @kick
  @log           @motd          @newpassword   @pcreate       @poll
  @poor          @power         @purge         @quota         @readcache
  @rejectmotd    @shutdown      @sitelock      @sql           @squota
  @suggest       @uptime        @wall          @wizmotd       @wizwall
  cd             ch             cv
 
& ]
  "]" is a special prefix which can be used before any command. It instructs the MUSH that it shouldn't evaluate the arguments to the command (similar to the "/noeval" switch available on some commands). For example:

  > say [add(1,1)]
  You say, "2"

  > say \[add(1,1)\]
  You say, "[add(1,1)]"

  > ]say [add(1,1)]
  You say, "[add(1,1)]"

  > ]"[add(1,1)]
  You say, "[add(1,1)]"

  This can be used to pass unevaluated MUSHcode to softcoded commands without having to escape every special character, or to help objects set attributes to contain unevaluated code.

  See 'help ]2' for more examples.

See also: lit(), decompose(), escape(), @command, }
& ]2
  Using ']' with $-commands:
  
  > &test Tester=$test *: @pemit %#=I got: %0
  
  Normal evaluation:
    > test My name is %n.
    I got: My name is Wiggles.
  
  Preventing the user input from being evaluated:
    > ]test My name is %n.
    I got: My name is %n.

  Preventing evaluation of code inside the $-command:
    > &test Tester=$test *: ]@pemit %#=I got: %0
    > test My name is %n.
    I got: %0

  In the last example, '%0' would evaluate to 'My name is Wiggles.' (because the string entered by the user was evaluated), but the @pemit has been told not to evaluate its arguments.
& }
  "}" is a special prefix which can be used before any command. It causes the MUSH to show debug information when evaluating that command (the same as if you had the DEBUG flag set), and for any $-commands which are triggered by the command.
  
  In order for debug to be shown for triggered $-commands, you must either control the object(s) the matching $-commands are on, or be in the object's DEBUGFORWARDLIST attribute. 
  
See also: DEBUG, ]
& @@
  @@ [<text>]
 
  The "@@" command does nothing; it does not evaluate its input or show any messages to the executor. It can be used for commenting code.
  
  Example:
  > @va me=$testing: @emit Test ; @@ Just a test ; @vb me=Testing
  
See also: @@(), null()
& @aclone
  @aclone <object>=<action list>

  Sets the actions to be taken by <object> whenever it's @cloned. This command can be useful for notifying the owner of a vending machine or parent object when someone uses the machine.

  Please note that there are no @clone or @oclone attributes.
  
See also: @clone, @create, ACTION LISTS
& @aconnect
  @aconnect <object>=<action list>

  Sets the actions to be taken by <object> when a player connects to the game. @aconnects are triggered on connecting players, their locations (if the room_connects @config option is true), their zone object/objects in their zone master room, and objects in the Master Room.

  Note that long and spammy @aconnect messages, whether in your room or on a channel, are frequently found annoying by other players.

  One argument is passed to @aconnect:
  %1 = number of player connections (1 if this is an initial connect)
  
  Example:
    > @aconnect me=+who ; +bbscan

See also: @adisconnect, ACTION LISTS, EVENTS
& @amail
  @amail <object>=<action list>

  Sets the actions to be taken by <object> whenever it receives @mail. Admin-only, and is only triggered if enabled via the amail configuration option.

See also: @mail
& @adescribe
& @odescribe
  @odescribe <object>[=<message>]
  @adescribe <object>[=<action list>]
  
  These attributes contain the message shown to others in the enactor's location when he looks at <object>, and the actions to be taken by <object> when someone looks at it. (See 'help @describe' for the attribute shown to the enactor when he looks at <object>.) When the enactor is inside <object>, the @oidescribe and @aidescribe attributes will be used instead, if set. Please note that using these attributes to show long messages is often found annoying.
  
  Examples:
    > @odescribe Walker=glances at Walker and sniggers.
    > @adescribe me=think %n just looked at you.

See also: look, @describe, @idescribe, ACTION LISTS
& @adestroy
  @adestroy <object>[=<action list>]
 
  The adestroy attribute is triggered when <object> is @destroyed. It can only be set by wizards. Because the attribute is triggered when <object> is @destroyed, not when the object is actually purged from the database, it's possible for <object> to be @undestroyed after the adestroy has run.
  
  Please note that there are no destroy or odestroy attributes.
  
See also: @destroy, @undestroy, EVENTS
& @adisconnect
  @adisconnect <object>[=<action list>]

  Sets the actions to be taken by <object> when a player disconnects from the game. @adisconnects are triggered on disconnecting players, their locations (if the room_connects @config option is true), their zone object/objects in their zone master room, and objects in the Master Room.
 
  Several arguments are passed to @adisconnect:
   %1 = number of remaining connections (0 if a full disconnect)
   %2 = bytes received by the disconnecting descriptor
   %3 = bytes sent by the disconnecting descriptor
   %4 = commands issued by the disconnecting descriptor
   %5 = 1 if the descriptor was hidden on disconnect, 0 otherwise
  
  Example:
  > @adisconnect me = home
 
See also: @aconnect, ACTION LISTS, recv(), sent(), cmds(), EVENTS
& @adrop
& @odrop
& @drop
  @drop <object>[=<message>]
  @odrop <object>[=<message>]
  @adrop <object>[=<action list>]
  
  When <object> is a player or thing, the @drop attribute is shown to whoever drops <object>, and @odrop to others in the location <object> is dropped in. The @adrop attribute is triggered when <object> is dropped.
  
  When <object> is an exit, @drop is shown to objects going through <object>, and @odrop is shown to objects in the exit's destination. @adrop is triggered when someone passes through the exit.
  
  Example:
    > @drop Box=You put the box down gently.
    > @odrop Box=puts the box down gently.
    
    > @odrop South=arrives from the North.
  
See also: drop, empty, ACTION LISTS, VERBS, @success
& @aefail
& @oefail
& @efail
  @efail <object>[=<message>]
  @oefail <object>[=<message>]
  @aefail <object>[=<action list>]
  
  These attributes contain the message shown to someone who fails to enter <object>, the message shown to others when someone fails to enter <object>, and the actions to be taken when someone fails to enter it, respectively.

See also: enter, @enter, FAILURE, ACTION LISTS, VERBS
& @aufail
& @oufail
& @ufail
  @ufail <object>=[<message>]
  @oufail <object>=[<message>]
  @aufail <object>=[<action list>]
 
  Sets the message shown to a player who fails to use an object via the 'use' command (because they don't pass the @lock/use), the message shown to others in the room when a player fails to use <object>, and the actions to be taken by <object> when someone fails to use it, respectively.

  Note that these attributes are @ufail, NOT @ufailure, for TinyMUSH compatibility.
  
  Although the Use @lock also restricts who can trigger $-commands or ^-listens on an object, these attributes will not be triggered for those failures. Instead, the COMMAND_LOCK`* and LISTEN_LOCK`* attributes are triggered. See 'help failure' for more information.
  
See also: use, @use, FAILURE, ACTION LISTS, VERBS
& @afailure
& @ofailure
& @failure
  @failure <object>[=<message>]
  @ofailure <object>[=<message>]
  @afailure <object>[=<action list>]

  @failure contains the message shown to someone who fails to pass <object>'s Basic @lock. @ofailure contains the message shown to others, and @afailure contains the actions to be taken by <object>.
  
  For players and things, this means failure to get/take. For exits, it means failure to go through the exit. For rooms the lock is checked when objects "look" inside the room, though failure to pass the lock does not prevent the object from looking.

See also: get, move, @lock, ACTION LISTS, VERBS, @success
& @follow
& @ofollow
& @afollow
  @follow <object>[=<message>]
  @ofollow <object>[=<message>]
  @afollow <object>[=<action list>]
  
  Sets the message shown to someone who begins following <object>, the message shown to others in the room, and the actions to be taken by <object> when someone begins following it, respectively. The name of the person following <object> is automatically prepended to the @ofollow message.

See also: follow, unfollow, @unfollow, followers(), ACTION LISTS, VERBS
& @unfollow
& @ounfollow
& @aunfollow
  @unfollow <object>[=<message>]
  @ounfollow <object>[=<message>]
  @aunfollow <object>[=<action list>]
  
  Sets the message shown to someone who stops following <object>, the message shown to others in the room, and the actions to be taken by <object> when someone stops following it, respectively. The name of the person stopping following <object> is automatically prepended to the @ounfollow message.

See also: follow, unfollow, @follow, followers(), ACTION LISTS, VERBS
& @ahear
& @amhear
& @aahear
  @ahear <object>[=<action list>]
  @amhear <object>[=<action list>]
  @aahear <object>[=<action list>]

  Sets the actions to be taken after the object's @listen is matched. @ahear will only be triggered by sound made by other objects, and @amhear is only triggered by sound made by <object> itself. @aahear will be triggered by all matching sound, regardless of the source.
  
See also: @listen, LISTENING, ACTION LISTS
& @leave
& @oleave
& @oxleave
& @aleave
  @leave <object>[=<message>]
  @oleave <object>[=<message>]
  @oxleave <object>[=<message>]
  @aleave <object>[=<action list>]
  
  These attributes contain the message shown to anyone leaving <object>, the message shown to others inside <object> when someone leaves it, the message shown to others in <object>'s location when someone leaves it, and the actions to be taken by <object> when someone leaves it, respectively.
  
  The leaver's new location is passed in %0, if <object> has permission to see it there.

See also: leave, @oxleave, @lfail, ACTION LISTS, VERBS
& @lfail
& @olfail
& @alfail
  @lfail <object>[=<message>]
  @olfail <object>[=<message>]
  @alfail <object>[=<action list>]

  These attributes contain the message shown to objects who try to leave <object> and fail, the message shown to others inside <object> when someone fails to leave, and the actions to be taken by <object> when someone attempts to leave it and fails.
  
  Such a failure usually occurs because <object> is set NO_LEAVE, or because the person trying to leave does not pass <object>'s @lock/leave.

See also: leave, @leave, NO_LEAVE, locktypes, ACTION LISTS, VERBS
& @alias
  @alias <player>[=<name1>[;<name2>[;...;<nameN>]]]
  @alias <object>[=<string>]
 
  For players and exits, the ALIAS attribute has special meaning: it contains a list of aliases (separated by semicolons) which can be used instead of its name to refer to the player or exit.
  
  Players can only have a limited number of aliases; the number is controlled by the 'max_aliases' @config option. The same rules which apply to player names also apply to aliases, and you cannot use another player's name as your alias (though you can include your own name in your aliases, and can change your name to one of your aliases).
  
  If the 'page_aliases' @config option is on, the first alias in the list is shown along with the player's name when they page others.
  
  Exit aliases used to be a part of their name, though all newly created exits use @alias instead.
 
  For other types of object, @alias has no special meaning.

See also: @name, alias(), fullalias()
& @move
& @omove
& @oxmove
& @amove
  @move <object>[=<message>]
  @omove <object>[=<message>]
  @oxmove <object>[=<message>]
  @amove <object>[=<action list>]
  
  These attributes contain the message shown to <object> immediately after it moves, the message shown to others in the room <object> moves into, the message shown to objects in the location <object> leaves, and the actions to be taken when <object> moves, respectively. Please note that long @omoves are frequently found annoying.

  The <object>'s new location is in %0 and the old location it moved from in %1.

  Example:
   > @move me=You moved! You are now in the room: [name(here)].
   > @omove me=stalks into the room wearing a malevolent expression.
   > @oxmove me=stalks away, glaring.

See also: goto, @oxmove, ACTION LISTS, VERBS
& @aenter
& @enter
& @oenter
& @oxenter
  @enter <object>[=<message>]
  @oenter <object>[=<message>]
  @oxenter <object>[=<message>]
  @aenter <object>[=<action list>]
  
  These attributes contain the messages shown to someone who enters <object>, the message shown to others inside <object> when someone enters it, the message shown to those in <object>'s location when someone enters it, and the actions to be taken by <object> when someone enters it, respectively.
  
  The old location of the entering object is passed in %0, if <object> had permission to see it there.

  Example:
    > @enter Sofa=You sit on the comfy sofa.
    > @oenter Sofa=sits with you on the sofa.
    > @oxenter Sofa=sits down on the sofa. It looks comfy.
    > @aenter Sofa=@pemit/silent owner(me)=%n sat down on [name(me)]!
    
See also: enter, @ealias, leave, ACTION LISTS, VERBS
& @apayment
& @payment
& @opayment
  @payment <object>[=<message>]
  @opayment <object>[=<message>]
  @apayment <object>[=<action list>]
  
  These attributes contain the messages shown to someone who pays <object> pennies with the "give" command, the message shown to others when someone pays <object>, and the actions to be taken by <object> when it's paid. Each attribute is passed the number of pennies paid as %0.

  Example:
    > @payment Collecting Tin=Thank you for your donation!
    > @opayment Collecting Tin=makes a donation to charity.
    > @apayment Collecting Tin=&%# me=%0 at [time()]

See also: give, @cost, buy, MONEY, ACTION LISTS, VERBS
& @atport
& @tport
& @otport
& @oxtport
  @tport <object>[=<message>]
  @otport <object>[=<message>]
  @oxtport <object> [=<message>]
  @atport <object>[=<action list>]

  These attributes contain the message shown to <object> when it is teleported, the message shown to others in the room <object> is teleported to, the message shown to others in the room <object> is teleported from, and the actions to be taken by <object> when it disappears, respectively.
  
  In all of these attributes, %0 is the object which teleported <object>, and %1 is <object>'s old location.
  
  Example:
  > @tport me=name(%0) has teleported you from [name(%1)] to [name(here)].
  > @otport me=appears in a puff of smoke.
  > @oxtport me=disappears in a puff of smoke.
  
See also: @teleport, ACTION LISTS, VERBS
& @atrchown
& @attrchown
  @atrchown <object>/<attribute>=<new owner>
  
  This command changes the ownership of the attribute <attribute> on <object> to <new owner>. You can only @atrchown attributes which you can set. Wizards can @atrchown to any player, while mortals can only @atrchown attributes to themselves. Only players can own attributes; if <new owner> is not a player, <new owner>'s owner is used instead.

See also: @atrlock, @chown, ATTRIBUTES, NON-STANDARD ATTRIBUTES
& @atrlock
& @attrlock
  @atrlock <object>/<attribute>
  @atrlock <object>/<attribute=[on|off]
  
  The first form of this command tells you whether or not the given attribute is locked (whether it has the "locked" attribute flag set).
  
  The second form attempts to lock (for 'on') or unlock (for 'off') the given attribute. You automatically gain ownership of the attribute (as per @atrchown) when you lock it. Locked attributes cannot be altered by anyone but Wizards and the attribute's owner (though the owner may be unable to alter the attribute for other reasons, such as not controlling <object>). You must be able to set an attribute in order to lock it.
  
  If you wish to lock an attribute without gaining ownership, you can set it "locked" with @set <obj>/<attr>=locked - be aware that you'll be unable to make any changes to the attribute after this, including unlocking it!

See also: atrlock(), @atrchown, ATTRIBUTES, NON-STANDARD ATTRIBUTES
& @asuccess
& @success
& @osuccess
  @success <object>[=<message>] 
  @osuccess <object>[=<message>]
  @asuccess <object>[=<action list>]
  
  For players and things, these attributes contain the message shown to someone who picks up <object> with the "get" command, the message shown to others when someone gets <object>, and the actions to be taken by <object> when someone gets it, respectively.
  
  For exits, they contain the message shown to an object passing through the exit <object>, the message shown in the exit's source when someone passes through it, and the actions to be taken by the exit when someone passes through it, respectively.
  
  In all cases, %0 is the dbref of the moving object's original location.
  
  Example:
    > @success Door=You open the door and step inside.
    > @osuccess Door=opens the door and steps inside.
    
    > @success Box=You pick up the box.
    > @osuccess Box=picks up the box.

See also: get, goto, @lock, SUCCESS, FAILURE, @odrop, ACTION LISTS, VERBS
& @attribute
  @attribute <attrib>

  The @attribute command displays and modifies the MUSH's standard attributes (see "@list/attribs" for a list of them).
  
  Since 1.8.5p1, changes to the attribute table are saved across reboots and shutdowns, and don't need to be placed in an @startup.

  The first form of the command displays the full name of the attribute <attrib>, along with the its attribute flags, and the dbref of the object which added it to the attribute table.
  
  Continued in 'help @attribute2'.
& @attribute2
  @attribute/access[/retroactive] <attrib>=<flag list>
  @attribute/delete <attrib>
  @attribute/rename <attrib>=<new name>
  @attribute/decompile[/retroactive] [<pattern>]
  
  @attribute/access adds <attrib> as a new standard attribute, with the default attribute flags <flag list>. If <attrib> is already a standard attribute, this command modifies its default attribute flags. Use "none" for <flag list> if you don't want any default attribute flags.
  
  If the /retroactive switch is given with /access, all existing copies of the attribute will be @atrchown'd to the player running the command, and will have its flags changed to <flag list>.
  
  @attribute/delete removes a standard attribute from the table.
  @attribute/rename renames a standard attribute. 
  
  Only Wizards can modify the attribute table.
  
  @attribute/decompile prints out a list of @attribute/access commands needed to recreate the attribute table on another MUSH. If /retroactive is given, that switch will be included in the output. If <pattern> is given, only attributes matching <pattern> are decompiled.
  
  Continued in 'help @attribute3'.
& @attribute3
  @attribute/limit <attrib>=<regexp pattern>
  @attribute/enum [<delim>] <attrib>=<list of choices>

  @attribute/limit lets you restrict all _new_ values for an attribute to those that match a regexp pattern. Case insensitive. (Use (?-i) to make your regexp case-sensitive.)

  @attribute/enum lets you restrict all _new_ values for an attribute to match an item in a list. It will also perform partial matching on the list, much like a grab. Delimiter is optional, and defaults to a space.

  Examples:

    @attribute/enum sex=male female   <-- requires 'male' or 'female' as @sex
    @attribute/enum | race=Wookie|Indy 500 <- Your race can be 'wookie' or 'Indy 500'
    @attribute/limit score=^\\d+$    <-- @score can only contain digits. (Remember, Penn's parser eats a \)

See also: ATTRIBUTES, attribute flags, @set, @atrchown,
  @atrlock, @list
& @ause
& @use
& @ouse
  @use <object>[=<message>]
  @ouse <object>[=<message>]
  @ause <object>[=<action list>]
  
  These attributes contain the message shown to someone who successfully uses <object>, the message shown to others when someone uses <object>, and the actions to be taken by <object> when it is used, respectively.
  
  Note that, if <object> has a CHARGES attribute set and it does not contain a number greater than 0, the RUNOUT attribute is triggered instead of the AUSE attribute. See 'help @charges' for more information.
  
  Example:
    > @use Jack-In-The-Box=You wind the handle.
    > @ouse Jack-In-The-Box=winds the handle.
    > @ause Jack-In-The-Box=@wait 3=POSE pops up with a bang!
    > use Jack-In-The-Box
    
See also: use, @charges, @runout, ACTION LISTS, VERBS
& @away
  @away <player>[=<message>]

  If <message> evaluates to something non-null, it will be shown to anyone who pages <player> when she is not connected.
  
  Example: 
    > @away me=I'm not here, please send me @mail instead.

See also: @idle, @haven
& @boot
  @boot[/silent] <player>
  @boot/port[/silent] <descriptor number>
  @boot/me

  The first form of this command disconnects all of <player>'s connections from the game.
  
  The /port switch disconnects a particular descriptor (as shown under "Des" in the Wizard WHO, returned by lports() and ports(), etc).
  
  If the /silent switch is given, the message telling <player> he was booted is suppressed.

  The /me switch boots all descriptors for the player using the command which have been idle for over 1 minute. Players can use this command to terminate hung connections.

  Only admin and those with the "boot" power can @boot other players.

See also: QUIT, LOGOUT
& @break
& @assert
  @break[/queued] <boolean>[=<action list>]
  @assert[/queued] <boolean>[=<action list>]

  @break stops the execution of further commands in the current action list if <boolean> is a true value. It doesn't affect new queue entries made by previous commands in the action list. It can be useful for doing error checking without having to nest @switches and suffer from delayed execution because of queueing.
  
  If <action list> is given, it is executed instead of the rest of the commands in the current action list. By default, <action list> is run immediately, replacing the rest of the action list @break was called in. If the /queued switch is given, <action list> will instead be queued to be run later. @break also accepts an /inline switch, for Rhost compatability; this switch does nothing on PennMUSH.

  @assert does the inverse: it stops execution if <boolean> evaluates to false.

  See 'help @break2' for examples.
See also: ACTION LISTS, QUEUE, BOOLEAN VALUES, @switch, @if
& @break2
& @assert2
  Examples:
  > @va obj=$testme *: @pemit %#=You try a test ; @break lt(%0,10)=@pemit %#=But you're too low! ; @pemit %#=And you succeed!
  > testme 0
  You try a test
  But you're too low!
  
  > testme 10
  You try a test
  And you succeed!

  > @force me={@switch 1=1, think Third; think First; @break 1; think Second}
  First
  Third
  (The @switch is run, which queues 'think Third', think First is run, displaying 'First', command execution is broken (so we never think Second), and then the queued 'think Third' is run, displaying Third. If you figured that out, you have a very good understanding of the PennMUSH queue. :)
& @charges
& @runout
  @charges <object>[=<integer>]
  @runout <object>[=<action list>]

  These attributes can limit how many times an object can be successfully "use"d. When you "use" an object with a CHARGES attribute set, the object's AUSE attribute is only triggered if CHARGES is a positive integer. When CHARGES is less than 1 (or not a number), the object's RUNOUT attribute is triggered instead.
  
  When the CHARGES attribute is present and AUSE is triggered, the value of the CHARGES attribute is automatically decreased by 1. When no CHARGES attribute is set, AUSE is always triggered.
  
  See 'help charges2' for an example.

See also: use, @ause, ACTION LISTS
& charges2
& runout2
  
  Example:
    > @create Revolver
    > @use Revolver=You pull the trigger.
    > @ouse Revolver=pulls the trigger.
    > @charges Revolver=6
    > @ause Revolver=POSE fires into the air.
    > @runout Revolver=POSE clicks, but is out of bullets.
    
    > use revolver
    You pull the trigger.
    Revolver fires into the air.
    > ex revolver/charges
    CHARGES [#6$]: 5
    
  The next 5 "use revolver"s work the same way, decrementing CHARGES each time.
  
    > ex revolver/charges
    CHARGES [#6$]: 0
    > use revolver
    You pull the trigger.
    Revolver clicks, but is out of bullets.
    > ex revolver/charges
    CHARGES [#6$]: 0
& @chown
  @chown[/preserve] <object>=<player>
  @chown <object>/<attribute>=<player>

  Changes the ownership of <object> to <player>. You can chown things, rooms or exits. Players can't be @chown'd - they always own themselves. To chown a thing, you have to be carrying it. If you do not own an object, you can only chown it if it has the CHOWN_OK flag and you pass its @lock/chown. If you're not a Wizard, you can only @chown objects to yourself or a Zone Master whose zone-lock you pass.

  Normally, @chown'ing an object clears privileged flags and powers, and sets the object halt. Wizards can use @chown/preserve to avoid this. Doing this to an active object with queued commands is not recommended, and may have strange and insecure effects.
  
  If /<attribute> is specified, it acts as an alias for @atrchown; see 'help @atrchown' for details.

  Examples:
    > @chown here=me (for a room)
    > @chown box=Soundwave (for a thing)

See also: CHOWN_OK, Zone Masters, @chownall, owner(), @atrchown
& @chownall
  @chownall[/preserve][/<types>] <player>[=<new owner>]

  This command @chowns all objects currently owned by <player> to the player <new owner>, or to the person running the command if no <new owner> is given. All the objects will have privileged flags and powers cleared, and be set halt, unless the /preserve switch is given.
  
  If one or more of /things, /rooms or /exits are provided, only objects of the given types are chowned. Otherwise, all objects are chowned.
  
  This command can only be used by Wizards.

See also: @chown
& @chzone
  @chzone[/preserve] <object>=<zone> 
  @chzone <object>=none

  The first form of this command changes the zone of <object> to <zone>. This puts the object on that zone and may (if the zone_control_zmp_only @config option is off) allow anyone who passes the Zone @lock of <zone> to control <object>. Any kind of object can be @chzoned, and any kind of object can be used as a zone.

  The second form of this command removes <object> from its current zone, leaving it unzoned.

  If a player is @chzoned, any objects he creates from that point on will automatically be on the same zone. Objects the player already owns are not affected.
  
  You must control <object>, and either control <zone> or pass its @lock/chzone. 

  Continued in 'help @chzone2'.
& @chzone2
  To see the Zone of an object, you can use either 'brief' or 'examine' to examine it. The Zone is listed on the same line as the Owner of the object.

  If <zone> does not have a Zone @lock when something is @chzoned to it, the lock is automatically set to =<zone> (see 'help @lock' for more info).

  Whenever an object besides a player is @chzoned to a zone object, the WIZARD, ROYALTY, and TRUST flags will be reset, as will all @power's (for security purposes). For similar reasons, it is strongly recommended that you do not @chzone admin- or wizard-owned objects to any zone that less privileged players have access to. Wizards can use the /preserve switch to prevent this reset.

See also: ZONES, @chzoneall, zone()
& @chzoneall
  @chzoneall[/preserve] <player>=<zone object>

  Changes the zone of all objects owned by <player> to <zone object>. If <zone object> is "none", the zone is reset to NOTHING. Only wizards may use this command.
  
See also: @chzone, ZONES
& @clone
  @clone <object>[=<new name>[, <dbref>]]
  @clone/preserve <object>[=<new name>[, <dbref>]]

  This command creates a copy of <object>. The clone will have the same name as the original unless a <new name> is given for it. You can only clone things, rooms and exits, not players. You must control <object>. The new object will be owned by the player who performs the @clone, not the owner of the original <object>.
  
  When cloning things and exits, the clone will be placed in your current location, not the location of <object>. When cloning rooms, the exits and contents in the room are not cloned as well.

  The cloned object will have the same modification time as the original object, to make tracking revisions easier, but will have a different creation time.
  
  Normally, the Wizard and Royalty flags, @powers and @warnings are stripped from the cloned object, but Wizards may use the /preserve flag to prevent this.
  
  The clone will normally be created with the first available dbref, but Wizards and objects with the pick_dbref power may specify the <dbref> of a garbage object to use that instead.

  To clone a room and all its exits, use code like:
    > @teleport setq(0,%L)[clone(here)]
    > @dolist lexits(%q0)=@clone ##

See also: @create, clone(), create(), @cpattr
& @command
  @command <command>
  @command/<switch> <command>
  @command/alias <command>=<alias>
  @command/clone <command>=<clone>
  @command/restrict <command>=<restriction>

  @command can be used for adding new built-in commands, altering the way a built-in command works, and displaying information about how commands currently work.

  With no switches, @command shows all sorts of interesting information about how a command is parsed. Any player can use @command with no switch, while the switches are Wizard-only.
  
  The /alias switch creates an alias for <command>, allowing players to type <alias> to run <command>. The /clone switch creates a separate copy of <command>, which works the same initially but can be restricted, @hooked, etc, separately.

  @command/restrict can be used to restrict who can use <command>. See 'help restrict' for more information.

  Switches include:
  /add     : Add a new command that does nothing, but can be @hook'd.
  /delete  : Delete a command added with @command/add or /alias. God only.
  /disable : Disable a command added in the hardcode.
  /enable  : Re-enable a command disabled with @command/disable.

  The /quiet switch can be used to suppress output from @command.

  Continued in 'help @command2'.
& @command2
  @command/add is a powerful tool that lets you create new commands which are matched before normal $-commands, and which can be set not to parse their arguments, but (via @hook) can still execute softcode like an $-command.

  You can use these additional switches, along with @command/add, to control how the new command parses its arguments:

  /noparse   : The command does not evaluate the leftside arg(s).
  /eqsplit   : The parser parses leftside and rightside around =
  /lsargs    : Comma-separated arguments on the left side are parsed.
  /rsargs    : When used with /eqsplit, the right-side arguments are comma-separated and are parsed individually
  /rsnoparse : The command does not evaluate the rightside arg(s).

  Any command added with neither /noparse or /rsnoparse is provided with a /noeval switch automatically, so if you @command/add foo, then foo's arguments are parsed by default, but you can call foo/noeval. Note: when you @hook/override foo, its $-command pattern must be able to match "foo/noeval" as well for the switch to actually be used.

  Commands added with @command/add, like other standard commands, are always case-insensitive. Commands can also be added in the alias.cnf file.

  See 'help @command3' for examples.
See also: @hook, RESTRICT, EVALUATION ORDER
& @command3
  Examples:
    > @create Dining Machine
    > &eat dining=$eat *:@remit %L=%n takes a bite of %0.
    > @command/add/noparse eat
    > @hook/override eat=dining machine,eat
    > eat meat loaf
    Walker takes a bite of meat loaf.
    > eat randword(apple tomato pear)
    Walker takes a bite of randword(apple tomato pear)

    > &drink dining=$^drink(/noeval)? (.*)$:@remit %L=%n drinks %2.
    > @set dining/drink=regexp
    > @command/add drink
    > @hook/override drink=dining machine,drink
    > drink reverse(tea)
    Walker drinks aet.
    > drink/noeval reverse(tea)
    Walker drinks reverse(tea).
& @comment
  @comment <object>[=<comment>]

  This is a wizard-only command which sets a COMMENT attribute on <object>. The attribute can only be seen by those with the See_All power.
  
See also: @@, @@()
& @config
  @config
  @config [<category>|<option>]
  @config/set <option>=<value>
  @config/save <option>=<value>
  
  With no arguments, @config lists the categories of configuration options for the MUSH. With an argument, @config lists the options in the given <category>, or shows the current value of the given <option>.
  
  The wizard-only /set switch changes the value of <option> to <value>. This change does not last across reboots. God can also use the /save switch, which attempts to save the new <value> in the mush.cnf configuration file, as well as changing it in-game.

  For information about parameters, see 'help @config parameters'
& @conformat
  @conformat <object>[=<format>]

  When set, the CONFORMAT attribute is evaluated when <object> is looked at, and the result is displayed instead of the usual "Contents:" (for rooms) or "Carrying:" (for players and things) list of contents.
  
  The dbrefs of the objects which would appear in the normal contents list are passed to the attribute as %0 (you can use lcon(me) for a full contents list). A list of the names of these objects as they would appear in the default contents list is passed as %1, |-delimited.

  Q-registers (set via setq() and similar functions) are inherited from the @descformat, and passed on to the @exitformat.

  Examples:
    Show the normal contents list, but in upper-case:
    > @conformat here=edit(ucstr(%1), |, %r)
    
    Show just the object names (with no ansi) in a table:
    > @conformat here=table(iter(%0, name(%i0), %b, |), 20, width(%#), |)

See also: look, @exitformat, @nameformat, @descformat, @invformat,
    @idescformat
& @include
  @include[/<switches>] <object>/<attribute>[=<arg1>,<arg2>,...]

  @include inserts the contents of the attribute provided into the action list in-place, without adding a new queue entry. It is useful to avoid having to copy the same code into multiple commands. The attribute to be included must be visible to the enactor.

  Example:
    &CHECKS me=@assert [orflags(%#,Wr)]; @break [gt(words(lwho()),%0)]
    &CMD1 me=$cmd *: @include me/CHECKS; @pemit %#=You passed.
    &CMD2 me=$othercmd *: @include me/CHECKS; @@ Do something else...

  When including attribute contents, @include ignores any ^...: or $...: at the start, so the CHECKS attribute above could also be written like this, to allow for "unit testing":

    &CHECKS me=$testchk *: @assert [orflags(%#,Wr)]; @break [gt(words(lwho()),%0)]
 
  The including environment (%0-%9) is available to the included actions. If arguments are provided to @include, they are substituted for the environment's %0, %1, etc. while the included action list is running. The environment is then restored after the @include. 
  
  Continued in 'help @include2'.
& @include2
  
  @include takes the following switches to alter its behaviour:
  /nobreak:   Prevents an @break/@assert in the included attribute from breaking the including action list.
  /localize:  Saves all q-registers before including the attribute, and restores them after including the attribute.
  /clearregs: Clears all q-registers before including the attribute.
  
See also: @trigger, ufun(), @break
& @invformat
  @invformat <object>[=<format>]

  When set, this attribute is evaluated and displayed instead of the usual "You are carrying:" list of objects when <object> uses the "inventory" command. The list of objects that would normally appear in the inventory is passed as %0, and a list of the names as they would appear in the default display, |-delimited, is passed as %1.

  Example:
    > @invformat me=You're holding: [itemize(iter(%0, name(%i0), %b, |), |)]
    > inventory
    You're holding: Red Ball, Pickle, and Piano
 
See also: inventory, @conformat, @exitformat, @nameformat, @descformat, @idescformat
& @descformat
  @descformat <object>[=<format>]

  When set, this attribute is evaluated and displayed instead of <object>'s @describe, when someone looks at <object>. The evaluated @describe, which would be shown if no @descformat were set, is passed to the @descformt as %0; use v(describe) to get the unevaluted description.
  
  This is primarily useful for room parents, to enforce a consistent look for all rooms without having to apply formatting to ever @describe. Note that this object is only used with @describe - to format the @idescribe, use @idescformat.
  
  Q-registers (set via setq() and similar functions) are inherited from the @nameformat, and passed on to the @conformat.
  
  Example:
    > @descformat Room Parent=repeat(=, width(%#))%r%0[repeat(=, width(%#))]

See also: look, @exitformat, @nameformat, @conformat, @idescformat, @invformat
& @idescformat
  @idescformat <object>[=<format>]

  When set, this attribute is evaluated and displayed instead of <object>'s @idescribe, when someone looks at <object> while inside it. The evaluated @idescribe, which would be shown if no @idescformat were set, is passed to the @idescformt as %0; use v(idescribe) to get the unevaluted description.
  
  Note that this attribute is only used when an @idescribe is set. When no @idescribe is set, the @descformat (and @describe) attributes are used, even when someone "look"s inside <object>.

  This is useful for things like object parents that enforce a consistent "look" for each object's @idescribe, without having to place formatting into every @idescribe.
  
  Q-registers (set via setq() and similar functions) are inherited from the @nameformat, and passed on to the @conformat.

  Example:
    > @idescribe Vehicle Parent=repeat(*, width(%#))%r%0

See also: look, @exitformat, @nameformat, @conformat, @descformat, @invformat
& @nameaccent
  @nameaccent <object>[=<accent template>]

  When this attribute holds an accent template that is the same length as <object>'s @name, it is used to change the object's name in some situations (how it shows up in speech, look, and a few other commands). This allows for accented names without having to use the accented characters directly in a name, which can make it harder for people to type.
  
  The <accent template> is explained in 'help accents'.

  If a container has both a @nameaccent and a @nameformat, the @nameformat is used.

See also: accent(), @nameformat, accname(), stripaccents(), iname()
& @nameformat
  @nameformat <object>[=<format>]

  When set, this attribute is evaluated and displayed in place of <object>'s name, when objects inside <object> "look". The room's dbref is passed as %0, and the default-formatted name (as it would be displayed with no @nameformat set) is passed as %1.
  
  @nameformat is not used when people who are outside the object look at it.
  
  Q-registers (set via setq() and similar functions) are passed on from the nameformat to the other @*format attributes used for formatting "look" output. Use localize() if you don't want this behaviour.
  
  Example:
    Show the room's zone after its name.
    > @nameformat here = %1 [if(zone(%0),<[name(zone(%0))]>)]

See also: look, @exitformat, @conformat, @descformat, @nameaccent, @invformat, @idescformat, iname()
& @cost
  @cost <object>[=<amount>]
  
  The COST attribute contains the number of pennies that must be given to <object> to trigger its @pay/@opay/@apay attributes. If less than this amount is given, the money will be refused, and if more is given, the difference is refunded.
  
  This attribute is evaluated, with the amount being given passed as %0. If the attribute returns a number less than 0, the money will be refused. Non-players must have this attribute set in order to receive pennies. Players who don't have a COST always accept the amount of pennies given.

  Example:
    > @cost Exit Machine=10
    > @apay Exit Machine=@open %n-exit 
    > @pay Exit Machine=Your exit has been created.
 
    > give Exit Machine=10
    Your exit has been created.
    (The exit will also have been opened by the machine.)

    > @cost charity=%0
    > @pay charity=Thanks for your donation of %0 [money(%0)].

See also: give, MONEY, @pay, money(), buy
& @cpattr
& @mvattr
  @cpattr[/noflagcopy] <obj>/<attr>=<obj1>[/<attr1>][, ..., <objN>[/<attrN>]]
  @mvattr[/noflagcopy] <obj>/<attr>=<obj1>[/<attr1>][, ..., <objN>[/<attrN>]]
  
  @cpattr copies the <attr> attribute from <obj> to <obj1> (and any other objects given). By default, the new attributes will have the same name as the original, but you can specify a different name to be used on each object if you wish.
  
  @mvattr works the same, but also attempts to remove the original attribute after copying it.
  
  Attribute flags are copied as well, unless the /noflagcopy switch is given. This is recommended when copying from a non-standard attribute to a standard one.

  Example:
    > @cpattr box/test=box/test1, cube/random, tribble/describe
  would check the object "box" for an attribute named TEST and then copy it to the attributes TEST1 on "box", RANDOM on the object named "cube", and DESCRIBE on the object named "tribble".

    > @cpattr box/test=cube
  would copy the TEST attribute from "box" to TEST on "cube".

See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES, @set
& @create
  @create <name>[=<cost>[,<dbref>]]

  This command creates a new thing called <name>. Creating an object costs a certain number of pennies (see '@config object_cost'); you can specify a higher cost if you wish. This cost is refunded to you when the object is destroyed.

  Some MUSHes choose to limit the number of objects you can create by setting a quota.
  
  Wizards and objects with the pick_dbref power can also specify the <dbref> of a garbage object to use when creating the object. Otherwise, the object is given the next available dbref.
 
See also: give, @quota, MONEY, @clone, create(), @dig, @open, @pcreate
& @dbck
  @dbck
  
  This is a wizard only command. It forces the database to perform a series of internal cleanup and consistency checks that normally run approximately every 10 minutes:

  1. For every object, make sure its location, home, next, contents, parent, and zone fields are valid objects.
  2. Check for disconnected rooms that aren't set FLOATING
  3. For every exit, player, or thing, make sure there is exactly one way to reach it from a room by following the contents fields of non-exits, the next fields of non-rooms, and the exits fields of rooms.
  4. For every thing or player, make sure that it is in the contents list of its location. Make sure every exit is in the exits list of its location.
  5. Check that objects being used as zones have a @lock/zone.

  @dbck no longer performs an @purge. The results of @dbck are written to the game's error log, and not reported to the Wizard.

& @decompile
  @decompile[/<switches>] <object>[=<prefix>]
  @decompile[/<switches>] <object>/<attribute patterns>[=<prefix>]

  @decompile outputs a list of the commands that you would have to enter in order to recreate <object>. Useful for either copying objects from one MUSH to another, or for making logs of important objects to protect against an accidental @nuke or a crash.

  All output lines are prefixed with <prefix>, if one is given. This is useful for creating client-side scripts for editing code.

  You can either @decompile an entire object, or just certain parts of it. To @decompile just a few attributes, for example, you could type:

      @decompile <object>/<attribute pattern> [ ... <attribute patternN>]

  including each attribute. Attribute patterns can be wildcards.

  Continued in 'help @decompile2'.
& @decompile2
  @decompile takes the following switches, which can be combined:

  @decompile/name
    This switch causes @decompile to use the object's name, instead of its dbref. This is the default.
  @decompile/db
    This switch makes @decompile use the object's dbref instead of its name, which is useful for editing code off-MUSH.
  @decompile/flags
    Only the code to @create the object and set flags/powers/locks is printed. When an <attribute pattern> is given, this switch is ignored, and @decompile only prints the matching attributes.
  @decompile/attribs
    Only the code to set the object's attributes is printed. Same as @decompile <object>/**
  @decompile/skipdefaults
    Don't output commands to set attribute flags if those flags are the defaults for that attribute on that MUSH.
  @decompile/tf
    Explained in 'help @decompile3'.
  
  Continued in 'help @decompile3'.
& @decompile3

  @decompile/tf <object>[/<attribute>]

  The /tf works the same as if you'd typed:
    @decompile/db <obj>[/<attrs>]=[default(me/TFPREFIX, FugueEdit >%b)]
    
  with the exception that @decompile/tf does not include commands for setting attribute flags. If you have a TFPREFIX attribute set, the (unevaluated) contents of that attribute is used as the prefix. Otherwise, the string "FugueEdit > " is used. It's useful for automatically copying @decompile output into your client to alter. It is highly recommended that you set a TFPREFIX attribute, to prevent others from maliciously placing code in your client's command line.

  To set up @decompile/tf:
  
    In TinyFugue:
      /def -ag -mglob -p100 -t"FugueEdit > *" fe = /grab %-2

    In SimpleMU:
      Set your Options -> Grab Password
      @set me=tfprefix:<grabpassword>FugueEdit >%b

See also: CLIENTS, ATTRIBUTES, WILDCARDS, MUSHCODE
& @describe
& @desc
  @describe <object>[=<description>]

  This command sets the description of the object, which will be seen whenever something looks at the object with the 'look' command. Every object should have a description, even if just a short one describing its purpose. When looking at a thing, player or exit which has no description, you will see the message "You see nothing special.". A room with no desc set shows nothing.

  The description can be formatted using the @descformat attribute. This is particularly useful for @parents and ancestors.
  
  When inside a thing or player, you will see its @idescribe instead, if one is set.

  @describe can be abbreviated as @desc.

See also: look, @adescribe, @idescribe, @descformat
& @destroy
& @recycle
& @nuke
  @destroy[/override] <object>
  @nuke <object>
  @undestroy <object>

  The @destroy command marks <object> for destruction by setting the GOING flag on it. If <object> is a room, all the exits in the room are marked for destruction as well. If <object> is a player, and the @config option destroy_possessions is on, everything he owns is marked for destruction as well. (If really_safe is also on, his SAFE objects will not be destroyed.) If the adestroy @config option is on, the ADESTROY attribute will be triggered when the object is first @destroy'd.
  
  The MUSH checks for GOING objects every ten minutes or so (see '@config purge_interval'); each one is set with the GOING_TWICE flag, and will be destroyed totally on the next cycle. You can save it from destruction during this period using the @undestroy command, or @destroy it again to destroy it instantly.
  
  When an object is destroyed, any commands, @waits and semaphores it has queued are drained, and the object's owner has the quota for the object, and the initial cost of creating it, refunded.
  
  Continued in 'help @destroy2'.
& @destroy2

  To destroy an object, you must either control it, control its source or destination room (for exits), or it must be set DESTROY_OK and you must pass its @lock/destroy.
  
  To destroy objects set SAFE, you must use @destroy/override or @nuke. If the really_safe @config option is on, even @nuke can't destroy SAFE objects, and you must clear the safe flag first.
  
  Players can only be @destroyed when they are not connected, and even then can only be destroyed by a Wizard player. If the destroy_possessions @config option is on, anything the player owns is @destroyed. If the really_safe option is also on, his SAFE possessions are @chown'd to God instead. If the option is off, all their possessions are @chown'd to God.

  @recycle is an alias for @destroy. Some MUSHes disable @destroy and only use @recycle, to avoid players mistyping.
  
See also: @undestroy, @create, @dig, @open, DESTROY_OK, SAFE
& @undestroy
& @unrecycle
  @undestroy <object>
  
  When an object has been marked for destruction using @destroy, this command spares it from destruction. <object>'s @startup is triggered when it is spared.
  
  @unrecycle is an alias for @undestroy.
  
See also: @destroy, GOING, @startup
& @dig
  @dig[/teleport] <room name>[=<exit to>, <exit from>, <room dbref>, <to dbref>, <from dbref>]
  
  This command creates a new room named <room name>. Creating a room costs some pennies (see '@config room_cost' for exactly how many). If the /teleport switch is given, you will be teleported to the room after it's created, as per the @teleport command.
  
  If <exit to> is given, the MUSH will automatically open an exit from your current location to the new room named <exit to>, if you have permission. You can also specify <exit from>, to create an exit from the new room back to your current location. Opening exists also costs pennies; see '@config exit_cost'. The exit names may contain multiple aliases, separated with semicolons, as per 'help @name'.

  Wizards and objects with the pick_dbref power can also specify the dbrefs of garbage objects to use when creating the room and the to and from exits.
  
  See 'help @dig2' for examples.
& @dig2
  Examples: 
    > @dig Kitchen
  This command will create a new room named 'Kitchen'. You will be informed what the dbref of this room is.

    > @dig Kitchen=Kitchen <N>;n;north;kitchen;k
  This will create the room as above, and also open an exit leading to it named "Kitchen <N>" with the aliases n, north, kitchen and k. It will NOT create an exit coming back from the Kitchen room.

    > @dig Kitchen=Kitchen <N>;n;north;kitchen;k, Out <S>;s;south;out;o
  This will do just the same as the above, except it will also create an exit named "Out <S>" with the aliases s, south, out and o coming back from the kitchen to whatever room you are currently in.

See also: @open, @link, EXITS, @create, DBREF, dig()
& @doing
  @doing <object>[=<message>]

  With a <message> argument, this command sets <object>'s DOING attribute to <message>. The DOING attribute is only meaningful for players; the evaluated result is shown on the output of the normal MUSH WHO command, and on the login screen WHO.
  
  With no <message> the attribute is cleared.
  
  To change the message shown above player @doings in WHO, use @poll.

See also: @poll, WHO, doing()
& @dolist
  @dolist[/<switches>][/notify][/delimit <delim>] <list>=<action list>
  
  @dolist queues the <action list> for execution once for each element in <list>. <list> is space-separated, unless the /delimit switch is given, in which case it is a <delim>-separated list.
  
  The %i0 substitution, or the function itext(0), can be used in the <action list> to get the current element of the <list>, and the inum(0) function returns the position of the current element. ilev() returns the nesting depth of @dolists. The %iL substitution returns the itext() for the outermost @dolist, and is equivilent to itext(ilev()).
  
  For backwards compatability, the string "##" is also replaced with the current element of the list, and "#@" the current position. However, these replacements occur BEFORE evaluation, which means that they always return the values for the outermost @dolist, and are thus unsuitable for nesting. It also makes them unsafe for use on user-input or strings which may contain special characters; using the %i* sub or itext() instead is very strongly recommended.

  Continued in 'help @dolist2'.
& @dolist2

  If the /notify switch is given, the command "@notify me" is queued after all copies of <action list> have been queued. This is useful for object synchronization with semaphores.

  If the /inline switch is given, @dolist will run the new action lists instantly, instead of queueing them to be run later.

  When using @dolist/inline, an @break in an <action list> will stop the calling action list (and any further <action list>s) from running. Each <action list> will also be able to see/alter the q-registers for the calling action list. The following switches can be used with /inline to alter this behaviour:
   /nobreak:  @breaks in <action list> do not effect to the calling action list
   /localize: q-registers are saved before each <action> is run, and restored after it completes
   /clearreg: q-registers are all reset before each <action> is run. Most useful when used in combination with /localize.
              
  @dolist/inplace is an alias for @dolist/inline/nobreak/localize.

  See 'help @dolist3' for examples.
See also: iter(), itext(), map(), @notify, SEMAPHORES, ACTION LISTS
& @dolist3

  Examples:
    > @dolist a b c=say %i0 is number [inum(0)]
    You say, "a is number 1"
    You say, "b is number 2"
    You say, "c is number 3"

   > &test me=$test: say Starting ; @wait me={say Done} ;
                     @dolist/notify a b c=say %i0 is [inum(0)]
   > test
   You say, "Starting"
   You say, "a is 1"
   You say, "b is 2"
   You say, "c is 3"
   Notified.
   You say, "Done"
   
   > @dolist a b c=@dolist 1 2 3=say %iL/%i0
   You say, "a/1"
   You say, "a/2"
   You say, "a/3"
   You say, "b/1"
   You say, "b/2"
   You say, "b/3"
   You say, "c/1"
   You say, "c/2"
   You say, "c/3"

& @drain
  @drain[/any][/all] <object>[/<attribute>][=<number>]
  
  This command discards commands waiting on a semaphore without executing them. (For non-semaphore queues, use @halt or @halt/pid.)

  If the /any switch is given, then all semaphores associated with <object> are @drained. Otherwise, only the specified semaphore attribute (or SEMAPHORE if no <attribute> is specified) is @drained.

  If the /all switch is given, then all queue entries associated with the selected semaphore(s) are discarded, and the semaphore attribute(s) are cleared. Otherwise, only the indicated <number> of queue entries are discarded. If no <number> is given, then the /all switch is assumed.

  You may not specify both the /any switch and a specific attribute. Similarly, you may not specify both the /all switch and a number.

See also: SEMAPHORES, @wait, @notify, @halt
& @dump
  @dump
  @dump[/paranoid|/debug|/nofork] [<check interval>]
 
  This is a wizard-only command which saves a copy of the database from memory into the outdb file on disk. The MUSH saves the game automatically at a regular interval, controlled by the "dump_interval" @config option.
 
  If the /paranoid switch is given, the game performs additional consistency checking which corrects possible data corruption in the copy of the db written to disk. If a check interval is specified, the game writes confirmation of the dump to the checkpoint log file every <interval> objects. If no interval is specified, it is taken to be the size of the database, divided by 5.
  
  @dump/debug is the same as @dump/paranoid, but also attempts to fix any errors found in the running (in-memory) copy of the database. In order to do this safely, the dump will be a non-forking dump, even if the MUSH is configured to do forking dumps (see "@config forking_dump").

  @dump/nofork does a normal, always non-forking dump.
  
  These switches should ONLY be used if a normal @dump is not being done correctly. They should generally only be done by wizards with access to the account on which the MUSH is running, since others will not have access to the checkpoint log file.

See also: @shutdown
& @ealias
& @lalias
  @ealias <object>[=<enter alias1>[; ... ; <enter aliasN>]]
  @lalias <object>[=<leave alias1>[; ... ; <leave aliasN>]]
  
  These attributes contain lists of "enter aliases" and "leave aliases" for <object> - any of the aliases can be used in place of "enter <object>" and "leave <object>" to enter/leave the object.
  
  These attributes only have meaning for players and things (as rooms/exits cannot be "enter"ed) - the aliases for exits are stored in @alias.
  
  Example:
    > @ealias Chair=Sit down;sit
    > @lalias Chair=Stand up;stand

See also: enter, leave, goto, ENTER_OK
& @edit
& @gedit
  @edit[/first][/check][/quiet] <object>/<attributes>=<search>, <replace> 
  @edit[/check][/quiet] <object>/<attributes>=$, <string to append>
  @edit[/check][/quiet] <object>/<attributes>=^, <string to prepend>

  This command allows you to edit the contents of attributes, without having to retype the entire attribute.
  
  All the attributes on <object> whose names match the wildcard pattern <attributes> will be searched for the string <search>, and each occurrence of it will be replaced with the string <replace>.
  
  If <search> is "$", then <replace> will be added to the end of the attributes. When <search> is "^", <replace> will be added to the beginning of the attributes. (If you need to replace a single $ or ^, consider using @edit/regexp (see help @edit2) or the edit() function.)
  
  If the /first switch is given, only the first occurrence of <search> in each attribute is replaced. If the /check switch is given, the attributes are not altered, you'll just be shown what would be changed (with the changes ansi-highlighted).
  
  If the /quiet switch is given, you won't be shown the modified text, you'll just be told how many of the matching attributes were/weren't edited. Useful when edited a lot of large/spammy attributes.
  
  <search> and <replace> are not evaluated, so you don't need to escape special characters. If either contains commas, however, you may need to wrap the string in {curly braces}.
  
  Continued in 'help @edit2'.
& @edit2
  @edit/regexp[/all][/nocase][/check][/quiet] <object>/<attributes>=<regexp>,<replace>

  When the /regexp switch is given, @edit performs a regular expression replacement, similar to the regedit() function. Normally, only the first match per attribute will be replaced; if the /all switch is given, all possible matches in each attribute are replaced (as per regeditall()).
  
  Regexp matches are case-sensitive by default, but the /nocase switch can be given to make them case-insensitive (as per regediti()/regeditalli()).
  
  The /check and /quiet switches work the same as for non-regexp @edits.
  
  Note that, unlike normal @edits, the <replace> for an @edit/regexp WILL be evaluated, once for each replacement made, with the $0 token being replaced with the overall matching text, $1 with the first subexpression, and so on. Named subexpressions are also possible via $<name>.
  
  Example:
  > &foo me=Block of text/Wed Feb 22 22:54:02 2012/#10010
  > @edit/regexp me/foo=^(.+)/([^/]+)/(#[0-9]+(?::[0-9]+)?)$, ucstr($1) -- [convtime($2)] -- [name($3)]
  FOO - Set: BLOCK OF TEXT -- 1329951242 -- Minion
  
  Replace a literal '^' with 'v'
  > @edit/regexp me/bar=\^, v
  
See also: edit(), regedit(), ATTRIBUTES,
& @elock
& @eunlock
  @elock <object>[=<key>]
  @eunlock <object>
  
  @elock sets the Enter @lock for <object> to <key>, or clears the the lock if no <key. is given. @eunlock removes the Enter @lock for <object>.
  
  @elock and @eunlock are deprecated and uses of them should be replaced by
    @lock/enter <object>[=<key>]
  and
    @lock/enter <object>

See also: @lock, locktypes, enter, ENTER_OK
& @emit
& \
  @emit[/<switch>] <message>
  \<message>

  This sends <message> to everyone in your location. Nothing is added to the message, not even your name. If you have a SPEECHMOD attribute set, it will be evaluated with <message> as %0, and | as %1, and the result will be shown instead of <message> as long as it evaluates to a non-empty string.

  The /noeval switch prevents the MUSH from evaluating <message>. The /spoof switch causes nospoof notifications to show the enactor's dbref instead of the executor's dbref, and requires control over the enactor or the Can_spoof power.

  @emit can be abbreviated "\"

See also: @nsemit, emit(), @pemit, @remit, @oemit, @lemit, @zemit, @cemit, @speechmod, NOSPOOF and SPOOFING.
& @enable
& @disable
  @enable <option>
  @disable <option>

  These wizard-only commands allow for any boolean @config options to be changed (see 'help @config paramaters' for a list).

  @enable <option> is the same thing as @config/set <option>=yes
  @disable <option> is the same thing as @config/set <option>=no

See also: @config
& @zenter
& @ozenter
& @azenter
  @zenter <object>[=<message>]
  @ozenter <object>[=<message>]
  @azenter <object>[=<action list>]
  
  These attributes set the message shown to a player when he enters the zone <object>, the message shown to others in the room the player enters when he enters the zone, and the action to be taken by the zone <object> when the player moves into an area zoned to it.

  Entry into a new zone is said to occur when a player goes from a room not in the zone to a room in the zone. "Room" in this context means the player's absolute room (outermost container), so entering and leaving unzoned objects within a zoned room doesn't trigger these.

  Zone entry is assumed to occur before room entry, so these are triggered before the room's @[oa]enter.

See also: @zleave, ZONES, @zemit, zwho(), VERBS
& @zleave
& @ozleave
& @azleave
  @zleave <object>[=<message>]
  @ozleave <object>[=<message>]
  @azleave <object>[=<action list>]
  
  These attributes set the message shown to a player when he leaves the zone <object>, the message shown to others in the room he left when leaving the zone, and the actions to be taken by <object> with a player leaves an area zoned to it.

  Leaving a zone is said to occur when a player goes from a room in the zone to a room not in the zone. "Room" in this context means the player's absolute room (outermost container), so entering and leaving unzoned objects within a zoned room doesn't trigger these.

  Zone leaving is assumed to occur after room leaving, so these are triggered after the room's @[oa]leave.

See also: @zenter, ZONES, @zemit, zwho(), VERBS
& @entrances
  @entrances[/<switch>] [<object>][=<begin>[, <end>]]
  
  This command will show you all objects linked to <object>. If you don't specify an <object>, your current location is used. You can limit the range of the dbrefs searched by specifying <begin> and <end>.
  
  You can use any combination of switches to limit the types of objects:
    /exits       show only exits linked to <object>
    /things      show only things which have their homes in <object>
    /players     show only players who have their homes in <object>
    /rooms       show only rooms which have a drop-to of <object>
    
  If you control <object>, or have the Search or See_All powers, all objects linked to <object> are listed. Otherwise, only objects which you can examine will be shown.
    
See also: @link, @search, entrances()
& @exitformat
  @exitformat <object>[=<format>]

  When set, the exitformat attribute is evaluated and shown in place of the "Obvious exits" list for a room. (It has no meaning when set on other types of object.) The dbrefs of the exits which would appear in the default "Obvious exits" list is passed to the attribute as %0 as a space-separated list; you can use lexits(me) to get all the exits in the room.

  Q-registers (set via setq() and similar functions) are inherited from the @conformat.

  Example:
    > @exitformat here=Exits: [itemize(iter(%0, name(%i0)))]

See also: TRANSPARENT, @conformat, @nameformat, @descformat
& @HTTP
  @http      <obj>/<attr>=<URL>
  @http/delete <obj>/<att>=<URL>[,<data>]
  @http/post <obj>/<att>=<URL>[,<data>]
  @http/put <obj>/<att>=<URL>[,<data>]

  Attempts to retrieve URL with a HTTP GET request, and upon doing so, queues the action list in <obj>/<attr>. The body of the reply from the remote web server is passed as %0, with the HTTP status in %q<status> and the Content-Type header in %q<content-type>. Any commas in the URL need to be escaped.

  The POST switch makes it do a HTTP POST request instead of the default GET, (And PUT and DELETE do the obvious). With these, the 'content-type' q-register controls the type of data; it defaults to 'application/x-www-form-urlencoded'.` If it contains the string "charset=utf-8", <data> will be converted to UTF-8, otherwise it is assumed to be Latin-1.

  If the q-register 'userpass' is set when running @http, it should hold a string of the form user:password and will be used if needed for HTTP authentication.

  Restricted to objects set Wizard or with the Can_HTTP @Power.

  Note: The response body has the same 8k limit as other MUSH strings. Anything longer is truncated; this command is best used with APIs that provide short responses.

See also: urlencode(), urldecode()
& @firstexit
  @firstexit <exit1>[, ... , <exitN>]
  
  Normally, exits appear in a room's Obvious exits list in the order they were created, most recent first. You can use this command to rearrange them. @firstexit moves each exit, in the order given, to the top of the Obvious exits list for its source room. You must control the room.
  
  Example:
    > @dig/teleport Test Room
    > @open Two ; @open Three ; @open One
    > look
    Test Room(#3Rn)
    Obvious exits:
    One, Three, and Two
    > @firstexit two, one
    > look
    Test Room(#3Rn)
    Obvious exits:
    One, Two, and Three

See also: EXITS, @open, @link
& @filter
  @filter <object>[=<pattern1>[, <pattern2>[, ..., <patternN>]]
 
  The filter attribute is used in conjunction with the AUDIBLE flag. When set, sound which matches any of the comma-separated list of wildcard patterns in this attribute is not propagated through the audible object.
  
  @filter uses the type of matching described in HELP SWITCH WILDCARDS.

  If you need to use a comma in one of the patterns, put a \ before it, do not use {} curly braces.

  You can set the regexp flag on the filter attribute to use regular expressions instead of wildcard patterns, and can set the case flag to make the patterns case-sensitive.
  
  Sounds are only forwarded if the speaker also passes <object>'s @lock/filter, which receives the sound heard as %0.
  
  See 'help @filter2' for an example.
  
See also: AUDIBLE, @infilter, attribute flags, LISTENING, @forwardlist, @prefix
& @filter2

  Example: 
  An audible exit leads from the room where Wizard is standing to another room where the puppet "Wiztoy" is standing.
  
    > @prefix exit=From inside,
    > :tests.
    Wizard tests.
    Wiztoy> From inside, Wizard tests.

    > @filter exit=* jumps.,* tests.
    > :jumps.
    Wizard jumps.
    > :tests.
    Wizard tests.

    > :tests again.
    Wizard tests again.
    Wiztoy> From inside, Wizard tests again.
& @find
  @find [<name>][=<begin>, <end>]

  Displays the name and dbref of every room, thing, or player you control whose name matches <name>. If <begin> and <end> are given, @find will start at the <begin>th object in the database, and will not search past the <end>th object.

  You may wish to use the @search command instead, which can filter the results more complexly.

See also: @search, lsearch(), @entrances
& @forwardlist
& forwardlist
  @forwardlist <object>[=<list of dbrefs>]

  If <object> is set AUDIBLE, any sound it hears which passes its @filter and @lock/filter will be forwarded (prefixed with its @prefix) to each of the dbrefs given in its @forwardlist attribute, in much the same way as puppets forward sound to their owners.

  In order to forward to an object, you must either control it, have the pemit_all power, or pass its @lock/forward. (If you want to allow all objects you own to forward to you, regardless of whether or not they control you, use @lock/forward me=$me)

See also: @filter, @prefix, AUDIBLE, PUPPET, @debugforwardlist, @lock
& @debugforwardlist
& debugforwardlist
  @debugforwardlist <object>[=<list of dbrefs>]

  When <object> has an @debugforwardlist attribute set, any debug output it produces (either because it has the DEBUG flag set, or because an attribute with the DEBUG attribute flag is evaluated) is forwarded to all the dbrefs listed in the debugforwardlist.

  The @debugforwardlist must be a space-seperated list of dbrefs. In order to forward to an object, you must either control it, have the pemit_all power, or pass its @lock/forward.

See also: DEBUG, @forwardlist, @lock
& @force
  @force[/noeval][/inline] <object>=<action list>

  This command forces <object> to queue the given action list, as if the object had entered the action list itself. You must control <object> to @force it. @force is useful for manipulating puppets. 

  If /inline is given, <object> will run <action list> _now_, instead of being queued for execution later. By default, <action list> will be able to see/alter q-registers in the calling action list, and any @breaks in <action list> will also stop the calling action list. The following switches alter that behaviour:
   /nobreak:   @breaks in <action list> will not stop the calling action list.
   /localize:  q-registers will be saved before <action list> is run, and restored after.
   /clearregs: q-registers will all be reset before <action list> is run. You'll usually want to use /localize as well with this.
               
  @force/inplace is an alias for @force/inline/nobreak/localize.

  @force can be abbreviated as
    <dbref> <action list>

  Continued in 'help @force2'.
& @force2
  Normally, the action list is evaluated twice - once when @force is run, and again when <object> runs the action list. If the /noeval switch is given, <action list> is not evaluated until it is run by <object>.

  Examples:
    > @create Lackey
    Created: Object #103 
    > @force Lackey=go east
    Lackey goes east.
    Lackey has left.
    > @force #103=page Cyclonus=Hi there!
    Lackey pages: Hi there!
    > #103 page Cyclonus=Whee
    Lackey pages: Whee

  Continued in 'help @force3'.
& @force3
  Normally, @force creates a new queue entry. @force/inline does not.

  Examples:
    > @create Lackey
    Created: Object #103 
    > &order me=$order *:say Lackey, %0 ; @force Lackey=%0 ; say Done?
    > order pose salutes!
    You say, "Lackey, pose salutes!"
    You say, "Done?"
    Lackey salutes!

    > &order me=$order *:say Lackey, %0 ; @force/inline Lackey=%0 ; say Done?
    > order pose salutes!
    You say, "Lackey, pose salutes!"
    Lackey salutes!
    You say, "Done?"

See also: PUPPET, DBREF, objeval()
& @flag
  @flag <flag name>
  @flag/list [<flag name pattern>]
  @flag/add <flag name>=[<letter>], [<type(s)>], [<setperms>], [<unsetperms>]
  @flag/delete <flag name>
  @flag/alias <flag name>=<alias>
  @flag/letter <flag name>[=<letter>]
  @flag/restrict <flag name>=[<setperms>], [<unsetperms>]
  @flag/type <flag name>=<type(s)>
  @flag/enable <flag name>
  @flag/disable <flagname>
  @flag/decompile [<pattern>]

  This command manipulates the list of flags in the database. With no switches, the command displays information about the given flag, including aliases and permissions. @flag/list lists names of enabled flags, and may be given a wildcarded pattern to restrict which names it will show.

  All other switches to this command are restricted to God:
    /disable disables a flag, making it invisible and unusable
    /enable re-enables a disabled flag
    /alias adds a new alias for an existing flag; use !<alias> to delete one.
    /letter changes or removes a single-letter alias for an existing flag.
    /restrict changes flag permissions (see help @flag2)
    /type changes flag type(s) (see help @flag2)
    /delete deletes a flag completely, removing it from all objects in the database and then removing it permanently from the flag table. It requires the exact flag name or alias to be used. Be very very careful with this. 
    /decompile prints out a list of @flag/add commands needed to recreate the flag table on another MUSH. If <pattern> is given, only flags whose names match that wildcard pattern are shown.

  See 'help @flag2' for information on @flag/add.
  
See also: FLAGS, @set, @power, flag permissions
& @flag2
  @flag/add is used to add a new flag with the given name. Arguments other than the flag name are optional:

  <letter> gives the flag's one-letter abbreviation, which must not conflict with the one-letter abbreviation of another flag that could be applied to the same object type(s). It defaults to none, which means it won't appear in a list of flag characters but can still be tested for with hasflag(), andlflags(), and orlflags(). 
  <type> specifies the space-separated list of types to which the flag applies, and may be 'any' (the default) or one or more of 'room', 'thing', 'player', or 'exit'.
  <setperms> specifies the space-separated list of permissions for who can set and/or see the flag. See 'help flag permissions' for details. It defaults to 'any'
  <unsetperms> specifies the space-separated list of permissions for who can clear the flag on an object they control. It defaults to whatever <setperms> is given, or 'any'.

  Flags added with @flag/add are saved with the database when it is dumped, and do not need to be re-added at startup. They are treated exactly as any other flag in the server.
& flag permissions
  The following permissions can be used when specifying whether <actor> may set or clear a flag on an <object> they control:

   trusted     <actor> must pass a TRUST check (see help TRUST)
   royalty     <actor> must be ROYALTY or WIZARD
   wizard      <actor> must be WIZARD
   god         <actor> must be God (#1)

  The following permissions can be used to specify whether <looker> can see the flag on an <object>, and are given along with the <setperms> in @flag/add. By default, anyone can see the flag:

   dark        <actor> must be Only God (#1) to see the flag on objects
   mdark       <actor> must be WIZARD or ROYALTY 
   odark       <actor> must own the <object> (or be WIZARD or ROYALTY)

  The following permissions control other behavior related to the flag:
  
  log          Log when the flag is set or cleared. Only meaningful in <setperms>.
  event        Trigger the OBJECT`FLAG event when this flag is set or cleared. Only meaningful in <setperms>. See 'help events' for more information.
& @function
  @function [<function name>]
  @function[/preserve] <name>=<obj>, <attrib>[, <min args>, <max args>[, <restrictions>]]
  @function <function name>=<object>/<attribute>
  @function/<switch> <function name>
  @function/restrict[/builtin] <function name>=<restrictions>
  @function/alias <function name>=<alias>
  @function/clone <function name>=<clone>
  
  When used without any arguments, this command lists all global user-defined functions. For wizards and others with the Functions power, it also lists the dbref number and attribute corresponding to the listed functions.

  When used with a function name, it displays some information about how that function is parsed, and how many arguments it takes.
  
  <switch> can be one of:
  /disable, to disable a function.
  /enable, to re-enable it.
  /delete, to remove a user-defined or cloned function, or allow a built-in function to be overriden by a user-defined one.
  /restrict, to change the restriction flags on an existing function.
  
  @function/alias creates an alias for the built-in function <function name> so that it can also be called as <alias>. @function/clone creates a new copy of <function name> named <clone>, which works the same initially but can be restricted separately. You cannot alias or clone @functions, or alias cloned functions.

  Otherwise, this command defines a global function with the name <function name>, which evaluates to <attribute> on <object>.
  
  Continued in 'help @function2'.
& @function2
  <object> can be anything that the player using the @function command controls (if safer_ufun is enabled) or can examine (if not). <function name> must be 30 characters or less.

  A function defined using @function works just like any of the normal MUSH functions, from the user's perspective. The functions are executed by the object, with its powers.
 
  Functions defined via @function should follow the format used by UFUN() - %0 is the first argument passed, %1 is the second argument passed, and so forth. Optional third and fourth arguments to @function can be used to set a parser-enforced number of arguments for the function. If the maximum arguments is negative, any additional arguments are treated as part of the text of the last argument. Note that this behaviour is deprecated, and will be removed in the near future.
  
  An optional fifth argument will set restriction flags.

  The /preserve switch, for MUX compability, does the same thing as the 'localize' restriction - treats the attribute that's evaluated as if it were called with ulocal() instead of u().
  
  Example:
  
    > &WORD_CONCAT #10=%0 %1
    > say u(#10/word_concat, foo, bar)
    You say, "foo bar"
  
    > @function word_concat=#10, word_concat
    > say word_concat(foo,bar)
    You say, "foo bar"
 
  Continued in 'help @function3'.
& @function3
  Global user-defined functions are not automatically loaded when the game is restarted. In order to avoid objects which attempt to use functions that have not been loaded, a @startup containing @function commands should be set on a wizard object with as low a dbref number as possible; God (#1) is suggested for this use. You can also create functions from the alias.cnf file.

  For example, if you have one object that stores all your global functions, you could set the following command (the object is #100 in the example):

    @startup #1=@dolist lattr(#100)=@function ##=#100,##

  And then store each function as an attribute of the same name on object #100.
  
  Continued in 'help @function4'.
& @function4
  Normally, built in functions cannot be overriden by @functions. However, if a built-in function is deleted with @function/delete, you can then make a @function with the same name. "Deleted" built-ins can still be called through the FN() function, and can have restrictions applied with @function/restrict/builtin. @function/restore will delete the @function and turn the built in version back on.

  Using @function on an already-added @function will delete the old one and install a new function with none of the settings of the old one kept.

  Example:
    > @function/delete ansi
    > &ansi_fun #1234=%1
    > @function ansi=#1234, ansi_fun, 2, -2, noguest

  This creates a new version of ansi() that doesn't do any colorization, and that needs two arguments, like the built-in version. It will be restricted to non-guest players.

See also: RESTRICT, FUNCTIONS, @startup, fn(), valid()
& @grep
  @grep[/<switches>] <object>[/<attrs>]=<pattern>
  
  @grep returns a list of all attributes on <object> which match <pattern>. If <attrs> is specified, only attributes which match the wildcard pattern <attrs> are checked; it defaults to "*". Use "**" for all attributes.
  
  By default, attributes which contain the string <pattern> are returned. However, if the /wild switch is given, <pattern> is treated as a wildcard pattern, and attributes which match the pattern are returned. If the /regexp switch is given, <pattern> is treated as a regular expression, and attributes matching the regexp are returned. Please note that <pattern> will NOT be evaluated, so you can easily grep for code strings.
  
  All matches are case-sensitive, unless the /nocase switch is given.
  
  @grep only shows a list of matching attributes. However, you can specify the /print switch, in which case attribute values are also shown, with the matching substrings ansi-highlighted if appropriate.
  
  If the /parent switch is given, attributes <object> inherits from its parent(s) will be checked as well.

  For backwards compatability, the /list switch provides the default behaviour of listing attributes without printing the values, and /ilist and /iprint are aliases for /list/nocase and /print/nocase.
   
See also: grep(), wildgrep(), regrep(), WILDCARDS
& @halt
& @allhalt
  @halt[/noeval] <object>[=<action list>] 
  @halt/pid <pid>
  @halt/all
  @allhalt
 
  The @halt command removes all queued actions for <object>. If given, <action list> is placed in the queue for the object instead. If no action list is specified, the object is set HALT.

  If <object> is a player, it clears the queue for the player and all of his objects. You can use "@halt me" to clear your own queue without setting yourself HALT.

  Only wizards and objects with the halt @power can @halt other player's objects. Note that halting an object does NOT affect any objects waiting on it as a semaphore.

  @halt/pid will cancel a single queue entry with the given pid (the number in parenthesis before it in @ps). You must control the object that queued the command or have the halt power to do this.

  @halt/all is a synonym for @allhalt, and is a wizard-only command which halts all objects in the game in an effort to free up the queue.
  
See also: @wait, @ps, SEMAPHORES, @drain, @notify
& @haven
  @haven <player>[=<message>]

  When someone attempts to page <player> and is unable to, either because <player> is set HAVEN or because of his page lock, they will be shown <message>, if it evaluates to something non-null.

  Example:
    > @set me=HAVEN
    > @haven me=I'm AFK and can't answer pages. Please @mail instead.

See also: HAVEN, page, @lock, @away, @idle
& @hide
  @hide[/<switch>] <descriptor>
  @hide[/<switch>] [<player>]

  This command allows players to hide their online status. Hidden connections don't show up on WHO, in lwho(), etc, when used by players without see_all.
  
  The first form of this command affects the single connection specified by <descriptor> (as returned by ports(), or shown on the admin WHO). The second affects all connections for the given <player>, or the enactor if no <player> is given. You must be a Wizard, Royalty, or have the Hide @power to affect your own connections; only Wizards can affect other players' connections.
  
  The /on and /yes switches hide connections, while /off and /no unhide connections. If no switch is given, the command acts as a toggle: for a single descriptor, the hide status is reversed. For a player, if all his connections are hidden, they will be unhidden. If any are unhidden, they will all be hidden.

See also: hidden(), WHO, lwho(), lports(), ports()
& @idescribe
& @oidescribe
& @aidescribe
  @idescribe <object>[=<description>]
  @oidescribe <object>[=<message>]
  @aidescribe <object>[=<action list>]

  @idescribe command sets the internal description for an object, which is shown to anyone who enters or looks while inside the object. It's only used for players and things; rooms and exits always use @describe.
  
  The @oidescribe attribute is shown to others inside <object> when someone looks at the @idescribe, and the @aidescribe is triggered when someone lookst at the @idescribe.

  If there is no IDESCRIBE set for an object, those who enter or look inside it will see its @describe. In this case, others in the object will see nothing, and the @aidescribe will not be triggered. If you want to use @aidescribe without @idescribe, set @idescribe to a blank string, or to u(describe) to show the description.

See also: enter, @enter, ENTER_OK, @describe, look, @idescformat, VERBS
& @hook
  @hook/<switch> <command>[=<object>[, <attribute>]]
  @hook/list [<command>]

  @hook makes the command parser evaluate given attributes at certain points in command evaluation. The possible points, indicated by the proper switch:

  @hook/ignore: The attribute is evaluated before the built-in command is run. If it returns a false value, the command is skipped (the input is still matched against softcoded commands)
  @hook/override: The object/attribute is matched for a $-command, and if it matches, it is run instead of the built-in command, but with the precedence of the built-in command (thus overriding not only the built-in command but any local $-commands that might match). If the match fails, normal built-in command processing continues. Note that all locks and flags on the object (HALT, etc.) still apply.
  @hook/override/inline: Same as @hook/override, but the resulting matches are run immediately - not queued for later execution!
  @hook/before: The attribute is evaluated before the built-in command is run.
  @hook/after: The attribute is evaluated after the built-in command is run.
  @hook/extend: If an invalid switch is given to the command, attempt to run a matching $-command in <object>[/<attribute>] instead of giving an error. Allows extending built-in commands in softcode without having to rewrite the core functionality.
  @hook/extend/inline: As above, but the $-command won't be queued.

  Continued in 'help @hook2'.
& @hook2
  In all cases, %# is the dbref of the object doing the command, and all hooks share the same set of q-registers. With /before and /after, the results of the evaluated attribute is thrown away like it was wrapped in a call of null(). Also, in cases where a command and function do the same thing (e.g., @pemit and pemit()), only the command gets the hooks.
  
  A number of named registers are available in @hooks, accessible via r(<name>, args), containing the arguments passed to the command. The exact registers available depend on the command type and the arguments passed; see 'help @hook7' for a description of all possible registers.
  
  Hooks can also be set in the alias.cnf file.

  Leaving out the object and attribute clears an existing hook. Wizards can see existing hooks with @command or @hook/list.

  See 'help @hook3' for more information about @hook/override/inline, 'help @hook4' for information on @hook/extend, 'help @hook5' for examples, and 'help @hook7' for an list of available named registers.
& @hook3

  @hook/override/inline and @hook/extend/inline allow you to write softcoded commands which act exactly like built-in commands - because they're run immediately, instead of being queued, output from the command appears in the right order relative to other commands in the action list. By default, commands hooked with /inline have access to the q-registers of the calling action list, and @breaks in the hooked command propagate to the calling action list, allowing you to write your own control structures.
  
  For example, this adds a new command, @qbreak, which works like @break but stops command execution when %q0 contains a true value:
    > &qbreak #123=$@qbreak: @break %q0=@pemit/silent %#=Stopping.
    > @command/add @qbreak
    > @hook/override/inline @qbreak=#123, qbreak
    
  This behaviour can be altered by adding the following switches to @hook/inline:
    /nobreak:   @breaks in the hooked command do not stop the calling action list from running
    /localize:  q-registers are saved before the hooked command is run, and restored after it completes
    /clearregs: All q-registers are reset before the hooked command is run. Most useful when used with /localize.

  @hook/inplace is an alias for @hook/inline/localize/clearregs/nobreak.
  
  See 'help @hook6' for some examples of using @hook/override/inline.
& @hook4

  @hook/extend can be used to add new features to a built-in command, via additional switches, without forcing you to also rewrite the existing functionality like @hook/override would. For example:
  
  > &who`active #123=$who/active*: @nspemit %#=ufun(fun_who, lwho(%#), switch(%0, ?*, stringsecs(%0)))
  > &who`staff #123=$who/staff: @nspemit %#=ufun(fun_who, setunion(lwho(%#), lsearch(all, elock, type^player&(flag^wizard|flag^royalty)))
  > @hook/extend WHO=#123
  
  This leaves the built-in WHO command working as normal, but adds two new switches for filtering the output in different ways.
  
  @hook/igswitch is an alias for @hook/extend, for Rhost compatability.
& @hook5
  An example of @hook:

  > &top_line #3=pemit(%#, What follows is the results of a look)
  > &bottom_line #3=pemit(%#, You're done looking.)
  > @hook/before look=#3, top_line
  > @hook/after look=#3, bottom_line
  > look
  What follows is the results of a look
  Room Zero
  You are in Room Zero. It's very dark here.
  You're done looking.
  
  > &cmd.say #3=$say *: @remit %L=if(hasflag(%#,OOC),<OOC>%b)%n says, "%0"
  > @hook/override say=#3, cmd.say
  > @set me=OOC
  > "test
  <OOC> Robert says, "test"

  See 'help @hook6' for /inplace examples.
& @hook6
  > &dance me=$dance:pose sticks his right foot in ; say Do the hokey pokey ; pose sticks his right foot out
  > dance
  Walker sticks his right foot in
  You say, "Do the hokey pokey"
  Walker sticks his right foot out

  > &cmd.say #3=$say *:@remit %l=%n declares, "%0"
  > @hook/override say=#3,cmd.say
  > dance
  Walker sticks his right foot in
  Walker sticks his right foot out
  Walker declares, "Do the hokey pokey"

  > @hook/override/inplace say=#3,cmd.say
  > dance
  Walker sticks his right foot in
  Walker declares, "Do the hokey pokey"
  Walker sticks his right foot out
& @hook7

  The following named registers may be available (via r(<name>,args)) in your @hook, depending on the command hooked and the arguments given when run; use registers(,args) to get the available registers. /before, /after and /ignore hooks can also use the %u substitution to access the entire command string entered.
  
  Register  Description
  --------  -------------------------------------------------------------
  Always available:
  ARGS      The entire argument string, before evaluation. Always available.
  LS        If the command doesn't have multiple left-side args, LS is set to the entire left-side arg (before the = for EQSPLIT commands)
  LSAC      For commands with multiple left-side-args, the number of left-side args given
  LSAx      The xth left-side-arg, where x is between 1 and LSAC
  
  Available for EQSPLIT commands:
  EQUALS    If the = was given, this is set to "="
  RS        For commands without multiple right-side args, this is the entire right-side arg (after the =)
  RSAC      For commands with multiple right-side-args, the number of right-side args given
  RSAx      The xth right-side-arg, where x is between 1 and RSAC
  
  Available for SWITCHES commands (such as @lock):
  SWITCHES  The switch string given. (Note: Currently, switches given to normal commands are not available here, but can be accessed via the %u substitution.)

& HUH_COMMAND

  This internal command is run whenever someone attempts to run a command which doesn't match any built-in or softcoded commands. The huh_command command cannot be run directly, but it can be @hook'd to perform custom actions when an invalid command is entered.
  
  Examples:
    > &cmd.huh #0=$huh_command: @pemit/sil %#=Whu?
    > @hook/override huh_command=#0, cmd.huh
    > dsfsdf
    Whu?
    
    > &cmd.huh #0=$huh_command *: @pemit/sil %#=Whu? What is '%0'?
    > sdfsdf ert
    Whu? What is 'sdfsdf ert'?
    
    > &cmd.huh #0=$huh_command *: &typos %#=add(default(%#/typos,0),1) ; @pemit/sil %#=Huh? %b(Type "help" for help.) ; @break mod(get(%#/typos),10) ; @wall %n wins %p [ordinal(div(get(%#/typos),10))] typo trophy!
    > asfdsf  (10 times)
    Huh?  (Type "help" for help.)  (10 times)
    Announcement: Room Zero shouts, "Dunce wins his first typo trophy!"

See also: @hook, EVALUATION ORDER, warn_on_missing, unimplemented_command
& @idle
  @idle <player>[=<message>]

  This message is sent in return to every page which successfully reaches you if it evaluates non-null. It is useful if you are idle for long periods of time and wish to inform people where you are, or if you are in a meeting and cannot quickly return pages.

  Example: 
    > @idle me=switch(idle(me),>120,I'm idle. Use @mail)

  Players paging me will only see the "I'm idle" message if I've been idle for over 2 minutes (120 seconds).
  
See also: @away, @haven
& @if
& @ifelse
& @skip
  @if <boolean>=<true>[, <false>]
  @skip <boolean>=<false>
  
  If <boolean> is true, the action list <true> is run, otherwise the action list <false> is run. The action list is not queued, it is run immediately, in the same action list as @if.
  
  For RhostMUSH compatability, @skip runs the action list <false> when <boolean> is false, and does nothing for true values.
  
  @ifelse and @skip/ifelse are aliases for @if.

  See 'help @if2' for examples.
See also: @break, @switch, if(), BOOLEAN VALUES
& @if2
  Examples:
    > @if 1=say Yes, say No
    You say, "Yes"

    > @if 0=say Yes, say No
    You say, "No"

    > &foo me=$foo *: say Checking... ; @if %0=say Yes, {say No ; say Sorry!}

    > foo 1
    You say, "Checking..."
    You say, "Yes"

    > foo 0
    You say, "Checking..."
    You say, "No"
    You say, "Sorry!"
& @infilter
  @infilter <object>[=<pattern 1>[, <pattern 2>[, ..., <pattern N>]]]
  
  @infilter is meant to be used on objects that have an @listen of "*" (ie, objects that listen to everything, which is commonly used for things like chairs so that someone inside the object can hear everything said/done outside it). @infilter filters out any messages that match one of the patterns and prevents those inside the object from hearing them. It does not stop the @ahear of the listening object from being triggered by things that match the @listen.

  Sounds are only forwarded if the speaker also passes <object>'s @lock/infilter, which receives the sound heard as %0.

  For an explanation of infilter patterns, see the help for "@filter".

See also: @filter, @listen, @inprefix, AUDIBLE, LISTENING
& @inprefix
  @inprefix <object>[=<message>]
  
  When an object has an @listen, any string it hears which is propagated to its contents will be prefixed with <message>. Useful for vehicles, etc, which have an @listen of "*".
  
  Example:
    > @create Vehicle
    Created: Object #103.
    > @create Test
    Created: Object #104.
    > @inprefix Vehicle=From outside,
    > @listen Vehicle=*
    > enter Vehicle
    > @force #104=:bounces.
    From outside, Test bounces.

See also: @prefix, @listen, @infilter
& @kick
  @kick <number>
  
  This wizard-only command forces the immediate execution of <number> items from the queue. Rarely useful. If your MUSH is lagging badly, chances are high that it stems from network problems. Check the queue before using this command.

See also: @ps, QUEUE
& @lemit
  @lemit[/<switch>] <message>

  Emits a message to the outermost container object. For example, if you are carrying a bird, and are inside a vehicle which is in room #10, and you force the bird to @lemit "Cheep", everyone in room #10 will hear "Cheep". This command is the same as "@emit/room".

  With the /silent switch, no confirmation message is shown. With /noisy, it is. If neither is given, the silent_pemit option determines if it is shown. 
  The /noeval switch prevents <message> from being evaluated. 
  The /spoof switch causes nospoof notifications to show the enactor's dbref instead of the executor's dbref, and requires control over the enactor or the Can_spoof power.

See also: @remit, @nslemit
& @list
  @list/<switch>
  @list[/lowercase] <switch>

  The @list command lists useful MUSH information.

  Switches include:
  motd        : Alias for @listmotd, shows current messages of the day.
  functions   : Lists all built-in functions and @functions.
  commands    : Lists all built-in commands and @commands.
  attribs     : Lists all standard attributes.
  locks       : Lists the built-in lock types.
  flags       : Alias for @flag/list, shows all flags.
  powers      : Alias for @powers/list, shows all powers.
  allocations : Information about memory allocations. Admin-only.
  
  By default, information is shown in upper-case. Add the /lowercase switch to show output in lowercase instead.
  
  "commands" and "functions" show built-in and local commands/functions by default. The /builtin or /local switches can be given to limit this.

See also: list(), @config, config(), functions(), @stats, @command, @function, @flag, @power, @attribute, @listmotd, @motd, locktypes
& @link
  @link[/preserve] <object>=[<dbref> | here | home | variable]

  Links <object> to either a room or a thing. If a thing or player is linked, that sets the object's HOME. If a room is linked, that sets the object's drop-to room, which is where objects that are dropped in the room will be sent to.

  Most often, @link is used to link or relink an exit to a destination room. In order to link an exit to a room, you must either own or control the room, OR the room must be set LINK_OK. If the exit is currently unlinked, and you pass its @lock/link, you may link it even if you do not own it. In this case, the exit will be @chowned to you (and set HALT). Linking an exit may have a cost (usually 1 penny.) The Wizard-only /preserve switch can be used to link without @chowning and HALTing the exit.

  If the destination of an exit is "variable", its destination is determined at the time of travel by the attribute DESTINATION on the exit, which is evaluated like a U()-function. You must have permission to link to whatever the DESTINATION evaluates to in order for the exit to work. If there's no DESTINATION attribute, the EXITTO attribute is also tried.

  If the destination is "home", those who travel through the exit will be sent to their homes.

  LINK_OK objects can also be used as semaphores, and any object can be @parented to them.

See also: EXITS, @open, @dig, DROP-TO, HOME
& @destination
& @exitto
& Variable Exits
  @destination <exit>[=<destination>]
  @exitto <exit>[=<destination>]
  
  The DESTINATION attribute is used by variable exits. To make a variable exit, you create it in the usual way (with @open), then @link it to "variable" instead of a dbref. When someone attempts to pass through the exit, the DESTINATION attribute will be evaluated, and should return a dbref; the dbref will be used as the location for the person to go to. The exit name or alias the moving player used is passed to the attribute as %0.
  
  The exit must be able to @link itself to the dbref returned by the attribute. This means the exit must control the destination, the destination must be set LINK_OK, or the exit must have the Link_Anywhere @power.
  
  If no DESTINATION attribute is set on a variable exit, the MUSH will also check for an EXITTO attribute, for cross-platform compatability. It works exactly the same as the DESTINATION attribute.
  
  Note that, unlike most attributes, @destination cannot be abbreviated and must be typed in full.
  
  Example:
    > @open Random Exit;re
    > @link re=variable
    > @power re=link_anywhere
    > @destination re=pickrand(#5 #123 #999 [home(%#)] %L)
  
See also: EXITS, @link, @open, LINK_OK, Link_Anywhere Power
& @listen
  @listen <object>[=<pattern>]

  Sets the object's listen pattern to <pattern>, which can have wildcards. Whenever something the object hears matches the pattern, the object's ahear/amhear/aahear attribute will be triggered. In addition, anything inside the object will hear it as well, if the speaker passes @lock/infilter.
  
  Rather than using @listen, it's recommended you use ^-listening patterns, which can be set in any attribute similar to $-commands. This allows for descriptive attribute names, and also allows multiple patterns per object. See 'help ^' for more information.

  For example:
    > @listen Chair=*
  Since the wildcard (*) matches anything, anyone inside the object will hear anything said outside it.
    > @listen Butler=* has arrived.
    > @ahear Butler=:walks over to the new arrival and takes %p coat.
  In this case, the listen pattern is met whenever someone 'arrives' in the room, and then the object does whatever is inside its @ahear attribute.
    Cyclonus has arrived.
    Butler walks over to the new arrival and takes his coat.

  Continued in 'help @listen2'.
& @listen2
  An object "hears" anything that another player standing in the same room would hear. For example, if you type in a command, the object does NOT hear it. If the command has a result that people in the room hear, the object will hear it.

  For example:
    > @listen Recorder=@emit *
    > @ahear Recorder=:records %0
    > @emit Whee!
    Whee!
  In this example, the Recorder's listen-pattern is NOT matched, because it doesn't hear the '@emit Whee!', it only hears the 'Whee!' part, which doesn't match.

    > @listen Recorder=Cyclonus says, "*"
    > say Whee!
    Cyclonus says, "Whee!"
    Recorder records: Whee!

See also: LISTENING, @ahear, @amhear, @aahear
& LOCKING
& LOCKS
& @lock
  @lock[/<switch>] <object>=<key> 
  
  This command "locks" the object, specifying a key which determines who or what can do certain things with the object. There are many different types of locks, all of which are described in 'help locktypes' and which are designated by the switch. The "basic" lock determines, for players and things, who can pick them up. For exits, it determines who can go through the exit. All other locks can be set the same way as the basic lock.

  Whenever you "pass" the basic lock, you succeed in doing something with the object. This triggers the @success/@osuccess/@asuccess messages and actions. If you fail to pass the basic lock, you trigger the @failure/@ofailure/@afailure messages and actions. Other locktypes may also have such success/failure messages: see 'help failure' for info.

  Just like attributes, locks can be inherited from parents. By default, locks are set no_inherit, but this flag can be cleared using @lset. More details and a list of flags can be found in 'help @lset'.

  A listing of lock types, such as pagelocks, look at 'help locktypes'. For the available key types, such as how to check an attribute on an object trying to pass a lock, see 'help lockkeys'.

See also: @lock-simple, locktypes, lockkeys, @clock, failure, success, elock(), lock(), @lset, @clock, testlock(), locks(), lockflags(), lockowner(), clock(), llocks()
& @lset
  @lset <object>/<lock type>=[!]<flag>

  This commands sets or clears flags on locks.
  Valid flags include:
  
  visual     (v)     This lock can be seen even if the object it's on isn't visual.
  no_inherit (i)     This lock isn't inherited off of parents. All locks are set no_inherit by default.
  no_clone   (c)     This lock isn't copied by @clone.
  wizard     (w)     This lock can only be set by wizards.
  locked     (+)     This lock can only be set by the owner of the lock.

See also: @lock, lockflags(), llockflags(), lset()
& @log
  @log[/<switch>] <message>
  @log/recall/<switch> [<number>]
 
  This wizard-only command puts <message> in a log file, tagged with the time and object executing the command. The available switches are /check, /cmd, /conn, /err, /trace, and /wiz, specifying which file to log to. /cmd is default.

  Adding the /recall switch will display the last <number> lines written to that log file, or the entire log buffer (Which is the last 1 kilobyte or so of data written to the log) if omitted.

See also: @logwipe
& @logwipe
  @logwipe/<log>[/<switch>] <password>

  This God-only command erases one of the MUSH logs.

  <log> specifies which log file to erase, and must be one of:
  /check, /cmd, /conn, /err (Default), /trace, and /wiz.

  The default policy of erasing a log can be changed by giving one of the following switches:

  /rotate : copies the log to a backup file and then erases it.
  /trim   : deletes all but the most recent lines in the file.
  /wipe   : erases the file (Default)
 
  God must give the log wipe password from the MUSH's configuration file to use this command.

See also: @log
& @message
  @message[/<switches>] <recipients>=<message>,[<obj>/]<attr>[,<arg0>[, ... , <arg29>]]]

  @message is designed for the use of *format messages, such as @pageformat or @chatformat. It is intended for use with @hooking page, @chat, or say/pose/emit, or for coding language systems.

  For each of the given <recipients>, <obj>/<attr> is evaluated (with up to 30 arguments, as if it was ufun()'d), and the object is shown the result via @pemit. If the attribute does not exist, or you do not have permission to evaluate it, they are shown <message> instead.
  
  If <obj> is not given, or is given as "#-2", the attribute will be checked on the recipient.

  If one of the arguments matches "##", it will be replaced with the dbref of the recipient.
  
  Switches:
    /noeval   -- none of @message's arguments will be evaluated
    /spoof    -- the message will appear to be from the enactor, not the executor. Requires the Can_Spoof @power.
    /remit    -- Works like @remit, treating <recipients> as a list of rooms to send <message> to
    /oemit    -- Works like @oemit, with <recipients> as a list of objects not to emit to. See 'help @oemit' for more info.
    /nospoof  -- don't show nospoof info, as per @nspemit/@nsremit/@nsoemit
    /silent   -- don't show a confirmation message
    /noisy    -- show a confirmation message

  See 'help @message2' for examples.
See also: message(), @chatformat, @pageformat, @oemit, @remit, speak()
& @message2

  Example:
    > &sayformat *Mike=%n sez, '%0'
    > &sayformat *Walker=From %n: %0
    > &cmd.fsay me=$fsay *: @message/spoof *Mike *Walker *Javelin=%n says\, "%0", SAYFORMAT, %0
    > fsay This is a test
    
  Mike sees:
    Player sez, 'This is a test'
  Walker sees:
    From Player: This is a test
  Javelin sees:
    Player says, "This is a test"

  A rough implementation of @chatformat:
    > &cmd.chat Globals=$^@chat (.+?)=([\:;]?)(.+?)$: @message/spoof cwho(%1)=setr(0,<%1> [speak(&[squish(ctitle(%1, %#) %n)], %2%3)]), CHATFORMAT, firstof(%2, "), %1, %3, %n, ctitle(%1, %#), %q0
    > @set Globals/cmd.chat=regexp

  See 'help @message3' for more examples.
& @message3

  A (very) basic language system:
    > &skill`spanish Juan=2
    > &skill`spanish Bob=1
    > &cmd.spanish Globals=$+spanish *: @nspemit %#=You say (Spanish), "%0"; @message/oemit/spoof %#=setr(0,%n says (Spanish)\, "%0"), %!/TRANSLATE, ##, SPANISH, %q0
    > &translate Globals=switch(default(%0/skill`%1, 2), 2, %2, speak(%#, |%2,, %!/translate`some))
    > &translate`some Globals="[iter(%0,if(rand(2),%i0,...))]"
    > +spanish The rain in Spain falls mainly on the plain
    
  You see:
    You say (Spanish), "The rain in Spain falls mainly on the plain"
  Bob sees (something like):
    Mike says (Spanish), "The rain ... ... falls ... ... ... ..."
  Juan sees:
    Mike says (Spanish), "The rain in Spain falls mainly on the plain"

& @moniker
  @moniker <object>[=<moniker>]
  
  This command sets or clears the "moniker" for <object>. A moniker is an ansi template, to show the object's name in color. Exactly where this color is displayed depends on the "monikers" @config option; see 'help monikers' for more information.
  
  <moniker> can contain any text - it will be ignored, and only the ansi colors will be taken into account. If <object>'s name is longer than <moniker>, the last color will be used for the remaining letters.
  
  Examples:
   Display your name in highligted red
   > @moniker me=ansi(hr,-)
   
   Show the first letter in orange, and the rest with no color
   > @moniker me=ansi(+orange,-)[ansi(n,-)]

See also: MONIKERS, moniker(), ansi(), @nameformat, @nameaccent, MONIKER
& @motd
& @listmotd
& @wizmotd
& @rejectmotd
  @motd[/<type>] <message>
  @motd/clear[/<type>]
  @motd/list

  This command is used for manipulating the various Messages of the Day, or MotD. The first form of this command sets the <type> MotD to <message>, the second form clears the <type> MotD, and the third form lists the current value of each MotD. If no switch is given, <type> defaults to /connect.
  
  These messages are intended for temporary announcements; the given <message> is shown in addition to the standard MotDs defined in the mush.cnf options. MotDs set via this command are cleared when the MUSH restarts.
  
  Valid <type>..   shown with..   and is seen by...
  /connect         motd_file      all players on connect
  /wizard          wizmotd_file   connecting Wizards and Royalty
  /full            full_file      players failing to connect because all available connections are in use
  /down            down_file      mortals failing to connect when logins are disabled

  You must have the Announce @power to change the Connect MotD; only wizards and royalty can see or alter the others.

  For historical reasons, @listmotd, @wizmotd and @rejectmotd are aliases for @motd/list, @motd/wizard and @motd/full, respectively.
& @name
  @name <object>=<new name>
  @name <player|exit>=<new name>[;<alias1>[;<aliasN>]]

  Changes the name of <object> to <new name>.

  Players can change their name to anything valid which is not currently in use by another player, as a name or alias. (They can change their name to something from their own @alias.)
  
  You can change the alias for a player or exit while renaming it, by giving the alias(es) after the new name, each separated by a semicolon. If the name is followed by a semicolon with no aliases, the existing alias will be cleared instead.

  When <object>'s name is changed, its ONAME and ANAME verb attributes will be triggered. See 'help @oname' for details.
  
  Examples:
    > @name here=My Room
    Name set.
    > @name me=Mike;Michael;m
    Alias set.
    Name set.
    > @name me=Obi Wan;
    Alias removed.
    Name set.
  
See also: @alias, @oname, name(), fullname()
Config options: player_name_spaces, player_name_len, only_ascii_in_names
& @ONAME
& @ANAME
  @oname <object>[=<message>]
  @aname <object>[=<action list>]
  
  Whenever <object>'s name is changed (via @name), others in the same location will see the contents of <object>'s ONAME attribute, prepended with <object>'s new name. At the same time, <object>'s ANAME attribute will be triggered. Both attributes receive the old name as %0, and the new name as %1.
  
    Example:
      > @oname me=has regenerated from %0!
      > @aname me=think >> Renamed from %0 to %1 at [time()] by %n(%#).

See also: @name, name(), VERBS
& @newpassword
  @newpassword <player>=<password>
  @newpassword/generate <player>

  This wizard-only command changes <player>'s password. If <player> is connected, she will be informed that the password was changed and who by, but not what it was changed to.
  
  The <player> argument is evaluated, but the <password> argument is not when the command is entered directly from a client.
  
  If the /generate switch is given, a new, random password is generated automatically, and shown to the enactor (but not to <player>).
  The <password> must not contain whitespace, unprintable characters, or '='.
  
See also: @password, checkpass()
& @notify
  @notify[/any][/all] <object>[/<attribute>][=<number>]
  @notify/setq <object>[/<attribute>]=<qreg1>,<qval1>[,...]
  
  This command notifies a semaphore, allowing commands queued for that semaphore to be executed.

  If the /any switch is given, then all semaphores associated with <object> are @notified. Otherwise, only the specified semaphore <attribute> (or SEMAPHORE if no attribute is specified) is @notified.

  If the /all switch is given, then all queue entries associated with the selected semaphore(s) are executed. Otherwise, only the first <number> of queue entries are run. If no <number> is given, then only one queue entry is run.

  If the /all switch was not used, and there were not enough queue entries waiting to satisfy the requested <number>, then the semaphore becomes negative, and subsequent @waits will not block until it reaches 0 again.
  
  You may not specify both the /any switch and a specific attribute. Similarly, you may not specify both the /all switch and a number.

  Continued in 'help @notify2'.
& @notify2
  @notify/setq is a special form of @notify: It requires that a queue entry exists and is waiting on <object>[/<attr>]. When this is the case, then @notify/setq will modify the Q-registers of the extant queue entry.

  /setq supercedes all other switches: You cannot @notify/all/setq or @notify/any/setq - it deals with just one queue entry.

  Example:
    > @wait me=think Hello, %q0!
    > @notify/setq me=0,Walker
    Hello, Walker!

See also: SEMAPHORES, @drain, @wait, @halt
& @nspemit
& @nsemit
& @nslemit
& @nsremit
& @nszemit
& @nsoemit
& @nsprompt
  @nsemit[/<switch>] [<message>]
  @nslemit[/<switch>] <message>
  @nspemit[/switches] <object>=<message>
  @nsprompt[/switches] <object>=<message>
  @nsremit[/switches] <object>=<message>
  @nsoemit[/<switch>] [<room>/]<object> [<object>...]=<message>
  @nszemit <zone>=<message>

  These commands work like @emit, @lemit, @pemit, @prompt, @remit, @oemit, and @zemit, respectively, but will not include nospoof information if used by Wizards or someone with the Can_spoof @power. They are meant to be used by commands in the master room where the nospoof information is just useless noise. They take the same switches as their respective commands, with a few exceptions (/spoof, and for @nspemit, /contents and the admin-only /port).

See also: @emit, @lemit, @pemit, @prompt, @remit, @oemit, @zemit, nsemit(), nslemit(), nspemit(), nsprompt(), nsremit(), nsoemit(), nszemit(), PROMPT_NEWLINES
& @oemit
  @oemit[/<switch>] [<room>/]<object> [... <object>]=<message>
 
  This command shows <message> to everyone in the location of <object> EXCEPT <object>. A list of objects can be given, in which case the message is shown in the locations of each, to everyone but those objects. If <object> contains a space, it should be enclosed in double-quotes.
  
  If <room> is specified (usually as a dbref), this command shows <message> to everyone in <room> except for the given <object>s. In this case, each <object> is matched relative to <room>. If no matching <object>s are found in <room>, this is the equivilent of @remit <room>=<message>.
  
  The /noeval switch prevents the MUSH from evaluating <message>.
  The /spoof switch causes nospoof notifications to show the enactor's dbref instead of the executor's dbref, and requires control over the enactor or the Can_spoof power.

  See 'help @oemit2' for examples.
See also: @emit, @pemit, @nsoemit, oemit(), nsoemit(), NOSPOOF, SPOOFING
& @oemit2
  Examples:
    Show a message in the locations of players Bob and Fred, to everyone except those two players:
    > @oemit *Bob *Fred=Bob throws a paper aeroplane at Fred.
    
    Show a message in #50 to everyone except the object 'Spy'.
    > @oemit #50/Spy=Sssh!
    
    Show a message to everyone in your current location, except the 2nd object called 'foo'.
    > @oemit %L/"2nd foo"=bar
& @open
  @open <exit name>[=<destination>,<return exit name>,<source room>,<dbref>,<return dbref>]

  This command opens an exit, named <exit name>, in your current location, or in <source room> if one is given. Exits can only be opened from rooms. If a <destination> is given, the exit will be linked (as per @link) to that object. If you don't have permission to link to <destination>, the exit will be created but unlinked.
  
  If <return exit name> is given, the MUSH will attempt to open an exit back from <destination> and link it to <exit name>'s source.
  
  Both <exit name> and <return exit name> can include any number of aliases for the exits, separated by semicolons. See 'help @name' for details.

  Wizards and objects with the pick_dbref power can specify garbage dbrefs to use for the exit and return exit.

  To open an exit in a room, you must control the room, have the Open_Anywhere @power, or the room must be set OPEN_OK and you must pass its @lock/open.

  Example:
    > @open Up <U>;up;u;climb=#255, Down <D>;down;d;fall
  
See also: EXITS, @link, @dig, open()
& @parent
  @parent <object>[=<parent>]
 
  This command sets the parent of <object> to <parent>. If no <parent> is given, or <parent> is "none", <object>'s parent is cleared. You must control <object>, and must either control <parent> or it must be set LINK_OK and you must pass its @lock/parent.
  
See also: PARENTS, parent(), lparent(), ANCESTORS
& @password
  @password <old password>=<new password>

  This changes your password. Please note that passwords ARE case-sensitive. The arguments are not evaluated.
  The <new password> must not contain whitespace, unprintable characters, or '='.
  
See also: @newpassword, checkpass()
& @pageformat
& @outpageformat
  @outpageformat <object>[=<message>]
  @pageformat <object>[=<message>]

  @pageformat changes the message seen by <object> when it receives a page.
  @outpageformat sets the message seen by <object> when it sends a page.

  %0 will be set to the page message (not including :, ; or ").
  %1 will be set to ':' ';' or '"' for pose, semipose and normal page, respectively.
  %2 will be set to the alias of the pager, if any.
  %3 will be a space-separated list of recipient dbrefs.
  %4 will be set to the default message.

  See 'help @pageformat2' for examples.

See also: page, speak(), @chatformat, @speechmod, @message
& @pageformat2
& @outpageformat2
  For simple page timestamps:
  > @pageformat me=\[[time()]\] %4
  > @outpageformat me=\[[time()]\] %4

  To obtain 'page_aliases' behavior:
  > @pageformat me=[setq(0,%n[if(%2,%b(%2))],1,switch(%3,%!,,itemize(iter(%3, name(##),%b,|),|)))][switch(%1,",%q0 pages[if(%q1,%b%q1)]: %0,:,From afar[if(%q1,%b(to %q1))]\, %q0 %0,From afar[if(%q1,%b(to %q1))]\, %q0%0)]

  To obtain no 'page_aliases' behavior:
  > @pageformat me=[setq(1,switch(%3,%!,,itemize(iter(%3,name(##),%b,|),|)))][switch(%1,",%n pages[if(%q1,%b%q1)]: %0,:,From afar[if(%q1,%b(to %q1))]\, %n %0,From afar[if(%q1,%b(to %q1))]\, %n%0)]
& @receive
& @oreceive
& @areceive
  @receive <recipient>[=<message>]
  @oreceive <recipient>[=<message>]
  @areceive <recipient>[=<action list>]

  These attributes contain the message shown <recipient> when he receives an object (via 'get' or 'give'), the message shown to others in <recipient>'s location when he receives an object, and the actions to be taken by <recipient> when he receives an object, respectively.
  
  In all cases, %0 is the dbref of the object received. If the object was 'give'n, %1 will be the dbref of the giver.

See also: give, get, @give, @success, ACTION LISTS, VERBS
& @give
& @ogive
& @agive
  @give <giver>[=<message>]
  @ogive <giver>[=<message>]
  @agive <giver>[=<action list>]
  
  These attributes contain the message shown to <giver> when he gives an object, the message shown to others in <giver>'s location when he gives an object, and the actions to be taken by <giver> when he gives an object, respectively.
  
  In all cases, %0 is the dbref of the object being given, and %1 is the dbref of the recipient.

See also: give, @receive, ACTION LISTS, VERBS
& @pcreate
  @pcreate <name>=<password>[, <dbref>]

  This wizard-only command creates a player with the given name and password. If specified, <dbref> is the dbref of a garbage object to be used for the new player.
  
See also: pcreate()
& @prompt
  @prompt[/<switch>] <dbref list>[=<message>]

  A variation of @pemit/list that adds a telnet GOAHEAD control code to the end of messages sent to players. Players with clients that handle GOAHEAD may get the message as a prompt in their client's input area.
  
  If <message> is omitted, an empty prompt is sent.

  @prompt supports the following @pemit switches: /silent, /noisy, /spoof, /noeval

See also: @pemit, @nsprompt, prompt(), nsprompt(), PROMPT_NEWLINES
& PROMPT_NEWLINES
  PROMPT_NEWLINES [1|0]

  This socket-level command is used to indicate whether a newline should be sent after the telnet GOAHEAD code issued by @prompt/prompt() to telnet-capable clients. By default, in order to maximize portability, newlines are sent.

  Some clients, like TinyFugue, are smart enough to interpret GOAHEAD and treat prompts specially by putting them into their input window. These clients do not require the newline, and sending the newline results in a blank line in their output window. The 'PROMPT_NEWLINES 0' command can be used to disable the newline and is recommended for users with these clients.

See also: @prompt, prompt(), terminfo(), @sockset
& @pemit
  @pemit[/<switches>] <object>=<message>
  @pemit/list[/<switches>] <object list>=<message>
  @pemit/port[/list][/silent] <descriptor(s)>=<message>
  
  The basic form of this command sends <message> to <object> directly. It is very similar in its effects to @emit except only one object will see the message.
 
  @pemit/list sends the message to multiple objects. You will not get a confirmation message when using this switch.
  
  @pemit/port can only be used by Wizards/Royalty, and sends <message> to one or more connections. It can be used to send messages to connections which are still at the login screen, or to send a message to just one of a player's connections when he's logged in multiple times.

  See 'help @pemit2' for more.
& @pemit2
  The @pemit command can take the following additional switches:
    /contents  -- equivalent to @remit.
    /silent    -- does not tell the @pemit'ing object a confirmation message.
    /noisy     -- tells the @pemit'ing object a confirmation message.
    /noeval    -- <message> will not be evaluated for substitutions 
    /spoof     -- the enactor's dbref will be used for nospoof notifications instead of the executor's dbref. Requires control over enactor or Can_spoof power. 

  You cannot @pemit to objects set HAVEN, or objects whose @lock/page you do not pass, unless you are set WIZARD or have the pemit_all @power.

See also: @emit, @nspemit, @oemit, @remit, NOSPOOF, SPOOFING, page
& @poll
  @poll
  @poll <message>
  @poll/clear

  This command manipulate the message at the top of WHO/DOING. By itself, it displays the current poll. Wizards and those with the poll @power can set or clear the message.

See also: @doing, WHO, DOING
& @poor
  @poor <value>
  
  This command sets the pennies of every player on the MUSH to <value>. It can only be used by God.

See also: MONEY, give
& @power
  @power/list [<power name pattern>]
  @power <power>
  @power <object>=[!]<power>
  
  @power/list lists the defined powers (see 'help powers'). A list of standard powers with explanations is given in 'help powers list'. When given a power name as an argument, @power displays information
  about a power.

  The third form manipulates powers on objects, and is limited to Wizards. @power <object>=[!]<power> sets (or clears) the given power on an object.

  God can add, delete, and otherwise manipulate power definitions. See help @power2 for these commands.

See also: powers(), @flag
& @power2
  @power/add <power>=[<letter>], [<type(s)>], [<setperms>], [<unsetperms>]
  @power/delete <power>
  @power/alias <power>=<alias>
  @power/letter <power>[=<letter>]
  @power/restrict <power>=[<setperms>], [<unsetperms>]
  @power/type <power>=<type(s)>
  @power/enable <power>
  @power/disable <power>
  
  These commands manipulate power definitions. Only God may use them.
    /disable disables a power, making it invisible and unusable
    /enable re-enables a disabled power
    /alias adds a new alias for an existing power
    /letter changes or removes a single-letter alias for an existing power.
    /restrict changes power permissions (see help @power3) 
    /type changes power type(s) (see help @power3) 
    /delete deletes a power completely, removing it from all objects in the database and the removing it permanently from the power table. It requires the exact power name or alias to be used. Be very very careful with this. 
  
  See help @power3 for information on @power/add
& @power3
  @power/add is used to add a new power with the given name. Arguments other than the power name are optional:
  
  <letter> gives the power's one-letter abbreviation, which must not conflict with the one-letter abbreviation of another power that could be applied to the same object type(s). It defaults to none, which means it won't appear in a list of power characters but can still be tested for with haspower(), andlpowers(), and orlpowers(). 
  <type> specifies the space-separated list of types to which the power applies, and may be 'any' or one or more of 'room', 'thing', 'player', or 'exit'. It defaults to 'any'. 
  <setperms> specifies the space-separated list of permissions for who can set and/or see the power. See 'help flag permissions' for details. It defaults to 'any'
  <unsetperms> specifies the space-separated list of permissions for who can clear the power on an object they control. It defaults to whatever <setperms> is given, or 'any'.

  Powers added with @power/add are saved with the database when it is dumped, and do not need to be re-added at startup. They are treated exactly as any other power in the server.
& @prefix
  @prefix <object>[=<message>]
 
  This attribute is meant to be used in conjunction with the AUDIBLE flag. The @prefix of the object is prepended to messages propagated via AUDIBLE. Pronoun substitution is done on @prefix messages.
  
  For example, if you have an audible exit "Outside" leading from a room Garden to a room Street, with @prefix "From the garden nearby," if Joe does a ":waves to everyone." from the Garden, the people at Street will see the message, "From the garden nearby, Joe waves to everyone."

See also: @inprefix, AUDIBLE, @listen
& @ps
  @ps[/<switch>] [<player>]
  @ps[/debug] <pid>
  
  @ps lists all commands currently on your 'to be executed' queue, thus allowing you to identify infinite (or unnecessary) loops with-out putting in says or poses. It gives a count of the total commands in each of the queues (Player, Object, Wait, and Semaphore), displayed in the format:
      <Number of your queued commands> / <Total number of queued commands>.

  Some of the queues also include a [Ndel] after the total. That number is the number of entries made by objects that have been halted but haven't been removed from the queue yet.
      
  It also shows a running load average of the number of queue entries executed per second for the last 1, 5 and 15 minutes.

  @ps with no arguments will show you your own queue. Wizards may specify the /all switch, and see the full queue. They may also specify a player. @ps/summary just displays the queue totals for the whole queue. @ps/quick displays the queue totals for just your queue.
  
  Continued in 'help @ps2'.
& @ps2
  With a <pid> argument, @ps shows information on a single queue entry. The /debug switch will also display the queue entry's environment: Arguments, q registers, executor, enactor and caller dbrefs.

  Each line includes the process id of the queue entry, the object and attribute being used as a semaphore (if any), the number of seconds left before it executes (for waits and semaphores), the object that is going to execute the entry, and the command. To halt a specific queue entry, use @halt/pid.
  
See also: @wait, @halt, @notify, @drain, SEMAPHORES
& @purge
  @purge is a wizard only command that calls the internal purge routine to advance the clock of each object scheduled to be destroyed, and destroy those things whose time is up. The internal purge routine is normally run automatically approximately every 10 minutes.

  The @purge command should almost never need to be performed manually. If you do use it manually, you may want to use it twice in a row to make sure that everything marked GOING is actually destroyed.

See also: @dbck
& @quota
  @quota [<player>]

  These commands are only meaningful if the Quota system is enabled (check the use_quota @config option).
  
  @quota shows the current quota for <player>, or for the executor if no <player> is given. You must control <player>, or have either the See_All or Quotas @power.

  Continued in 'help @quota2'.
& @quota2
& @squota
& @allquota
  @squota <player>=[+|-]<amount>
  @allquota[/quiet] [<limit>]

  @squota is a Wizard-only command which adjusts the quota of <player>. If <amount> is prefixed by + or -, their current quota will be incremented or decremented by <amount>, respectively. Otherwise, their total quota is set to <amount>.
  
  @allquota can only be used by God. With no <limit> argument, it reports the quotas of all players. If a <limit> is given, the quotas of all players is reset to <limit>. The /quiet switch stops @allquota reporting the current quotas before changing them.
  
  Players always have enough quota for the objects they currently own; if you attempt to set their quota to a lower number (with @squota or @allquota), it will be set to the number of objects they own instead.
  
  @quota/set and @quota/all are equivilent to @squota and @allquota, respectively.

See also: QUOTAS, Quotas Power, No_Quota Power
& @readcache
  @readcache
  
  This wizard-only command reloads the cached text files (listed under '@config messages') and rebuilds the indexes for help, news and similar commands. 

  On some systems (where '@config compile' shows 'Changed help files will be automatically reindexed.'), updates to these files are noticed and loaded automatically. Otherwise, @readcache must be used any time changes are made to one of these files while the game is running.

  A site admin can achieve the same effect by sending the MUSH process a kill -1 or kill -HUP.

  @readcache does not load updates to the configuration files (mush.cnf, restrict.cnf, etc) - the game must be restarted with @shutdown/reboot to reload these.

See also: @shutdown
& @remit
  @remit[/switches] <object>=<message>

  Sends the message to all contents of <object>, which can be a room, thing, or player. The message is also sent to the <object> itself. (The TinyMUSH equivalent is @pemit/contents).

  The /silent switch stops the remitter from getting feedback if they're in a different location than the target.
  The /noisy switch always gives feedback to the remitter if they are not in the target location. 
  (Without /silent or /noisy, the silent_pemit config option is used to determine noisiness.)
  The /list switch will send the message to the contents of multiple objects at the same time. The <object> argument is treated as a space-separated list of targets.
  The /spoof switch causes nospoof notifications to show the enactor's dbref instead of the executor's dbref, and requires control over the enactor or the Can_spoof power.
  The /noeval switch causes <message> to not be evaluated.

See also: @emit, @pemit, @oemit, SPOOFING, NOSPOOF, CONTROL.
& @retry
  @retry <boolean>
  @retry <boolean>=<arg0>[,...[,<argN>]]

  The @retry command restarts the current queue entry, enabling people to loop their command without requiring a wait for the next queue entry. It can be a little tricky to understand at first. It basically tells the parser: "If <boolean> is true, then go back to the beginning." It can also replace %0-%9 with the arguments passed to it. (<arg0>,...).

  Please note: @retry only restarts the action list it is currently in. If you have: "@break 1=@retry 1=hello", then the action list is only "@retry 1=hello" - which would thus create an infinite loop.

  Watch out for infinite loops! @retry does respect all the limits (cpu_limit, function_invocation_limit, etc). But because @retry causes the queue parser to repeat itself _without_ invoking a new function, it doesn't risk hitting any issues other than infinite loops.

  See 'help @retry2' for examples.

See also: ACTION LISTS, BOOLEAN VALUES, @break, @include
& @retry2
  Example: 'while'
  > &sing me=$sing *:say %0 bottles of beer! ; @retry gt(%0,0)=dec(%0) ; say Go get some more!
  > sing 3
  You say, "3 bottles of beer!"
  You say, "2 bottles of beer!"
  You say, "1 bottles of beer!"
  You say, "0 bottles of beer!"
  You say, "Go get some more!"

  Implementing a folding algorithm:
  (Yes, I know lmath is better, but this is just an example! :D)

  > &add me=$add *:@retry words(%0)=rest(%0),add(first(%0),0%1) ; think %1
  > add 4 3 2 1
  10

& @restart
  @restart <object>
  @restart/all
  
  This command halts <object> (as described in @halt), and then triggers the STARTUP attribute on the object, if set. If <object> is a player, it affects the player and all of their objects. Players can use @restart me to restart their own objects. The /all switch halts all objects (see @allhalt) and restarts them, and can only be used by a wizard.

See also: @halt, @startup, @shutdown
& @scan
  @scan[/<switches>] <command>
  
  @scan gives you a list of all objects containing $-commands (user-defined commands) which could match <command>. If given no switches, it checks you, your possessions, your location, objects in your location, the zone/zone master room of your location, your zone, and objects in the master room. It does NOT stop when it gets a match, but rather, finds all possible matches. It also tells how many commands on each object were matched, and what attributes they are in. It does NOT scan objects that you do not control and are not set VISUAL.
  
  This command any combination of these four switches:
     /room     --   just matches on your location and objects in it.
     /self     --   just matches on you and anything you're carrying.
     /zone     --   just matches on zones of your location and yourself.
     /globals  --   just matches on objects in the master room.
     
  If no switch is given, all locations are checked. <command> must be entered exactly as you would type it (so, to match the $-command $foo *: you must type '@scan foo <something>', not just '@scan foo').
  
See also: $-commands, EVALUATION ORDER
& @search
  @search [<player>] [<classN>=<restrictionN>[,...]][,<begin>,<end>]
  
  This command searches the database and lists objects which meet user specified search criteria. You can limit the scope of the search by specifying <begin> and <end> as the first and last dbrefs to search.
  
  If a <player> argument is supplied, only objects owned by that player will be listed, or all objects if "all" is used. Mortals attempting to match other players (aside from ZMPs whose @lock/zone they pass) or "all" will only get objects which they can examine.
  
  <class> and <restriction> arguments can be given to filter the match results. Possible <class>es include TYPE, NAME, ZONE, PARENT, EXITS, THINGS (or OBJECTS), ROOMS, PLAYERS, FLAGS, LFLAGS, POWERS, ELOCK, COMMAND, LISTEN, EVAL, EPLAYER, EROOM, EEXIT, and ETHING (or EOBJECT).

  If <class>=TYPE, possible <restriction>s include THING (or OBJECT), ROOM, EXIT, PLAYER, GARBAGE. This shows all objects of the specified type.
  
  If <class>=NAME, only objects whose name begin with the string <restriction> will be listed. If <class>=EXITS, OBJECTS, ROOMS or PLAYERS, only objects of that type whose name begins with <restriction> are listed.
  
  If <class>=ZONE, only objects in the zone <restriction> will be listed.
  If <class>=PARENT, only children of parent <restriction> will be listed.
  For ZONE and PARENT, <restriction> must be specified as a dbref number.
  
  Continued in 'help @search2'.
& @search2
  If <class>=FLAGS or LFLAGS, only objects with the list of flags specified by <restriction> will be listed. For FLAGS, flags to match should be given as a string of single flag letters, with appropriate case. For LFLAGS, flags to match should be given as a space-separated list of flag names.

  If <class>=POWERS, only objects with the given powers are listed. <restriction> should be a space-separated list of power names.

  If <class>=ELOCK, only objects that pass the given lock string (as in help @lock) are listed. For purposes of indirect locks (@#123), 'search' is the name of the lock.
  
  If <class>=EVAL, only objects for which <restriction> evaluates to a true boolean value will be listed. The token '##' in <restriction>, which is a function, is replaced by each dbref sequentially. Classes EPLAYER, EROOM, EEXIT, and ETHING work like EVAL but are restricted to a single type.
  
  Continued in 'help @search3' for more.
& @search3
  If <class>=MINDB, only objects with dbrefs of <restriction> or higher will be listed. If <class>=MAXDB, only objects with dbrefs of <restriction> or lower will be listed.

  If <class>=START, then @search will start returning results at the <restriction>th result.

  If <class>=COUNT, then @search will only return up to <restriction> results.

  If <class>=COMMAND, then @search will only return objects that respond to <restriction> as an $-command.

  If <class>=LISTEN, then @search will only return objects that respond to <restriction> through a listen.

  Continued in 'help @search4'.
& @search4
  
  For the class TYPE=PLAYER, and for PLAYER=<player-name>, anyone may obtain information on any player. In all other cases, wizards may obtain information about other players, and players who pass a ZMP's zone-lock may obtain information about the ZMP.

  If multiple <class> and <restrictions> are given, objects must meet all criteria in order to match successfully. The exception to this is that if multiple 'type' searches (PLAYER, EROOM, etc) are used, only the last type given is used in the search.

  @search is only mildly computationally expensive for most of the search classes. Computationally expensive searches are the evaluating searches (EVAL, EPLAYER, ETHING, EROOM, EEXIT), the attribute pattern searches (COMMAND, LISTEN), and ELOCK searches which perform evaluation searches (attr/value) or indirect locks (@obj/lock). These searches all cost a number of pennies (the exact amount is configurable; see @config find_cost).
  
  See 'help @search5' for some examples.
See also: lsearch(), @find
& @search5
  Examples:
    @search all type=player,flags=W      <-- list all Wizard players
    @search type=room     <-- list all rooms owned by me.
    @search zone=#50      <-- list all objects belong to zone #50.
    @search Joe eval=1,100,200   <-- list objects from #100-#200 owned by Joe.
    @search eval=gt(money(##),10)     <-- list all objects owned by me worth more than 10 coins.
    @search all elock=FLAG^WIZARD|FLAG^ROYALTY   <-- list all objects with wizard or royalty flags.
    @search wizard_bc command=+who    <-- Forgot what object has your +who?

& @set
  @set <object>=[!]<flag> [[!]<flag> ...]
  @<pre-defined attribute> <object>=<value>
  @set <object>=<attribute>:<value>
  @set <object>/<attribute>=[!]<attrflag>
  
  The first form sets (or unsets) flag(s) on <object>. See 'help flags'.
    Ex: @set me=VISUAL
  Flags may be specified by full name (recommended) or by flag character.
  Flags are set or reset in the order supplied.

  The second form sets a pre-defined attribute on <object>
    Ex: @fail Heavy Box=You can't pick that up.

  The third form sets an arbitrary attribute with <value> on <object>. You can also do this with &<attribute> <object>=<value>
    Ex: @set Test Object=random:This is a random attribute.
        &random Test Object=This is a random attribute.
  An important difference between these two forms is that @set will always evaluate the <value> before setting it on <object>, while the &<attribute> form will not evaluate when entered directly by a player in his client (and is usually what you want).
  
  The fourth form sets (or unsets) an attribute flag on the specified attribute. See 'help attribute flags'.
  
See also: ATTRIB_SET, attrib_set(), set()
& ATTRIB_SET
& @_
  &<attr> <object>[=<value>]
  @_<attr> <object>[=<value>]
  ATTRIB_SET/<attr> <object>=<value>
  
  The &<attr> and @_<attr> commands can be used to set or clear an attribute from an object. When entered directly from a client, they do not evaluate the <value>.
  
  ATTRIB_SET is the internal command which powers &attr and @_attr setting; it cannot be used directly, but can be restricted or @hook'd to change the behaviour of &attr/@_attr-setting.

See also: @set, attrib_set()
& @sex
  @sex <player>[=<gender>]

  You can use this command to set yourself or any of your objects to be male, female, neuter, or plural. The SEX attribute is used for pronoun substitution by the MUSH, and anything not recognizable will be treated as neuter. 

  Examples:
    > @sex me=Male
    > @sex me=Female
    > @sex me=Woman
    > @sex me=They
    > @sex me=Plural
    > @sex me=No thank you (silly, but possible)

See also: GENDER, subj(), poss(), aposs(), obj()
& @shutdown
  @shutdown[/panic][/reboot][/paranoid]

  @shutdown shuts down the game. It may only be used by Wizards.

  @shutdown/panic performs a panic shutdown of the game, using a seperate database file, not the normal one. It may only be used by God.

  @shutdown/reboot restarts the game without disconnecting the users. This is necessary to load changes to the MUSH's configuration files (mush.cnf, restrict.cnf, etc), though not changes to names.cnf, which take effect without a reboot.

  If the /paranoid switch is added, the shutdown dump will be a paranoid dump (see @dump).
& @sitelock
  @sitelock
  @sitelock/name <name>
  @sitelock[/player] <host-pattern>=<options>[, <name>]
  @sitelock[/<ban|register>][/player] <host-pattern>
  @sitelock/check <host>
  @sitelock/remove[/player] <string>

  The @sitelock command adds rules to the access.cnf file, controlling a host's level of access to the MUSH, or adds banned player names to the names.cnf file. Only Wizards may use @sitelock.
  
  @sitelock without arguments lists all sites in access.cnf. Rules are processed in the order listed, and the first matching rule is applied. @sitelock/check tells you which rule will match for a given <host>.

  @sitelock/name adds a name to the list of banned player names. Use !<name> to remove a name from the list.

  @sitelock <host-pattern>=<options>[, <name>] controls the access options for hosts which match <host-pattern>, which may include wildcard characters "*" and "?". See help @sitelock2 for the list of options, and help @sitelock3 for an explanation about the name argument.

  For backward compatibility, @sitelock/ban is shorthand for setting options "!connect !create !guest", and @sitelock/register is shorthand for options "!create register".
  
  If the /player switch is given, <host-pattern> is treated as a player name, and sitelock rules are added for that player's LASTIP and LASTSITE, if set.

Continued in 'help @sitelock2'
& @sitelock2

  Sitelock allow/deny options:
   connect   --  allow this site to connect to non-guest players
   !connect  --  don't allow this site to connect to non-guest players
   guest     --  allow this site to connect to guest players
   !guest    --  don't allow this site to connect to guest players
   create    --  allow this site to create players
   !create   --  don't allow this site to create players
   default   --  allow any of the above
   none      --  don't allow any of the above
   !god      --  God can't connect from this site.
   !wizard   --  Wizards can't connect from this site.
   !admin    --  Wizards and Royalty can't connect from this site.

  Allow/deny options not set are assumed to be allowed.

  Sitelock special options:
   register    -- allow this site to use 'register <name> <email>' at the connection screen to register players. Players will be emailed their character's password. This should be used with !create to be effective.
   suspect     -- set all players who connect from this site SUSPECT.
   deny_silent -- don't log failed access attempts from this site.
   regexp      -- Treat the hostname pattern as a regular expression instead of a wildcard pattern.

Continued in 'help @sitelock3'
& @sitelock3
  If you specify a character name after the options, the options are only checked if the host pattern matches, AND the character being checked for connect support matches the one you gave. Use it only with connect and !connect options, since they're the only ones where an existing character is used.

  For example, to disallow anyone from connecting to 'Twink' from one domain, but to allow connections to the character from others, use something like:

    > @sitelock *.somesite.com=!connect,Twink

  If you want to disallow connections to a character from anywhere, use @newpassword or @sitelock *=!connect,Twink.

  @sitelock/remove will delete entries that were added with @sitelock if their host-pattern matches <string> exactly. If the /player switch is given, <string> is treated as a player name, and entries whose host-patterns match the player's LASTIP or LASTSITE addresses exactly will be deleted.
& @SLAVE
  @slave/restart [info|ssl]

  @slave is a wizard-only command used to control the various subprocesses used by the mush to do various things. The only switch it currently takes is /restart, which will shut down and relaunch the slave daemon process in question.

  Two different daemons are used:

  info: Resolves IP addresses into host names whenever a new connection is established.
  ssl : Handles encrypted SSL connections across @shutdown/reboots. 

& @SOCKSET
& SOCKSET
  SOCKSET [<option>=<value>]
  @sockset [<descriptor>][=<option>, <value>[, ..., <optionN>, <valueN>]]

  SOCKSET is a socket command which sets or queries socket-specific options. These options are usually set automatically, or negotiated by the MUSH and your client, but this command lets you override those settings.
  
  With no args, SOCKSET shows the current value of the socket options. With an <option>=<value> pair, it attempts to set the given option.
  
  @sockset is a similar in-game command, but can specify which descriptor to change options for, and can set multiple options at once. Only Wizards can change the options for other players' descriptors. <descriptor> defaults to your least-idle descriptor, when used by a player; for non-players, it has no default.

  Options:
    colorstyle:      See 'help colorstyle'
    outputprefix:    Same as OUTPUTPREFIX
    outputsuffix:    Same as OUTPUTSUFFIX
    pueblo:          Sets Pueblo-related options. If value has md5=...", then it will set the pueblo checksum. If empty, Pueblo mode is turned off.
    telnet:          Yes or no, to enable/disable telnet negotiation
    width:           Set your width(), same as SCREENWIDTH
    height:          Set your height(), same as SCREENHEIGHT
    terminaltype:    Your terminal type, used by terminfo()
    prompt_newlines: Set whether a newline is shown after prompts from @prompt, same as PROMPT_NEWLINES
    stripaccents:    Strip accents for this connection. Like the NOACCENTS flag, but connection-specific. Set by default on connections which negotiate charset as [US-]ASCII

  Note that changing 'telnet' or 'pueblo' may stop your client from parsing or displaying output correctly; only use if you know what you're doing!
  
See also: SOCKET COMMANDS, terminfo(), Pueblo, colorstyle, @prompt
& COLORSTYLE
  SOCKSET colorstyle=<value>
  @SOCKSET [me|<descriptor>]=colorstyle,<value>

  You can override the color format you receive from PennMUSH. Normally, PennMUSH tries to guess what your client is capable of through telnet negotiation and your player flags. @sockset lets you inform PennMUSH that your client can support more colors than expected.

  Colorstyle options are:

    plain: Plain text. No markup whatsoever.
    hilite: You only receive hilite text. No colors, just ansi-hilite.
    16color: You receive hilite text and the ANSI 16 colors.
    xterm256: You receive xterm-style 256 colors for text and background.
    auto: go back to what PennMUSH determined was your client's capabilities.

  In the event that your client receives a color that it is unable to display, PennMUSH will attempt to find a close match that can fit your client's capabilities.

See also: ANSI, COLOR, XTERM256, @sockset
& @SPEECHMOD
  @speechmod <object>[=<modifier>]
  
  When set, this attribute modifies everything <object> says, poses, semiposes and @emits. The original text spoken/posed/emitted is passed as %0, with %1 passed as " (for say), : (for pose), ; (for semipose) or | (for @emit).
  
  If the attribute evaluates to an empty string, the original text will be used. Otherwise, the result of the attribute is used.
  
  Example:
    > @speechmod me=ucstr(%0)!
    > say hello
    You say, "HELLO!"
    > pose waves
    Bob WAVES!
    
    > @speechmod me=switch(%1,",ucstr(%0),:,lcstr(%0))
    > say Test
    You say, "TEST"
    > pose Test
    Bob test
    > @emit Test
    Test
    
See also: say, pose, @emit, @chatformat, @pageformat
& @mapsql
  @mapsql[/notify][/colnames][/spoof] <obj>/<attr>=<query>

  This command issues an SQL query if the MUSH supports SQL and can connect to an SQL server. You must be WIZARD or have the Sql_Ok power to use @sql.

  For each row returned by the query, the action list in <obj>/<attr> is queued, with row number passed as %0 and the columns passed as %1-%9 and v(10) to v(29). Row numbers start at 1. The MUSH will also set named arguments, with arg names matching the SQL field names. These are accessible as r(<name>, arg).

  The /notify switch causes the executor to do queue "@notify me" after all the rows are processed. Note that this is the object running "@mapsql", and not <obj>.

  The /colnames switch causes @mapsql to first queue the obj/attr with row number (%0) set to 0 and args %1 to v(29) being the column names.
  
  By default, the object using @mapsql will be the enactor (%#) for the triggered attribute. However, if you control <object>, the /spoof switch can be used to preserve the current enactor.
  
  Examples:
    > &desctable me=think align(30 20 4 10 10,%0,%1,%2,%3,%4)
    > @mapsql me/desctable=DESCRIBE table_name
    
    > &showresult me=@pemit %#=%0. [r(name, arg)] ([r(age, arg)])
    > @mapsql me/showresult=SELECT `name`, `age` FROM `people`

See also: @sql, sql(), sqlescape(), mapsql()
& @sql
  @sql <query>

  This command issues an SQL query if the MUSH supports SQL and can connect to an SQL server. You must be WIZARD or have the Sql_Ok power to use @sql.

  Generally, the sql() function is more useful for coding, as it delimits its return values, but @sql is handy for INSERT-type queries and quick checks. If you pass arbitrary data to @sql, be sure you call sqlescape() on it; see the example in help sql().

  Example:
    > @sql SHOW TABLES

See also: sql(), sqlescape(), mapsql(), @mapsql
& @startup
  @startup <object>[=<action list>]

  Sets the list of actions on <object> that will happen whenever the MUSH is restarted. This lets you start up objects that need to be running continuously. It is also useful for setting up @functions and @hooks, which are not saved across restarts.
  
  @startup is also triggered when an object is @restarted or @undestroyed.
  
  Note that @startups are NEVER inherited from parent objects.
  
See also: @restart, @undestroy, ACTION LISTS, @function, @command, @hook
& @stats
  @stats [<player>]
  @stats/tables
  @stats/flags
  @stats/chunks
  @stats/regions
  @stats/paging
  @stats/freespace

  In its first form, display the number of objects in the game broken down by object types. Wizards can supply a player name to count only objects owned by that player.

  @stats/tables displays statistics on internal tables.
  @stats/flags displays statistics about the flag and power system.

  In the remaining forms, display statistics or histograms about the chunk (attribute) memory system.
& @sweep
  @sweep [connected | here | inventory | exits ]
 
  @sweep gives you a list of all nearby objects that are listening, including the room you are in and the objects you are carrying. Most objects only listen for a particular string or phrase, so they normally do not pose a problem if you need privacy. You will have to be careful of players and puppets since they will hear everything you say and do. (And might post the same to r.g.m!) AUDIBLE exits are also shown on an ordinary sweep, if the room is also AUDIBLE. (Audible exits aren't active unless the room is audible).
 
  The four command options can also be used as switches (i.e., you can use "@sweep/connected" instead of "@sweep connected"). If the connected flag is given, only connected players and puppets owned by connected players will be shown in the @sweep. The "here" and "inventory" flags check only your location or inventory, respectively. "exits" only checks for AUDIBLE exits.

See also: @scan
& @switch
& @select
  @switch[/<switch>] <string>=<expr1>, <action1> [,<exprN>, <actionN>]... [,<default>]
  @select <string>=<expr1>, <action1> [,<exprN>, <actionN>]... [,<default>]
  
  For those of you familiar with programming, these command acts like if/then/else or switch/case. It compares <string> against whatever each <expr> evaluates to. If <string> and <expr> match, the action list associated with that <expr> is carried out. If no match is found, the <default> action list is carried out. @switch runs <action>s for all matching <expr>s by default, while @select only runs the <action> for the first matching <expr>.

  If <expr> is a regexp or a wildcard glob, then $0-$9 will be set with capture data. (In wildcard globbing, every wildcard captures.)

  The string "#$" in <action>'s will be replaced with the evaluated result of <string> before it is acted on. Note that this replacement happens BEFORE the <action> is queued and executed, and does not work well in nested switches. It is recommended that you use the %$N substitution, or the stext() function, instead.
  
  @switch/all runs <action>s for all matching <expr>s. Default for @switch.
  @switch/first runs <action> for the first matching <expr> only. Same as @select, and often the desired behaviour.
  @switch/notify queues "@notify me" after the last <action>. 
  @switch/inline runs all actions in place, instead of creating a new queue entry for them.
  @switch/regexp makes <expr>s case-insensitive regular expressions, not wildcard/glob patterns.

  Continued in 'help @switch2'.
& @switch2

  When using @switch/inline, an @break in an <action> will stop the calling action list (and any further <action>s) from running. Each <action> will also be able to see/alter the q-registers for the calling action list. The following switches can be used with /inline to alter this behaviour:
   /nobreak:  @breaks in <action> do not effect to the calling action list
   /localize: q-registers are saved before each <action> is run, and restored after it completes
   /clearreg: q-registers are all reset before each <action> is run. Most useful when used in combination with /localize.
              
  @switch/inplace is an alias for @switch/inline/nobreak/localize.

  See 'help @switch3' for examples.
See also: switch wildcards, switch(), @if, @break, stext(), slev()
& @switch3
  Examples: 
    > &SWITCH_EX thing=$foo *: @switch %0=*a*, :acks, *b*, :bars, :glurps
    > foo abc
    thing acks
    thing bars
    > foo xxx
    thing glurps

    > &SWITCH_EX thing=$foo *: @switch/first %0=*a*, :acks,*b*, :bars, :glurps
    > foo abc
    thing acks

    > &SWITCH_EX thing=$test: @switch hasflag(%#,PUPPET)=1, say Puppet!, say Not Puppet!
    > test
    thing says, "Not Puppet!"

    > &SWITCH_EX thing=$foo *: @switch %0=*a*,say Before: '$0'. After: '$1'
    > foo foobarbaz
    thing says, "Before: 'foob'. After: 'rbaz'
    
  Continued in 'help @switch4'
& @switch4
  Examples: 
    > &SWITCH_EX me=$foo *:think before ; @switch %0=1,think one ; think after
    > foo 1
    thing before
    thing after
    thing one

    > &SWITCH_EX me=$foo *:think before ; @switch/inline %0=1,think one ; think after
    > foo 1
    thing before
    thing one
    thing after
& @teleport
  @teleport[/<switches>] [<object>=]<destination>
  @teleport/list[/<switches>] <object-list>=<destination>

  Teleports <object> to <destination>. <object> can be a player, thing or exit, and defaults to yourself. (Exits must be specified by dbref, things or players can be specified by name.) The destination must be either JUMP_OK or controlled by you, and you must either control <object> or <object>'s current location. Also, the destination, if a room, cannot be teleport-locked against <object>. Mortals cannot teleport HEAVY objects. If the destination is a room with a drop-to, <object> may go to the drop-to room instead.
  
  If the /list switch is given, each object specified in <object-list> will be teleported to <destination> instead. Names containing spaces should be enclosed in "double quotes".
  
  Admin and those with the tport_anything power can teleport an object even if they don't control it. Those with tport_anywhere can teleport objects to any destination. You can also teleport an exit to any room if you have the Open_Anywhere power.

  Privileged players who teleport a player to another player send them to the location of the target, unless the /inside switch is used, in which case they are sent to the inventory of the target.
  
  Continued in 'help @teleport2.
& @teleport2
  Teleporting to an exit works the same as using "goto". If you don't control the exit and don't have the tport_anywhere power, either you or <object> must be nearby the exit.

  Teleportation from a room can be stopped by setting the NO_TEL flag. Royalty and Wizards can _always_ teleport to any location, regardless of NO_TEL or teleport locks.

  Teleportation triggers the @oxtport/@tport/@otport/@atport attributes, unless <room> is an exit or the /silent switch is given. With @oxtport, %0 is the dbref of the object causing the dbref. The others, in addition to %0, get the former location of the object that was teleported passed in %1.

  As a special case, using "home" as the <room> has the same effect as the home command, and does not act like a normal teleport.

See also: JUMP_OK, NO_TEL, Z_TEL, @tport, @lock
& @trigger
  @trigger[/spoof][/clearregs] <object>/<attribute>[=<arg0>, ..., <arg29>]

  @trigger queues an action list stored in an attribute. It can also pass values to that attribute on the stack, as %0 to %9 and r(0,args) to r(29,args).
  
  You must control <object>, or it must be Link_OK and you must have the same owner, to trigger an attribute on it.
  
  The triggered attribute is queued - the new action list is not run instantly. The action list is executed by <object>, not by the object using @trigger.
  
  Continued in 'help @trigger2'.
& @trigger2

  By default, the object using @trigger will be the enactor (%#) for the triggered attribute. However, if you control <object>, the /spoof switch can be used to preserve the current enactor. This is useful for global commands with @a* verb attributes.
  
  Q-registers set at the time @trigger is run will be copied and made available in the triggered attribute, unless the /clearregs switch is given.

  See 'help @trigger3' for examples.
See also: @include, ufun(), VERBS
& @trigger3
  Examples:
    > &GREET me=POSE waves hi.
    > @trigger me/GREET
    Cyclonus waves hi.

    > &GREET me=POSE waves to %0! ; say Hi there, %1.
    > @trigger me/GREET=Gears, Arcee
    Cyclonus waves to Gears.
    You say, "Hi there, Arcee."

    > &foo Globals=$foo *: @assert setr(0,locate(%#,%0,*))=@nspemit %#=Who? ; @nspemit %#=You foo [name(%q0)]. ; @trigger %q0/AFOO
    > &AFOO Bar=:is foo'd by %n!
    > FOO BAR
    Bar is foo'd by Globals!

    > &foo Globals=$foo *: @assert setr(0,locate(%#,%0,*))=@nspemit %#=Who? ; @nspemit %#=You foo [name(%q0)]. ; @trigger/spoof %q0/AFOO
    > FOO BAR
    Bar is foo'd by Cyclonus!
& @ulock
& @uunlock
  @ulock <object>[=<key>]
  @uunlock <object>

  These commands set the Use lock for <object> to <key>, or clear the Use lock. They are deprecated, and should be replaced with 

    @lock/use <object>[=<key>]
  and
    @lock/use <object>

  The Use lock determines who is allowed to "use" the object or trigger any $-commands or ^-listens on the object.
  
  To only lock who can use $-commands, use @lock/command. To only lock who can trigger ^-listens, use @lock/listen.

  Example: if I want everyone but Bob to be able to use my toy, I would "@lock/use toy=!*Bob". If I want only Bob to be able to use it, I would "@lock/use toy==*Bob".

See also: @lock, use, locktypes
& @uptime
  @uptime[/mortal]
  
  This command, for mortals, gives the time until the next database dump. For wizards, it also gives the system uptime (just as if 'uptime' had been typed at the shell prompt) and process statistics, some of which are explained in the next help entry. Wizards can use the /mortal switch to avoid seeing the extra process statistics.

  Continued in 'help @uptime2'.
& @uptime2
  While the exact statistics displayed depends on the operating system of the game's server, typical things might include the process ID, the machine page size, the maximum resident set size utilized (in K), "integral" memory (in K x seconds-of-execution), the number of page faults ("hard" ones require I/O activity, "soft" ones do not), the number of times the process was "swapped" out of main memory, the number of times the process had to perform disk I/O, the number of network packets sent and received, the number of context switches, and the number of signals delivered to the process.

  Under Linux, memory usage is split into a number of different categories including shared libraries, resident set size, stack size, and some other figures. Also under linux, more information on signals is printed.

See also: @stats, @list
& @unlink
  @unlink <exit>
  @unlink <room>

  The first form of this command unlinks an exit from its destination room. Unlinked exits may be picked up and dropped elsewhere or relinked by anyone else. (Note that relinking an unlinked exit will @chown it to you if you do not already own it.)

  The second form removes the DROP-TO on the room.

See also: @link, DROP-TO
& @unlock
  @unlock[/<switch>] <object>

  Removes the lock on <object>. It can take as many switches as @lock can. 

See also: @lock, locktypes
& @version
  @version

  Tells the player the name of the MUSH, which version of the code is currently running on the system, when it was compiled, and when the last restart was. It may also include some other information, including the MUSH's website address and the GIT revision, if available.
  
See also: version(), numversion()
& @verb
  @verb <victim>=<actor>,<what>,<whatd>,<owhat>,<owhatd>,<awhat>,<args>
  
  This command provides a way to do user-defined verbs with associated @attr/@oattr/@aattr groups. Invoking it does the following:
  
  <actor> sees the contents of <victim>'s <what> attribute, or <whatd> if <victim> doesn't have a <what>.
  Everyone in the same room as <actor> sees the contents of <victim>'s <owhat> attribute, with <actor>'s name prepended, or <owhatd>, also with <actor>'s name prepended, if <victim> doesn't have an <owhat>.
  <victim> executes the contents of his <awhat> attribute.
  
  By supplying up to 29 <args>, you may pass those values on the stack (i.e. %0, %1, %2, etc. up through %9, and r(0,args) to r(29,args)).
  
  Continued in 'help @verb2'.
& @verb2
  In order to use this command, at least one of the following criterion must apply:
    1. The object which did the @verb is a wizard.
    2. The object which did the @verb controls both <actor> and <victim>
    3. The thing which triggered the @verb (such as through a $-command on the object which did the @verb) must be <actor>, AND the object which did the @verb must be either privileged or control <victim> or <victim> must be VISUAL.
  
  See 'help @verb3' for examples.
See also: USER-DEFINED COMMANDS, STACK, VERBS, @trigger
& @verb3
  Examples:
  
  > &VERB_EXAMPLE Test Object=$test:@verb me=%#,TEST,You just tested.,OTEST,just tested the example.,ATEST,%n
  > test
  You just tested.
  [others see] Cyclonus just tested the example.

  > &TEST Test Object=You have just tested this object!
  > &ATEST Test Object=@emit %0 has failed!
  > &OTEST Test Object=tests test object.
  > test
  You have just tested this object!
  [others see] Cyclonus tests test object.
  Cyclonus has failed!

  See 'help @verb4' for another example.
& @verb4
  In order to make this into a global command that anyone can use, we need to put it on a WIZARD object in the Master Room. 

  > &DO_TEST Global=$test *: @assert setr(0,locate(%#,%0,n))=@pemit %#=I don't see that here. ; @verb %q0=%#, TEST, You test [capstr(%0)]., OTEST,tests [capstr(%0)]. ,ATEST
 
  > &TEST Example=You test this fun example.
  > &ATEST Example=POSE has been tested!
  > test example
  You test this fun example.
  [others see] You test Example.
  Example has been tested!
& @wait
  @wait[/until] <time>=<command_list>
  @wait <object>=<command_list>
  @wait[/until] <object>/<time>=<command_list>

  The basic form of this command puts the command list (a semicolon-separated list of commands) into the wait queue to execute in <time> seconds. If the /until switch is given, the time is taken to be an absolute value in seconds, not an offset.
  
  The second form sets up a semaphore wait on <object>. The enactor will execute <command_list> when <object> is @notified.
  
  The third form combines the first two: the enactor will execute <command_list> when <object> is @notified or when <time> passes, whichever happens first.
 
  More forms that support semaphores on arbitrary attributes are described in 'help @wait2'.

See also: SEMAPHORES, @drain, @notify
& @wait2
  Normally, a semaphore wait depends on the SEMAPHORE attribute of the object in question. However, it is useful to be able to use other attributes as semaphores, so one object can be used as the blocker for multiple different things at once. Possible attribute names aren't completely arbitrary. See 'HELP SEMAPHORES5' for details.

  The syntax for these are:
 
  @wait <object>/<attribute>=<command list>
  @wait[/until] <object>/<attribute>/<time>=<command list>

  You cannot do a non-timed semaphore on an attribute with a numeric name, as that is taken as a timeout instead.

  Continued in 'help @wait3'.
& @wait3
  @wait/pid <pid>=<seconds>
  @wait/pid <pid>=[+-]<adjustment>
  @wait/pid/until <pid>=<time>

  The /pid switch can be used to alter the timeout of entries in the wait and semaphore queues. You can set a new wait time, increase or decrease the current time, or set a new absolute time in seconds.

  You must control the object doing the wait, or have the halt @power.
& @wall
& @rwall
& @wizwall
  @wall[/emit][/noeval] <message>
  @rwall[/emit][/noeval] <message>
  @wizwall[/emit][/noeval] <message>

  @wall sends <message> to all connected players. @rwall only sends the message to connected wizards and royalty, and @wizwall is seen only be wizards.
  
  <message> can be prefixed with : or ; to pose or semi-pose it, respectively, or the /emit switch can be given to emit the message. If <message> begins with a " and the chat_strip_quote option is on, the " will be stripped.
  
  The message is prefixed with the value of the wall_prefix, rwall_prefix or wizwall_prefix options, depending on the command used.

See also: @wizwall, @rwall
& @warnings
  @warnings <object>=<warning list>

  This command will set the types of warnings which should be reported on an object or to a player. You must control the object to use this command.

  When an object is checked for warnings (via @wcheck by the owner, or automatically), only warnings which are set to be reported on the object will be reported. If no warnings are set on the object, the owner's warning settings will be used. When admin use @wcheck to check non-owned objects, their personal warnings are always used.

  For a list of warnings, see 'help warnings list'. 
  For examples, see 'help @warnings2'.
  
See also: @wcheck, NO_WARN
& @warnings2

  Example 1: Normal building situations
  Most people will simply want to leave their @warnings set to "normal" and their objects' @warnings set to "none". They will then receive normal warnings for all their objects.

  Example 2: Warning-lover
  People who find warnings very helpful (like heavy builders) may want to set their personal @warnings to "extra" or "all", and keep their objects' warnings at "none". If a specific object should be treated less strictly, set that object's @warnings differently. If an object shouldn't be warned on at all, set the NO_WARN flag on the object.

  Continued in 'help @warnings3'.
& @warnings3
  Example 3: Warning-hater
  People who prefer not to be warned except for specific object may set their personal @warnings to "none" and set the @warnings on those objects to appropriate levels.

  Example 4: I need some peace!
  Players who @set themselves NO_WARN will receive no warnings ever until they unset the flag.
& @wcheck
  @wcheck <object>
  @wcheck/all 
  @wcheck/me

  The first form of the command performs warning checks on a specific object. The player must own the object or be see_all. When the owner runs the command, the @warnings of the object are used to determine which warnings to give. If the object has no @warning's set, the @warnings of the owner are used. When a non-owner runs the command, the @warnings of the non-owner are used.

  The second form of the command runs @wcheck on every object in the database and informs connected owners of warnings. It is usually automatically run by the MUSH at intervals. Only Wizards may use @wcheck/all.

  The third runs it on all objects the player owns that aren't set NO_WARN.

See also: @warnings, WARNINGS, NO_WARN
& @whereis
  @whereis <player>

  If <player> is not set UNFINDABLE, this command will tell you where the player is. It will also inform the player that you attempted to locate their position, and whether you succeeded or not.

  To avoid being found this way, just do: @set me=UNFINDABLE

  Example: 
    > @whereis Moonchilde

See also: UNFINDABLE, loc()
& @wipe
  @wipe <object>[/<attribute pattern>]
  
  This command clears attributes from <object>, with the exception of attributes changeable only by wizards, and attributes not controlled by the object's owner (i.e. locked attributes owned by someone else). Only God may use @wipe to clear wiz-changeable-only attributes. The SAFE flag protects objects from @wipe.
 
  If no <pattern> is given, this gets rid of all the attributes, with exceptions as given above. If <pattern> is given, it gets rid of all attributes which match that pattern. Note that the restrictions above still apply.

  When wiping an attribute that is the root of an attribute tree, all attributes in that tree will also be removed.
& @zemit
  @zemit[/silent|/noisy] <zone>=<message>

  Emits a message to all rooms in <zone>. You must have control <zone> in order to use this command.
  
  The /silent switch suppresses the confirmation message, and /noisy causes it to be shown. With neither switch, the silent_pemit @config option determines whether or not the message is shown. The confirmation message is only shown if you are not in a room which would receive <message>.
  
See also: @nszemit, zemit(), zone(), zwho(), ZONES
& ahelp
& anews
  ahelp [<topic>]
  anews [<topic>]

  These commands, if enabled, show the admin-only help or news files for the MUSH. Only Wizards and Royalty may use them.

& brief
  brief[/opaque] [<object>]

  This command works like an abbreviated version of "examine", showing information about an object including its name, owner, zone, type, flags and powers, locks, channels, warnings, home and location. Unlike "examine", it does not print out all the attributes on the object. It will include the contents of <object>, unless the /opaque switch is given.
  
  <object> defaults to "here".

See also: examine
& cd
& ch
& cv
  cd <name> <password>
  ch <name> <password>
  cv <name> <password>

  Not really MUSH commands, but commands available at the connect screen. Wizards can use 'cd' instead of 'connect'; the new connection will be hidden (as per @hide), and the player will be set DARK. Mortals set HEAR_CONNECT will not hear dark wizards connect.
  
  Wizards, Royalty, and those with the Hide @power can use 'ch' to connect with the new connection hidden (as per @hide).
  
  Connecting using 'cv' causes the Dark flag to be cleared prior to connection messages being broadcast.
  
  None of those commands affect the hidden status of other connections, if you're reconnecting.
  
See also: DARK, @hide
& OUTPUTPREFIX
& OUTPUTSUFFIX
  OUTPUTPREFIX <string>
  OUTPUTSUFFIX <string>

  Sets your output prefix or suffix. These strings will be shown before and after the output of any command that you initiate, respectively. They are primarily useful for bots and the like.

& IDLE
  IDLE [<string>]

  This command does nothing. It does not reset a connection's idle time. It is useful for people who are connecting from behind a NAT gateway with a short fixed timeout; if you're in this situation, have your client send the IDLE command every minute or so, and the NAT connection won't time out (but you won't appear, to other players, to be active).
  
  Some routers will only consider a connection alive if text is received, as well as sent. If you give a <string> with the IDLE command, that same <string> will be sent back to you for this purpose.
  
See also: KEEPALIVE, @idle
& teach
  teach <command>
  teach/list <action list>
  
  The teach command shows its argument (unparsed) to others in your location, and then executes it as a command. If the /list switch is given, it will run an <action list> of commands in much the same way as @triggering an attribute. Otherwise, it executes a single <command>, exactly as if you'd entered <command> from your client. Useful for helping newbies and demonstrating commands.

    > say To do a pose, use :<action>
    You say "To do a pose, use :<action>"
    > teach :waves hello.
    Javelin types --> :waves hello.
    Javelin waves hello.

    > teach "[sort(c b a)]
    Javelin types --> "[sort(c b a)]
    Javelin says, "a b c"
  
    > teach/list @switch 1=1, say Third; say First; @break 1; say Second
    Javelin types --> @switch 1=1, say Third; say First; @break 1; say Second
    You say, "First"
    You say, "Third"

See also: @trigger, @include
& drop
  drop <object>

  Drops <object>, if you are presently carrying it. If the room the object is dropped in has a DROP-TO set, the object may automatically be sent to another location. 

  In order to drop an object, you must pass it's Drop lock and your location's DropIn lock.

See also: empty, get, STICKY, DROP-TO
& enter
  enter <object>

  Used to enter a thing or player. You can only enter an object if you own it or if it is set ENTER_OK. You must also pass the enter-lock, if it is set. Entering an object triggers is @enter/@oenter/@oxenter messages and its @aenter actions. If you fail the enter-lock, the object's @efail/@oefail/@aefail messages and actions are triggered.

  Insides of objects are best used for vehicles, or storage spaces when you don't have a home. You can describe the interior of an object differently from its exterior by using @idescribe.

See: @enter, @efail, @ealias, leave, @lock, @idescribe, INTERIORS
& examine
  examine[/<switches>] <object>[/<attribute>] 
  
  Displays all available information about <object>. <object> may be an object, 'me' or 'here'. You must control the object to examine it. If you do not own the object, or it is not visible, you will just see the name of the object's owner. May be abbreviated 'ex <object>'. If the attribute parameter is given, you will only see that attribute (good for looking at code). You can also wild-card match on attributes. 
  The * wildcard matches any number of characters except a backtick (`).
  The ? wildcard matches a single character except a backtick (`).
  The ** wildcard matches any number of characters, including backticks.
  For example. to see all the attributes that began with a 'v' you could do ex <object>/v**
  
  The /brief switch is equivalent to the 'brief' command.
  The /debug switch is wizard-only and shows raw values for certain fields in an object. 
  The /mortal switch shows an object as if you were a mortal other than the object's owner and is primarily useful to admins. This switch ignores the object's VISUAL flag (but not its attribute flags)
  The /parent switch show attributes that would be inherited from the object's parents, if you have permission to examine the attributes on the parent.
  The /all switch shows the values of VEILED attributes.
  The /opaque switch omits contents listings.

See also: ATTRIBUTE TREES, brief, lattr()
& follow
  follow <object>

  If you pass the object's follow lock, you begin following it. As the object moves around (except if it @teleports away or goes home), you will automatically move around with it, so long as you pass all the locks and enter/leave locks on the exits and things the object moves through. This doesn't prevent you from going somewhere else on your own.

See also: unfollow, dismiss, desert, followers(), following(), @follow, @ofollow, @afollow
& dismiss
  dismiss <object>
  dismiss

  The dismiss command stops <object> from following you. If no object is given, it stops everyone from following you.

See also: follow, unfollow, desert, followers()
& desert
  desert <object>
  desert
 
  The desert command stops <object> from following you and stops you from following <object>. That is, it's shorthand for 'unfollow <object>' and 'dismiss <object>'. If no object is given, it stops everyone from following or leading you.

See also: follow, unfollow, dismiss, followers(), following()
& empty
  empty <object>

  The empty command attempts to move all the contents of <object> to <object>'s location. You must either be holding <object> (in which case the command is like getting <object>'s <item> for each item) or be in the same location as <object> (in which case the command is like getting <object>'s <item> and dropping it).

  The empty command assumes that all <object>'s items pass through the hands of the player running the command. Therefore, the same kinds of locks and messages that are applied in a possessive get (and, possibly, a drop) are applied to each item in <object>. It is therefore possible to fail to empty an object for many reasons, even when you could do so using "extraphysical" methods (teleporting items, forcing the object to drop them, or forcing the items to leave the object.)

See also: get, drop
& get
& take
  get <object>
  get <box>'s <object>

  The first form of this command lets you pick up <object> from your current location. The second form allows you to take <object> from inside <box>'s inventory.
  
  In both cases, you must pass <object>'s Basic @lock, and the @lock/take of it's location.
  
  To get an object from someone else's inventory, the possessive_get @config option must be true (and, if <box> is a disconnected player, so must possessive_get_d). <box> must also be set ENTER_OK.
  
  'take' is usually an alias for the 'get' command.

See also: @lock, ENTER_OK, give, drop, @success, inventory
& @buy
& @abuy
& @obuy
  @buy <object>[=<message>]
  @obuy <object>[=<message>]
  @abuy <object>[=<message>]
  
  These attributes contain the message shown to a player who successfully buys something from <object> using the "buy" command, the message shown to others in the room when something is bought from <object> (prefixed with the buyer's name), and the actions to be taken by <object> when something is bought from it, respectively. Each attribute is passed the item being purchased as %0 and the amount paid for it as %1.

  Example:
    > @buy Vendor=udefault(me/buy`%0,You buy %0 for %1 [money(%1)]., %0, %1)
    > @obuy Vendor=hands some money to [name(me)] for [art(%0)] %0.
    > @abuy Vendor=:goes into the storeroom. ; @wait 2=:returns with %n's %0.

See also: buy, @pricelist, MONEY, @lock, VERBS, @cost, give
& @pricelist
  @pricelist <object>=<item1>:<price1>[,<price2>][ <item2>:...]

  The PRICELIST attribute is a space-delimited list of item names and prices that are checked when the 'buy' command is run.
  
  An item name may have '_'s where the player would use a space in the name.

  A price is either a number (20), a range of numbers (10-30), or a minimum number (10+). An item can also have several different prices, separated by commas.
  
  A player must pass <object>'s @lock/pay in order to purchase from it.

  Example::
    > @PRICELIST vendor=mansion:1000+ large_house:100-200 house:20,30,50

See also: buy, @buy, MONEY, @cost, give, @lock
& buy
  buy <item>[ from <vendor>][ for <cost>]

  When you try buying an item, PRICELIST attributes on nearby objects (or <vendor> if given) will be checked for matching item:costs. If <cost> is given, the first item that matches that cost will be purchased. Otherwise, the first matching item that you can afford will be purchased. You must pass the vendor's @lock/pay in order to purchase items.

  If the pricelist match contains a list of prices, ITEM:30,20,10, the first one you can afford will be the resulting price.

  Example:
    > @PRICELIST vendor=coke:20 pepsi:20
    > &drink`coke vendor=You enjoy a delicious coke.
    > &drink`pepsi vendor=It tastes like a funny coke.
    > @BUY vendor=u(drink`%0)
    > buy coke
    You enjoy a delicious coke.

See also: @BUY, @PRICELIST, give, @COST
& give
  give[/silent] <recipient>=<number>
  give[/silent] <number> to <recipient>
  give <recipient>=<object>
  give <object> to <recipient>

  The first two forms of this command give <number> pennies to <recipient>. If <recipient> is a non-player, it must have an @COST, and any pennies given to it will go to its owner. The amount given must match <recipient>'s @cost (if set). If /silent is given, the message informing the recipient how many pennies were given is suppressed. Wizards may "give" a negative number of pennies to take from players. When you give <recipient> pennies, his PAYMENT/OPAYMENT/APAYMENT attributes are triggered. You must pass <recipient>'s @lock/pay, unless you are a Wizard and are either giving a negative number of pennies, or giving to a player with no @cost.
  
  The last two forms of this command give an <object> from your inventory to <recipient>. The recipient must be set ENTER_OK, and you must pass his @lock/from. You must also pass <object>'s @lock/give, and <object> must pass <recipient>'s @lock/receive. When you give an object successfully, your GIVE/OGIVE/AGIVE attributes, <recipient>'s RECEIVE/ORECEIVE/ARECEIVE attributes, and <object>'s SUCCESS/ASUCCESS/OSUCCESS attributes are all triggered.

See also: @pay, @cost, @lock, inventory, @receive, @give, buy, @success
& go
& goto
& move
  go[to] <direction> 
  go[to] home
  move <direction>
  move home

  Goes in the specified direction. <Direction> can be the name or alias of an exit in your area, the enter alias of an object in your area, or the leave alias of the object you are in. You do not need to use the word 'go' or 'move', in fact -- simply typing the direction will have the same effect.

  'go home' is a special command that returns you to your home room/object.

See also: HOME, @link, @ealias, @lalias, EXITS
& INFO
  INFO

  This command returns some information about the MUSH you are on, such as its version number, time of last restart, number of players currently connected, and size of database. It can be issued from the connect screen.
  
See also: MSSP-REQUEST
& inventory
  inventory

  Lists what you are carrying. Can be abbreviated by just 'i', or 'inv'. It also tells you how much MUSH money you have. If you are not set OPAQUE, others will also be able to see what is in your inventory by looking at you.

  Note that on some MUSHes it is possible to take things that are in someone else's inventory. To be safe, @lock any objects that you do not want to lose.
  
See also: score, take, drop, OPAQUE, @lock, @invformat
& leave
  leave

  The command leave allows you to exit an object you have enter'ed into. When you leave an object, its @leave/@oleave/@oxleave messages are triggered, and its @aleave actions are triggered.

  The NO_LEAVE flag may be enabled on some MUSHes. Objects set with this flag cannot be left. @lock/leave may also be enabled on some MUSHes, which allows you to set who can leave the object. If you fail to leave, the object's @lfail/@olfail/@alfail messages/actions will be triggered.

See also: enter, @leave, @lfail, @lalias, @lock, INTERIORS 
& LOGOUT
  LOGOUT

  LOGOUT is similar to QUIT, but instead of disconnecting you from the game completely, it merely disconnects you from your current character and returns you to the opening welcome screen. This is useful if you want to disconnect and then reconnect to another character. Unlike most commands, it is case-sensitive and must be typed in all caps.
& look
& read
  look [<object>]
  look <container>'s <object>
  look <exit>'s <object>
  look/outside [<object>]

  Displays the description of <object>, or the room you're in if you don't name a specific object. You can also look at objects inside others, as long as the <container> is not set OPAQUE, or at objects on the other side of an exit, if the exit is set TRANSPARENT or CLOUDY.
  
  If you're inside a container, look/outside allows you to look at the room the container is in, or at other objects in your container's location, as long as your container is not set OPAQUE.

  Continued in 'help look2'.
& look2
  If you look at an object that is not set OPAQUE, you will see any non-DARK items in its inventory. You can look at DARK items in your location if you know what their name is by typing 'look <object>', but they will not show up in the list of contents.

  When you type 'look' alone, you look at your current location. For a room, this normally shows you the room's description, the list of contents, and any obvious exits from the room. For an object, it shows you the interior description (@idescribe) instead, if one is set.
  
  If a room is set DARK, when you look you will not see any of the exits or contents of the room, unless they are set LIGHT.

  'look' may be abbreviated 'l', and is sometimes aliased as 'read'.
  
See also: OPAQUE, FLAGS, @describe, @adescribe, @odescribe, DARK, LIGHT, TRANSPARENT, CLOUDY
& news
  news [<topic>]

  The news system works just like the help system. Many MUSHes use it to provide standard information on the rules, theme, and customized commands of the particular MUSH. It is highly recommended that you read it regularly.
& page
  page[/<switch>] [<player-list>=]<message>

  This command sends a message to a player or list of players. If the player's name contains spaces, surround it with double-quotes. If you have already paged someone since connecting, just typing:

    'page <message>' or 'page =<message>'

  will send the message to the last person paged. You cannot page a player if they are set HAVEN or if you do not pass their @lock/page. In the latter case, the player's PAGE_LOCK`FAILURE, PAGE_LOCK`OFAILURE, and PAGE_LOCK`AFAILURE attributes will be activated if set.

  Examples:
    > page airwolf=hi there!
    You paged Airwolf with 'hi there!'.
    > page see, I don't have to retype the name.
    You paged Airwolf with 'see, I don't have to retype the name.'.
    > page "John Lennon" Ringo=Paul's fine!

  Continued in 'help page2'.
& page2
  Page will attempt a partial match on the name, checking both for an @alias and to see if the name matches someone connected. If the first character of <message> is a : or a ;, it will send the page in pose format.

  Objects may page players, but not vice versa. If an object pages a NOSPOOF player, that player will see the object's number in square brackets, in front of the message, in a fashion similar to the way NOSPOOF flags emits.

  When a player is paged, their PAGEFORMAT attribute is checked, and if exists, the page as viewed by the player is set to the results of calling PAGEFORMAT. See help @pageformat.

  Page takes three switches: /noeval, /override, and /port.

  The /noeval switch prevents the MUSH from evaluating the message.
  The /override switch is admin-only, and overrides pagelocks and HAVEN.
  The /port switch is admin-only, and will page a single port descriptor directly, including connections that have not yet logged into a player.
  
See also: @lock, @alias, @pageformat, pose, :, ;, HAVEN, NOSPOOF, FLAGS
& :
& ;
& pose
& semipose
  pose[/noeval] <action>
  :<action>

  pose/nospace[/noeval] <action>
  semipose[/noeval] <action>
  ;<action>
 
  The pose and semipose commands allow you to perform actions. Pose shows your name, a space, and then <action>; semipose omits the space. They can be abbreviated to ':' and ';' respectively. The /noeval switch stops <action> from being evaluated.
  
  If you have a SPEECHMOD attribute set, it will be evaluated with <action> as %0 and either : (for pose) or ; (for semipose) as %1. The result is used instead of <action>, as long as it returns a non-empty string.

  See 'help pose2' for examples.
See also: say, @emit, @speechmod
& pose2
 
  Examples:
    > pose waves.
    Bob waves.
    
    > :laughs out loud.
    Bob laughs out loud.
    > ;'s laughing on the inside.
    Bob's laughing on the inside.
& "
& say
  say[/noeval] <message>
  "<message>

  Says <message> out loud. The message will be enclosed in double-quotes. A single double-quote is the abbreviation for this common command. If the /noeval switch is given, <message> will not be evaluated.
  
  If you have a SPEECHMOD attribute set, it will be evaluated with <message> passed as %0 and " (a double-quote) passed as %1. The result is shown instead of <message>, as long as it evaluates to a non-empty string.
  
  If <message> begins with a double-quote and the chat_strip_quote @config option is on, the leading " will be stripped.

See also: pose, whisper, @speechmod, @emit, page
& score
  score
  
  Displays how many pennies you have. Helpful to see if any machines are looping. If they are, your pennies will be being rapidly drained. MUSH money may also be used for other purposes in the game.
  
See also: LOOPING, @ps, QUEUE, MONEY, TRACK_MONEY
& think
  think <message>

  You can use this command to send a private message to yourself. Pronoun substitution is performed. This is essentially equivalent to doing a "@pemit/silent me=<message>".

  One possible use: @adesc me=think %n just looked at you.

See also: @pemit, @@
& QUIT
  QUIT

  Log out and leave the game. Must be in all capitals.
& unfollow
  unfollow
  unfollow <object>

  This command stops you from following an object that you were formerly following. If no object is given, you stop following everyone you were following.

See also: follow, dismiss, desert, followers(), @follow, @ofollow, @afollow
& use
  use <object>

  This command attempts to "use" <object>. If you do not pass <object>'s @lock/use, the UFAIL/OUFAIL/AUFAIL attributes are triggered.
  
  If you pass the lock, you will see <object>'s USE attribute, and others in your location will see <object>'s OUSE. Depending on <object>'s CHARGES attribute, one of <object>'s AUSE or RUNOUT attributes will be triggered - see 'help @charges' for more information.

See also: @use, @charges, @lock, @ufail
& WARN_ON_MISSING

  This internal command is run when someone attempts to run a command which starts with a function, for example:
    &test me=$test: [emit(test)]
  By default it sends the owner of the offending object a message, so they can fix the code to use a command instead of a function. The command must be enabled (either in restrict.cnf or with @command/enable) in order to be used. It can be @hooked to set custom behaviour.
  
  Example:
    > @hook/override warn_on_missing=#0, wom
    > &wom #0=$warn_on_missing: @pemit/list %# [owner(%!)]=[name(%!)] has broken code in %=!
         
    > &wom #0=$warn_on_missing *: @pemit [owner(%!)]=[name(%!)] has broken code in %= - attempted to run %0!
         
See also: huh_command, unimplemented_command
& UNIMPLEMENTED_COMMAND

  This internal command is run when someone attempts to use an unimplemented command. Currently, this only occurs when a command has been added with @command/add but has not been properly @hooked to run softcode. UNIMPLEMENTED_COMMAND cannot be run directly.
  
  By default, the command just shows the message "This command has not been implemented.", but you can @hook it to perform other actions.
  
See also: huh_command, warn_on_missing, @command, @hook
& whisper
  whisper <player>=<message>
  whisper/silent <player>=<message>
  whisper/noisy <player>=<message>
  whisper/noeval <player>=<message>
  whisper/list <players>=<message>

  Whispers the message to the named person, if they are nearby. If <message> is prefixed with a ':' or ';' it will be posed or semiposed, respectively.
  
  With the /noisy switch, other players in the room may be informed who you whisper to (but not what you whisper); the probability that a noisy whisper will be heard is set by the 'whisper_loudness' @config option. With the /silent switch, the whisper will not be overheard. (When neither switch is given, the default behaviour is controlled by the 'noisy_whisper' @config option.)

  <message> will not be evaluated if the /noeval switch is given.
  
  The /list switch lets you whisper to multiple people at once. In this case, <players> is a space-separated list of names, and names with spaces should be enclosed in double-quotes, as per page/list.

See also: page, pose, @pemit
& WHO
& DOING
  WHO [<pattern>]
  DOING [<pattern>]
  
  For mortals, the WHO command displays a list of players currently connected to the MUSH, the amount of time they've been connected, their idle time, and their @doing. Hidden players are not shown.
  
  For admin, WHO shows the names of online players, their location, connection/idle times, the number of commands typed through the connection, the descriptor/port number, and the host the player is connected from. It also includes hidden players, and connections which are at the login screen, but have not yet connected to a player.
  
  Admin can use the DOING command to see the same output mortals see with WHO, with the exception that dark/hidden players are included.
  
  If a <pattern> is given for either command, only connected players whose names start with <pattern> are shown. If <pattern> is a wildcard, only players whose names or aliases match the pattern are shown.
  
  Continued in 'help who2'.
& WHO2

  In earlier versions of PennMUSH, WHO was a socket command (meaning only players could use it, and that while it could not be overwritten, you could use softcoded 'who' commands along side it which worked as long as they weren't typed in all upper-case). Existing games which have softcoded 'who' commands can maintain this feature by using an @hook/ignore on the WHO command, such as:
  
    > &HOOK.WHO <object>=not(comp(left(%c,3),WHO))
    > @hook/ignore WHO=<object>,HOOK.WHO

  @hooks are not maintained across reboots, and should be placed into an @startup on a low-dbref object.
  
  Note: The WHO command available at the login screen is totally separate from the in-game WHO command, and is not affected by any changes to the in-game WHO. To alter that, use the WHO_FILE @config option.

See also: @doing, @poll, SESSION
& SESSION
  SESSION [<pattern>]

  The SESSION command is the same as the admin WHO, but instead of showing the hostname, it shows the number of bytes sent to, received from, and pending for each connection. <pattern> limits the output, only showing players whose name begins with <pattern>, or whose names or aliases match <pattern> if it's a wildcard pattern.

See also: WHO
& with
  with[/room] <obj>=<command>

  Attempts to run a user-defined command on a specific object. If the /room switch is given, <obj> must be a room or your current location, and its contents are checked for commands as if it was a master room.
  
  <obj> must be an object near you, an object you control, your ZMO or (if the /room switch is given) the Master Room.

See also: USER-DEFINED COMMANDS, EVALUATION ORDER
& socket commands
  These commands can only be entered by a connected player through their client. They generally do things that only affect a specific connection and would be meaningless if run by an object or disconnected player.
  
  IDLE    INFO    LOGOUT  OUTPUTPREFIX    OUTPUTSUFFIX
  PROMPT_NEWLINES QUIT    SCREENWIDTH     SCREENHEIGHT
  SOCKSET MSSP-REQUEST

  In addition, the following commands can only be used at the login screen:

  cd ch cv connect create register
  
  The WHO command can also be used at the login screen. Please note that this is different to the in-game WHO command.
& MSSP-REQUEST
  MSSP-REQUEST
  
  This socket command shows some basic information about the MUSH, along with any admin-defined information specified in mush.cnf with the 'mssp' option. The info is also shown via the MSSP telnet option. Useful for MUD crawlers and bots. For more information about the MUD Server Status Protocol (MSSP), see http://tintin.sourceforge.net/mssp/
  
See also: INFO
& @SUGGEST
@suggest[/list]
@suggest/add <category>=<word>
@suggest/delete <category>=<word>

 Given a list of known good words in a category, the mush can suggest ones based on misspelled or otherwise invalid words. This is used for suggesting function names, help entries, etc. @suggest provides a way to add custom categories and vocabulary words.

 When given no switches or /list, shows all available suggestion categories. If the dict_file config option is set, tries to populate the 'words' category from it.

 /add and /delete are Wizard-only switches that do the respective operation for a word in a given category.

Example:
    > @suggest/add pets=dog
    > @suggest/add pets=cat
    > @suggest/add pets=bird
    > think suggest(pets, birb)
    BIRD

See also: suggest()
& code
& contact
PennMUSH is developed by a team of developers whose names are listed in 'help changes'. Suggestions, comments, and bug reports are welcome.

The main PennMUSH web page is at http://www.pennmush.org

Report bugs and make suggestions at https://github.com/pennmush/pennmush/issues

The PennMUSH community page is at http://community.pennmush.org

For information about downloading PennMUSH, see 'help download'.
For information about changes in versions of the code, see 'help changes'.
& download
The latest version of this MUSH code is available from https://github.com/pennmush/pennmush/releases or http://download.pennmush.org. It will be called something like pennmush-1.8.3p9.tar.bz2, depending on the version number.

The MUSH manual is available from http://download.pennmush.org, in the /Manuals directory. It should be called mushman.2.008.tar.Z or something similar; you should attempt to get at least version 2.007. Also on that site is Javelin's Guide for PennMUSH Gods, in /Guide, available as plain text or
HTML.
& i18n
& internationalization
& locale
& translation
Internationalization support in PennMUSH includes:
* Support for (8-bit) locale-based character sets, including translation of iso-8859-1 accented characters to html entities for Pueblo, the accent() and stripaccents() functions, and the NOACCENTS flag.
* Support for locale-based date/time formats
* Support for locale-based message sets for translations of server messages. There are active translation teams (and you can join!) and several languages have practically complete translation files available.
* Some support for locale-based string collation
* The ability to alias command and function names, so you can generate a set of translated commands/functions.

Most of these features get enabled by setting an appropriate environment variable in the PennMUSH restart script.

Unicode is not currently supported.
& copyright
& copyrite
& license
Copyright, License, and Credits for PennMUSH 1.x. Revised March 2006.

I. Copyrights

PennMUSH 1.x
Copyright (c) 1995-2006, T. Alexander Popiel <talek@pennmush.org> and Shawn Wagner <raevnos@pennmush.org>.

Some code used in this server may have been derived from the TinyMUSH 2.2 source code, with permission. TinyMUSH 2.2 is Copyright (c) 1994-2002, Jean Marie Diaz, Lydia Leong, and Devin Hooker.

Some code used in this server may have been derived from TinyMUSH 2.0. Copyright (c) 1995, Joseph Traub, Glenn Crocker.

Some code used in this server may have been derived from TinyMUD. Copyright (c) 1995, David Applegate, James Aspnes, Timothy Freeman and Bennet Yee.

 *------------------------------------------------------------------------*

II. License

Because PennMUSH includes parts of multiple works, you must comply with all of the relevant licenses of those works. The portions derived from TinyMUD/TinyMUSH 2.0 are licensed under the following terms:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that: (1) source code distributions
  retain the above copyright notice and this paragraph in its entirety, and
  (2) distributions including binary code include the above copyright 
  notice and this paragraph in its entirety in the documentation or other 
  materials provided with the distribution.  The names of the copyright 
  holders may not be used to endorse or promote products derived from 
  this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

The portions derived from TinyMUSH 2.2 are used under the Artistic License. The Artistic License is also the license under which you are granted permission to copy and modify PennMUSH:

The Artistic License

Preamble

The intent of this document is to state the conditions under which a
Package may be copied, such that the Copyright Holder maintains some
semblance of artistic control over the development of the package,
while giving the users of the package the right to use and distribute
the Package in a more-or-less customary fashion, plus the right to make
reasonable modifications.

Definitions:

"Package" refers to the collection of files distributed by the Copyright
Holder, and derivatives of that collection of files created through
textual modification.
"Standard Version" refers to such a Package if it has not been modified,
or has been modified in accordance with the wishes of the Copyright
Holder.
"Copyright Holder" is whoever is named in the copyright or copyrights
for the package.
"You" is you, if you're thinking about copying or distributing this Package.
"Reasonable copying fee" is whatever you can justify on the basis of media
cost, duplication charges, time of people involved, and so on. (You will
not be required to justify it to the Copyright Holder, but only to the
computing community at large as a market that must bear the fee.)
"Freely Available" means that no fee is charged for the item itself,
though there may be fees involved in handling the item. It also means
that recipients of the item may redistribute it under the same conditions
they received it.

1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that
you duplicate all of the original copyright notices and associated
disclaimers.

2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A Package
modified in such a way shall still be considered the Standard Version.

3. You may otherwise modify your copy of this Package in any way, provided
that you insert a prominent notice in each changed file stating how and
when you changed that file, and provided that you do at least ONE of
the following:

 a) place your modifications in the Public Domain or otherwise make them
 Freely Available, such as by posting said modifications to Usenet or an
 equivalent medium, or placing the modifications on a major archive site
 such as ftp.uu.net, or by allowing the Copyright Holder to include your
 modifications in the Standard Version of the Package.

 b) use the modified Package only within your corporation or organization.

 c) rename any non-standard executables so the names do not conflict with
 standard executables, which must also be provided, and provide a separate
 manual page for each non-standard executable that clearly documents how
 it differs from the Standard Version.

 d) make other distribution arrangements with the Copyright Holder.

4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:

 a) distribute a Standard Version of the executables and library files,
 together with instructions (in the manual page or equivalent) on where
 to get the Standard Version.

 b) accompany the distribution with the machine-readable source of the
 Package with your modifications.

 c) accompany any non-standard executables with their corresponding
 Standard Version executables, giving the non-standard executables
 non-standard names, and clearly documenting the differences in manual
 pages (or equivalent), together with instructions on where to get the
 Standard Version.

 d) make other distribution arrangements with the Copyright Holder.

5. You may charge a reasonable copying fee for any distribution of
this Package. You may charge any fee you choose for support of this
Package. You may not charge a fee for this Package itself. However, you
may distribute this Package in aggregate with other (possibly commercial)
programs as part of a larger (possibly commercial) software distribution
provided that you do not advertise this Package as a product of your own.

6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall under
the copyright of this Package, but belong to whomever generated them,
and may be sold commercially, and may be aggregated with this Package.

7. C or perl subroutines supplied by you and linked into this Package
shall not be considered part of this Package.

8. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.

9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

The End
& @config parameters
 Many of the mush's run-time options can be set from the game by wizards, using @config/set <option>=<new value>. Those that can be set with visible changes are listed below, grouped by category. See help @config <category> for details on each.

  Attribs      Chat       Cmds        Cosmetic      Costs
  Db           Dump       Flags       Funcs         Limits
  Log          Net        Tiny

 The categories and groups are the same as those used by @config/list. Values must be of the listed type for each option. They include: <number>, <dbref>, <boolean> (Yes/No), <time>, or <string>.

 Options which take a <time> will accept either a number of seconds or a combination of numbers followed by 's' for seconds, 'm' for minutes or 'h' for hours, making 1h30m and 5400 equivalent.

 <dbref> options can be given with or without the leading '#', so '1' and '#1' are the same.

& @config attribs
 These options control some attribute behavior.

  adestroy=<boolean>: Is the @adestroy attribute used?
  amail=<boolean>: Is the @amail attribute used?
  player_listen=<boolean>: Is @listen checked on players?
  player_ahear=<boolean>: Is @ahear triggered on players?
  startups=<boolean>: Are @startup triggered at restart?
  room_connects=<boolean>: Are @aconnect and @adisconnect triggered on rooms?
  read_remote_desc=<boolean>: Can anyone remotely retrieve @descs?
  empty_attrs=<boolean>: Can attributes be set to an empty string?
  reverse_shs=<boolean>: Reverse the endedness of the shs password encryption? (Playing with this will break logins)
& @config chat
 These options control chat system settings.

  chan_cost=<number>: How many pennies a channel costs to create.
  max_channels=<number>: How many channels can exist total.
  max_player_chans=<number>: How many channels can each non-admin player create? If 0, mortals cannot create channels.
  noisy_cemit=<boolean>: Is @cemit/noisy the default?
  chan_title_len=<number>: How long can @channel/title's be?
  use_muxcomm=<boolean>: Enable MUX-style channel aliases? See 'help muxcomsys'
  chat_token_alias=<character>: A single character that can be used as well as + for talking on channels (+<chan> <msg>)
& @config cmds
 These options affect command behavior.

  noisy_whisper=<boolean>: Does whisper default to whisper/noisy?
  possessive_get=<boolean>: Does "get container's object" work?
  possessive_get_d=<boolean>: Does it work on disconnected players?
  link_to_object=<boolean>: Can exits have objects as their destination?
  owner_queues=<boolean>: Are command queues kept per-owner, or per-object?
  full_invis=<boolean>: Should say by a dark player show up as 'Someone says,'?
  wiz_noaenter=<boolean>: If yes, dark players don't trigger @aenters.
  really_safe=<boolean>: Does SAFE prevent @nuking?
  destroy_possessions=<boolean>: When a player is destroyed, are their objects as well?
& @config cosmetic
 These are cosmetic options of various sorts.

  money_singular=<string>: What is one penny called?
  money_plural=<string>: What are many pennies called?
  player_name_spaces=<boolean>: Can player names have spaces in them?
  ansi_names=<boolean>: Are names in look hilighted?
  monikers=<list>: Where should @monikers be displayed? See 'help monikers'
  float_precision=<numbers>: How many digits after the decimal point in floating point numbers are kept when formatting the result of a floating point function?
  comma_exit_list=<boolean>: Do exits show up like North, East, and West or as North East West?
  count_all=<boolean>: Does the count of connected players in WHO include hidden connections for mortals?

Continued in help @config cosmetic2
& @config cosmetic2
 More cosmetic options.

  page_aliases=<boolean>: Are aliases included in page listings? For example, Foo(F) pages: Blah
  flags_on_examine=<boolean>: Are flag names included when examining objects?
  ex_public_attribs=<boolean>: Show visual attributes when examining objects you don't control?
  wizwall_prefix=<string>: Prefix for @wizwall messages.
  rwall_prefix=<string>: Prefix for @rwall messages.
  wall_prefix=<string>: Prefix for @wall messages.
  announce_connects=<boolean>: Should (dis)connects be announced to non-HEAR_CONNECT players and to channels?
  chat_strip_quote=<boolean>: Does +chan "foo strip the "?
  newline_one_char=<boolean>: Is strlen(%r) equal to 1?
  only_ascii_in_names=<boolean>: Names are ascii-only or are extended characters permitted?
& @config costs
 These options control how many pennies various things cost.

  object_cost=<number>: How many pennies it costs to create an object.
  exit_cost=<number>: How many pennies it costs to create an exit.
  link_cost=<number>: How many pennies it costs to use @link.
  room_cost=<number>: How many pennies it costs to @dig a room.
  queue_cost=<number>: How many pennies it costs to queue a command. Refunded when the command executes.
  quota_cost=<number>: How much @quota goes down by for each object.
  find_cost=<number>: How many pennies it costs to use @search, @find, @entrances, and their function versions.
& @config db
 These are database options.

  player_start=<dbref>: What room newly created players are in.
  master_room=<dbref>: The location of the master room.
  ancestor_room=<dbref>: If set to a good object, this is considered a global parent for all rooms. If -1 or a nonexistant object, then disabled.
  ancestor_exit=<dbref>: As ancestor_room for exits.
  ancestor_thing=<dbref>: As ancestor_room for things.
  ancestor_player=<dbref>: As ancestor_room for players.
  base_room=<dbref>: The starting room used to determine if other rooms are disconnected.
  default_home=<dbref>: The room to send things to when they're homeless.
  exits_connect_rooms=<boolean>: Is a room with any exit at all in not considered disconnected for FLOATING checks?
  zone_control_zmp_only=<boolean>: Do we only perform control checks on ZMPs, or do we check ZMOs and ZMRs too?
& @config dump
 These options affect database saves and other periodic checks.

  forking_dump=<boolean>: Does the game clone itself and save in the copy, or just pause while the save happens?
  dump_message=<string>: Notification message for a database save.
  dump_complete=<string>: Notification message for the end of a save.
  dump_warning_1min=<string>: Notification one minute before a save.
  dump_warning_5min=<string>: Notification five minutes before a save.
  dump_interval=<time>: Seconds between database saves.
  warn_interval=<time>: Seconds between automatic @wchecks.
  purge_interval=<time>: Seconds between automatic @purges.
  dbck_interval=<time>: Seconds between automatic @dbcks.
& @config flags
  These options set the default flags for newly-created objects and channels.

  player_flags=<string>: List of flags to set on newly created players
  room_flags=<string>: List of flags to set on newly created rooms
  thing_flags=<string>: List of flags to set on newly created things
  exit_flags=<string>: List of flags to set on newly created exits
  room_flags=<string>: List of flags to set on newly created rooms
  channel_flags=<string>: List of flags to set on newly created channels
& @config funcs
 These options affect the behavior of some functions.

  safer_ufun=<boolean>: Are objects stopped from evaluting attributes on objects with more privileges than themselves?
  function_side_effects=<boolean>: Are function side effects (functions which alter the database) allowed?
& @config limits
 Limits and other constants.

  max_dbref=<dbref>: The highest dbref an object can have. If 0, there is no limit on database size.
  max_attrs_per_obj=<number>: The maximum attributes an object can have.
  max_logins=<number>: The maximum number of connected players.
  max_guests=<number>: The maximum number of connected guests. If 0, no limit. If -1, limited by the number of guest players in the db.
  max_named_qregs=<number>: The maximum number of qregs except for a-z and 0-9. The limit is per-localize()-call.
  connect_fail_limit=<count>: The maximum number of times in a 10 minute period that an IP can attempt to log in and fail. Maximum is 50, 0 means no limit.
  idle_timeout=<time>: The number of minutes a connection can be idle before getting booted. 0 means no limit.
  unconnected_idle_timeout=<time>: The number of minutes a connection can be sitting at the login screen before getting booted. 0 means no limit.

Continued in help @config limits2
& @config limits2
 Limits and constants, continued.

  whisper_loudness=<number>: The percentage chance of a whisper/noisy being heard.
  starting_quota=<number>: How much quota new players get.
  starting_money=<number>: How many pennies new players get.
  paycheck=<number>: How many pennies players get each day they log on.
  max_pennies=<number>: The maximum pennies an object can have.
  mail_limit=<number>: How many @mail messages someone can have.
  max_depth=<number>: How deep indirect @lock chains can go.
  player_queue_limit=<number>: The number of commands a player can have queued at once.
  queue_loss=<number>: One in <number> times, queuing a command will cost an extra penny that doesn't get refunded.
  queue_chunk=<number>: How many queued commands get executed in a row when there's no network activity pending.

Continued in help @config limits3
& @config limits3
 Limits and constants, continued.

  active_queue_chunk=<number>: How many queued commands get executed in a row when there is network activity pending.
  function_recursion_limit=<number>: The depth to which softcode functions can call more functions.
  function_invocation_limit=<number>: The maximum number of softcode functions that can be called in one command.
  guest_paycheck=<number>: How many pennies guests get each day.
  max_guest_pennies=<number>: The maximum pennies a guest can have.
  player_name_len=<number>: The maximum length of a player name.
  queue_entry_cpu_time=<number>: The maximum number of milliseconds a queue entry can take to run.
  use_quota=<boolean>: Controls if quotas are used to limit the number of objects a player can own.

Continued in help @config limits4
& @config limits4
 Limits and constants, continued

  max_aliases=<number>: The maximum number of aliases a player can have.
  keepalive_timeout=<time>: How often should an 'Are you still there?' query be sent to clients, to stop players' routers booting idle connections?
  max_parents=<number>: The maximum number of levels of parenting allowed.
  call_limit=<number>: The maximum number of times the parser can be called recursively for any one expression.
  chunk_migrate=<number>: Maximum number of attributes that can be moved to disk cache per second.
& @config log
 These options affect logging.

  log_commands=<boolean>: Are all commands logged?
  log_forces=<boolean>: Are @forces of wizard objects logged?
& @config net
 Networking and connection-related options.
 
  mud_name=<string>: The name of the mush for mudname() and @version and the like.
  mud_url=<string>: If this is set, the welcome message for the mush is bracketed in <!-- ... --> for all clients, and web browsers are redirected to the url described in mud_url.
  use_dns=<boolean>: Are IP addresses resolved into hostnames?
  logins=<boolean>: Are mortal logins enabled?
  player_creation=<boolean>: Can CREATE be used from the login screen?
  guests=<boolean>: Are guest logins allowed?
  pueblo=<boolean>: Is Pueblo support turned on?
  sql_platform=<string>: What kind of SQL server are we using? ("mysql", "postgreql", "sqlite" or "disabled")
  sql_host=<string>: What is the hostname or ip address of the SQL server
  ssl_require_client_cert=<boolean>: Are client certificates verified in SSL connections?
& @config tiny
 Options that help control compability with TinyMUSH servers.

  null_eq_zero=<boolean>: Is a null string where a number is expected considered a 0?
  tiny_booleans=<boolean>: Use Tiny-style boolean values where only non-zero numbers are true.
  tiny_trim_fun=<boolean>: Are the second and third arguments to trim() reversed?
  tiny_math=<boolean>: Is a string where a number is expected considered a 0?
  silent_pemit=<boolean>: Does @pemit default to @pemit/silent?
& EVENTS
& EVENT
  PennMUSH Events are hardcoded events that may or may not be caused by players. The Event system lets administrators designate an object as an event handler (using the "event_handler" config option). The
  event_handler object will then have attributes triggered, with arguments, on specified events.

  To use the PennMUSH Event System:

  > @create Event Handler
  > @config/set event_handler=[num(Event Handler)]
  > &<event name> Event Handler=<action list>

  You will very likely want to set the event_handler option in your mush.cnf file to ensure it survives over dumps and is actively receiving events even during startup.

  The enactor of an event is either:
    1) The executor that caused it, or
    2) #-1 for system events without an executor.

  For a list of events and their arguments, see 'help event list'.

  For some examples of using events, see 'help event examples'.
& EVENT EXAMPLES
  Suppose you want random dbsave messages:
  > &DUMP`COMPLETE Event Handler=@config/set dump_complete=SAVE: [v(randword(lattr(me/dumpmsg`*)))]
  > &DUMPMSG`NOTHING Event=The Database has been saved, nothing to see here.
  > &DUMPMSG`GRETZKY Event=The Database saves, but Gretzky scores!
  > &DUMPMSG`GEICO Event=The Database saved 15% by switching to Geico!
  > @dump
  SAVE: The Database has been saved, nothing to see here.
  > @dump
  SAVE: The Database saved 15% by switching to Geico!

  Or admin want to be notified when a player connect attempt fails.
  > @set Event=wizard
  > &SOCKET`LOGINFAIL Event=@wizwall/emit On descriptor '%0' from IP '%1' a failed connect attempt to '%4': '%3'
   (Later, a player attempts to log in as #1)
  Broadcast: [Event Handler]: On descriptor 3, from IP '127.0.0.1', a failed connect attempt to '#1': 'invalid password'

  For more examples, see 'help event examples2'.
& EVENT EXAMPLES2
  Suppose you want @pcreated players to be powered builder, set shared and zonelocked to roys, but players created at the connect screen to not be.
  > @set Event=wizard
  > &PLAYER`CREATE Event=@assert %# ; @pemit %#=Auto-Setting [name(%0)] Builder and shared ; @power %0=builder ; @lock/zone %0=FLAG^ROYALTY ; @set %0=shared
  > @pcreate Grid-BC
  Auto-Setting Grid-BC Builder and Shared

  The Event Handler object, since it's handling so many events, may become cluttered with attributes. We recommend using @trigger and @include to separate events to multiple objects.
& EVENT LIST
  Event names are of the format <type>`<event>. The 'type' is used simply to group similar events together for help.

  Event syntax in the help is of the form:
  <eventgroup>`<eventname> (What is passed as %0, %1, ... %9)

  The following event types and events have been added to PennMUSH. To see the help for them, type 'help event <type>'.

  dump: dump`5min, dump`1min, dump`complete, dump`error
  db: db`dbck, db`purge, db`warnings
  log: log`err, log`cmd, log`conn, log`trace, log`check, log`huh
  object: object`create, object`destroy, object`move, object`rename, object`flag
  sql: sql`connect, sql`connectfail, sql`disconnect
  signal: signal`usr1, signal`usr2
  player: player`create, player`connect, player`disconnect, player`inactivity
  socket: socket`connect, socket`disconnect, socket`loginfail, socket`createfail
& EVENT DB
  db`dbck: Run after the regular database consistency check.
  db`purge: Run after the regular purging of destroyed objects.
  db`wcheck: Run after the regular @warnings check.
  
  Note: These events are only triggered after the automatic scheduled checks, and not if someone manually runs @dbck, @purge or @wcheck.
& EVENT DUMP
  dump`5min (Original message, isforking)
      Database save will occur in 5 minutes.
  dump`1min (Original message, isforking)
      Database save will occur in 1 minute.
  dump`complete (Original message, wasforking)
      Database save has completed.
  dump`error (Error message, wasforking, exit_status)
      Database save failed! You might want this to alert any admin on.
      exit_status has different meanings in forking and non-forking dumps.
      In forking: exit_status is a string, either "SIGNAL <int>" or "EXIT <int>". SIGNAL <int> refers to the mush process receiving error message via signal while EXIT <int> refers to mush process exiting abnormally.
      In nonforking: exit_status is "PERROR <string>" - string being the error message returned by strerror(errno). If you are seeing errors on dbsave, we recommend setting forking_dump to 0, as nonforking dumps have more verbose error messages.

  The standard messages shown on dumps are still displayed when these events are set. To disable the standard message, set them to empty strings via @config or in mush.cnf.
& EVENT LOG
  Events in the log tree get triggered whenever the game logs any information to a log file (Either because of @log, or something else happening.) They all get passed a single argument, the message being logged.

  log`err
     Errors and the general catch-all.
  log`cmd
     Logged commands.
  log`wiz
     Logged wizard activity.
  log`conn
     Connection notifications.
  log`trace
     Memory tracking notifications.
  log`check
     Save-releated log messages.
  log`huh
     Commands that generate huh messages.
& EVENT OBJECT
  object`create (new objid, cloned-from)
      Triggered on the creation of any object except player. If it was created using @clone, then <cloned-from> will be a objid. Otherwise <cloned-from> will be null.

  object`destroy (objid, origname, type, owner, parent, zone)
      Triggered _after_ the object is totally destroyed. Passed arguments are former objid, name, type, owner, etc. Enactor is always #-1, so use former owner.

  object`move (objid, newloc, origloc, issilent, cause)
      Triggered after the object is moved, @tel'd, or otherwise sent to a new location. If <issilent> is 1, then the object was moved using @tel/silent.

  object`rename (objid, new name, old name)
      Triggered when any object is renamed.
      
  object`flag (objid of object with flag, flag name, type, setbool, setstr)
      Triggered when a flag or power which has the "event" restriction is set or cleared. <type> is one of FLAG or POWER. <setbool> is 1 if the flag/power is being set, and 0 if it's being cleared. <setstr> is either "SET" or "CLEARED".
    Example:
      &OBJECT`FLAG event handler=@cemit Admin=capstr(lcstr(%2)) %1 [lcstr(%4)] on [name(%0)] by %n.

& EVENT SQL
  sql`connect (platform)
      Triggered on successful connect to the SQL database. <platform> is 'mysql', 'postgresql' or 'sqlite3'.

  sql`connectfail (platform, error message)
      Triggered on unsuccessful connect to the SQL database.

  sql`disconnect (platform, error message)
      Triggered if SQL disconnects for any reason. Usually not a worry since Penn will auto-reconnect if it can.
& EVENT SIGNAL
No arguments are passed to these events.

  signal`usr1: Triggered when the PennMUSH process receives a "kill -USR1"

  signal`usr2: Triggered when the PennMUSH process receives a "kill -USR2"

  If these attributes exist, then penn will NOT perform what it usually does when it receives a signal. In effect, these override Penn's default actions.

  To mimic old behaviour:
  &SIGNAL`USR1 Event Handler=@nspemit/list lwho()=GAME: Reboot w/o disconnect from game account, please wait. ; @shutdown/reboot
  &SIGNAL`USR2 Event Handler=@dump
& EVENT PLAYER
  player`create (objid, name, how, descriptor, email)
      Triggered when a player is created. If the player was @pcreated, then %# will be the person who did the @pcreate. If player was created by using 'create' at the connect screen, then %# will be #-1 and <descriptor> will be non-null. <how> is one of: "pcreate", "create" or "register". If created using 'register', <email> will be set appropriately.

  player`connect (objid, number of connections, descriptor)
      Similar to @aconnect, but for events, and so you can use descriptor.

  player`disconnect (objid, number of remaining connections, hidden?, cause of disconnection, ip, descriptor, conn() secs, idle() secs, recv bytes/sent bytes/command count)
      Similar to @adisconnect, but for event system, and with more information available.
  player`inactivity: Triggered when idle players are disconnected. Only run if at least one player gets idlebooted (Or auto-hidden), not at every inactivity check.
& EVENT SOCKET
  socket`connect (descriptor, ip)
      Triggered when a socket first connects to the port. Using both this and player`connect could be spammy. This happens when a connecting socket sees the connect screen.

  socket`disconnect (former descriptor, former ip, cause of disconnection, recv bytes/sent bytes/command count)
      Triggered when a socket disconnects. Using this and player`disconnect could be spammy.

  socket`loginfail (descriptor, IP, count, reason, playerobjid, name)
      Triggered when a login attempt fails. <count> is the number of fails in the past 10 minutes. If used in conjuction with the config option connect_fail_limit, then any failures after the limit is reached will NOT trigger socket`loginfail. If the connect is a failed attempt to log into a valid player, <playerobjid> will be set to that objid. Otherwise it will be set to #-1. <name> is the name the connection attempted to connect with, and is only set when <playerobjid> is #-1.

  socket`createfail (descriptor, ip, count, reason, name[, error])
      Triggered when a player create attempt fails. <count> is the # of fails caused by this ip. If the failure is from an attempt to register a player via email, the error code of the mailer program is provided as <error>.

    A sitelock rule with deny_silent will not trigger socket`createfail or socket`createfail.
& FLAGS

  Flags give objects certain abilities or qualities. For example, a wizard player has wiz powers because s/he has the WIZARD flag set.

  Some flags can only be set on certain types of objects, such as just players or just rooms. Other flags, like VISUAL, can be set on any type of object (player, room, exit, thing).

  Flags can be set on an object with the @set command or set() function. To un-set a flag, use the exclamation point (!) before the flag name. For help on any particular flag, type 'help <flag name>'.

  A descriptive list of default flags is available in 'help flag list'. A complete list of all flags is available through '@flag/list'.

  Continued in 'help flags2'.
& FLAGS2
  You can see the list of flags set on an object in several ways.

  1. If you are allowed to examine the object. The flags are listed in expanded word format on the line just below the object's name, after the word "Flags:".
  2. Flag abbreviations are also visible after the object's name in the room description, if the object is not set OPAQUE and you are not set MYOPIC.
  3. The lflags() and flags()s function will return a list of flag names and abbreviations for an object, respectively.

  Note: The object type (player, thing, room, exit or garbage) is not actually a flag. See 'help types of objects' for more information.

See also: examine, flags(), hasflag(), orflags(), andflags(), orlflags(), andlflags(), types of objects, type(), hastype(), @flag, FLAG LIST, @set, set(), attribute flags
& FLAG LIST
& FLAGS LIST
Flag  Title            Flag  Title            Flag  Title           
-----------------------------------------------------------------------
A - Abode/Ansi         C - Chown_ok/Color     D - Dark              
F - Fixed/Floating     H - Haven              I - Trust             
J - Judge/Jump_ok      L - Link_ok            M - Monitor           
N - No_leave/No_tel    O - Opaque             Q - Quiet             
S - Sticky             U - Unfindable         V - Visual            
W - Wizard             X - Safe               Z - Shared/Z_tel      

^ - Listen_parent      ~ - Noaccents          ? - Unregistered      
" - Nospoof            a - Audible            b - Debug             
d - Destroy_ok         e - Enter_ok           g - Gagged            
h - Halt               i - Orphan             j - Jury_ok           
k - Keepalive          l - Light              m - Mistrust/Myopic   
n - No_command         o - On-vacation        p - Puppet            
r - Royalty            s - Suspect            t - Transparent       
u - Uninspected        v - Verbose            w - No_warn           
x - Cloudy/Terse      

    Chan_usefirstmatch     Hear_connect           Heavy             
    Loud                   No_log                 Paranoid          
    Track_money            XTERM256               MONIKER
    open_ok
-----------------------------------------------------------------------
Some flags may not be enabled on some MUSHes. @flag/list will show which are available.

& ABODE
  Flag:  ABODE  (rooms)

  If a room has the ABODE flag set, any player or thing can set his home there. It does not allow you to link exits to the room. It allows you to make a room a public 'living area'.
  
  To make a room your home, type '@link me=here' while standing in the room.

See also: @link, LINK_OK
& ANSI
  Flag:  ANSI  (players)
  
  When set, this flag allows a player to see ANSI highlight, generated by the ansi(h,...) function. Some ANSI is used by the MUSH, for example to highlight the names of objects (if the ansi_names @config option is on), and the names of attributes.
  
  ANSI highlight can also be enabled on a per-connection basis with @sockset.
  
See also: ansi(), COLOR, XTERM256, @config, @sockset
& AUDIBLE
  Flag:  AUDIBLE  (all types)

  Objects which are set AUDIBLE forward sound in a number of ways. Only sound passing the object's @filter, and its @lock/filter, is forwarded. The lock receives the sound heard as %0. The forwarded sound is always prefixed with the object's @prefix.
  
  If an AUDIBLE object has an @forwardlist attribute set, sound heard by the object is forwarded to the objects listed in the @forwardlist. See 'help @forwardlist' for more information.
  
  When a THING is set AUDIBLE, any sound made inside it is broadcast to other objects in its location. This is useful for coding vehicles. Only sound passing the @filter is broadcast, and is prefixed with the thing's @prefix, or "From [name(<thing>)], " if no @prefix is set.
  
  Setting the AUDIBLE flag on a ROOM activates audible exits in that room. EXITs which are set AUDIBLE propagate sound from their source room to their destination, prefixed with the exit's @prefix, or "From [name(home(<exit>))], " if no @prefix is set.
  
See also: @forwardlist, @filter, @prefix
& TRACK_MONEY
  Flag: TRACK_MONEY (players)

  By setting the TRACK_MONEY flag, a player can determine which objects may be using their money. TRACK_MONEY reports all charges to a player and their objects except the queue deposit.

  > @set me=TRACK_MONEY
  > give Javelin=50
  You give 50 pennies to Javelin.
  GAME: Walker spent 50 pennies!
  > @create foo
  GAME: Walker spent 10 pennies!
  Created: Object #345.
  > @for foo=@search eval=1
  GAME: foo(#345) spent 100 pennies!
  (search results)
  > <a whole buncha commands>
  GAME: Object Walker(#123) lost a Penny to queue loss.

See also: no_pay
& CHOWN_OK
  Flag:  CHOWN_OK  (things, rooms, exits)

  You can set this flag on an object you own to allow other players to transfer ownership of the object to themselves (using @chown), as long as they pass the object's @lock/chown.
  
See also: @chown
& CLOUDY
  Flag:  CLOUDY (exits)

  If this flag is set on a (non-TRANSPARENT) exit, when a player looks at the exit they will see the contents of the destination room following the exit's description.

  If the flag is set on a TRANSPARENT exit, when a player looks at the exit they will see only the description of the destination room following the exit's description, and will not see contents.
  
See also: TRANSPARENT, look
& COLOR
  Flag:  COLOR  (players)
  
  This flag indicates to the MUSH that the player's client can see ANSI colors, using the 8 standard ANSI colors plus highlight, flash, inverse, underline.

  ANSI colors can also be enabled on a per-connection basis with @sockset.

See also: ANSI, XTERM256, ansi(), @sockset
& XTERM256
  Flag:  XTERM256  (players)
  
  This flag indicates to the MUSH that the player's client can handle the 256 XTERM colors.
  
  The flag is aliased to COLOR256 for MUX compatability.
  
  XTERM colors can also be enabled on a per-connection basis with @sockset.
  
See also: ANSI, COLOR, ansi(), @sockset
& CONNECTED
  Flag:  CONNECTED  (players)

  This flag is used internally by the MUSH to track whether a player is currently connected. It cannot be set or cleared manually.

  Prior to 1.8.5p6, mortal objects couldn't use hasflag(<player>, connected) to see if a player was online, and needed to instead use conn() or lwho(). Starting with that version, any object can use hasflag() to see if they can see that a player is online. Be careful, when coding on a privileged object, not to give away the presence of hidden players!

See also: conn(), lwho(), mwho()
& DARK
  Flag:  DARK  (all types)

  When a room is set DARK, only objects which are set LIGHT will show up in the rooms contents list when someone "look"s in the room. Exits which are set DARK do not show up in a room's Obvious Exits list.
  
  DARK players and things do not show up in the contents list of rooms. Only Wizard players can set themselves dark. Puppets and Audible things with an @forwardlist will not be hidden by the flag.
  
  Note that players and things still trigger enter/leave messages, etc, in DARK rooms.
  
  If the "full_invis" @config option is on, DARK players and things will show up as "Someone" or "Something", respectively, when they speak.

  In the past, players set DARK were automatically hidden from the WHO list via @hide, but this no longer happens. If you wish to disappear completely, you must use @hide after setting yourself DARK.

See also: LIGHT, @hide
& DEBUG
  Flag: DEBUG  (all types)
  
  The DEBUG flag is used for debugging MUSHcode. When an object is set DEBUG, all parser evaluation results will be shown to the object's owner and to any dbrefs in the object's DEBUGFORWARDLIST, in the format:
 
  #dbref! <string to evaluate> :
  #dbref!  recursive evaluation of functions in string
  #dbref! <string to evaluate> => <evaluated string>

  Because the parser does recursive evaluations, you will see successive messages evaluating specific parts of an expression. This enables you to pinpoint exactly which evaluation is going wrong.

  Objects run under this flag are computationally expensive, and can generate large amounts of spam, so this flag should only be set when needed, and cleared afterwards.
  
  There's also a DEBUG attribute flag, which only affects a single attribute; see 'help attribute flags' for more information. You can also use the "}" command prefix to run a command with DEBUG output just once.
  
  See 'help debug2' for an example.
See also: VERBOSE, PUPPET, }
& DEBUG2

  > @create Test
  > @set Test=DEBUG
  > &cmd test=$wc *: say String %0 has [strlen(%0)] letters and [words(%0)] words.
  > wc This is my test string

  #14! String %0 has [strlen(%0)] letters and [words(%0)] words. :
  #14!  strlen(%0) :
  #14!   %0 => This is my test string
  #14!  strlen(%0) => 22
  #14!  words(%0) :
  #14!   %0 => This is my test string
  #14!  words(%0) => 5
  #14! String %0 has [strlen(%0)] letters and [words(%0)] words. =>
    String This is my test string has 22 letters and 5 words.

  Test says, "String This is my test string has 22 letters and 5 words."

& DESTROY_OK
  Flag:  DESTROY_OK  (things)

  The DESTROY_OK flag allows anyone to @destroy it. This is good for "temporary" objects like "Can of Cola". If the object has an @lock/destroy set, a player who doesn't control the object must pass this lock in order to destroy it.

  DESTROY_OK takes precedence over SAFE.

See also: @destroy
& ENTER_OK
  Flag:  ENTER_OK  (all types)
 
  If a player or thing is ENTER_OK, someone may:
    * "enter" it, if they pass its @lock/enter,
    * "give" to it, if they pass its @lock/from, or
    * use "get <object>'s <item>" to take something from its inventory, if they pass its @lock/take (and possessive_get is enabled; see "help get").

  This flag has no effect on rooms or exits.

See also: enter, leave, give, get, @lock, @ealias
& FIXED
  Flag: FIXED (players)
  
  When this flag is set on a player, it prevents them or any of their objects from using the @teleport or home command. The only exception is that a player's objects are permitted to @teleport themselves to the player's inventory.
  
See also: @teleport, home, goto
& FLOATING
  Flag:  FLOATING (rooms)

  If a room is set floating, you will not be notified every 10 minutes or so that you have a disconnected room. A disconnected room is one that can't be reached from room #0, or (if the exits_connect_rooms @config option is on) one which has no exits.
  
  If you don't plan to have your main grid accessible from Room #0, it's better to enable exits_connect_rooms than to set all your rooms FLOATING.
& GAGGED
  Flag: GAGGED (players)

  The Gagged flag prevents a player from speaking, building, moving objects, and many other things, leaving him able to do little more than move himself and look. It's normally used as a penalty for those who break MUSH rules.

  Only wizards can set this flag.
See also: FIXED
& GOING
& GOING_TWICE
  Flag:  GOING  (all types)
  Flag:  GOING_TWICE  (all types)

  These are internal flags set on objects when they are scheduled to be destroyed with @destroy. It cannot be set or cleared manually; use @destroy and @undestroy.
  
See also: @destroy, @undestroy
& HALT
  Flag:  HALT  (all types)

  Objects set HALT cannot perform any MUSH actions, queue commands, evaluate softcode, etc. Players set HALT can still enter commands directly from their clients.

See also: @halt, @restart, HALT POWER
& HAVEN
  Flag:  HAVEN  (players)

  If a player is set HAVEN, she cannot be paged and anyone paging them will be sent a brief notification. You can also set a longer @HAVEN message if you wish. You may prefer to use @lock/page to block out only specific individuals.

See also: @haven
& HEAR_CONNECT
  Flag:  HEAR_CONNECT  (players)
  
  Players with this flag will receive a message whenever a player connects, disconnects, or is created. Mortals will not hear messages for players connecting/disconnecting dark. Only royalty and wizards can set this flag.
  
See also: @aconnect, @adisconnect
& HEAVY
  Flag:  HEAVY  (all types)

  The HEAVY flag, which can only be set by wizards or royalty, prevents a mortal from @teleporting an object.

See also: @teleport
& LOUD
  Flag:  LOUD  (all types)

  LOUD objects bypass all speech, channel speech, and interaction @locks. This flag can only be set by royalty or wizards.

See also: can_spoof and pemit_all (help powers2)
& INHERIT
& TRUST
  Flag:  TRUST  (all types)
  
  Setting an object TRUST prevents anything else from controlling it, aside from WIZARDs, the object's owner, or another object owned by the same player which is also set TRUST. It also allows the object to control its owner.
  
See also: MISTRUST, CONTROL
& JUDGE
& JURY_OK
  Flags:  JUDGE and JURY_OK  (players)
 
  These flags do nothing by default, but are present in new dbs for historical reasons. They can be used in softcode as desired, or removed with @flag if unneeded.

See also: @flag
& JUMP_OK
& TEL_OK
  Flag:  JUMP_OK  (rooms)

  When a room is set JUMP_OK, anyone who passes the room's @lock/teleport can @teleport into it.
  
See also: @teleport, @lock, NO_TEL, Z_TEL
& KEEPALIVE
  Flag:  KEEPALIVE  (players)

  When this flag is set on a player with a telnet-capable connection, a telnet NOP (no-operation) is sent after there's been no activity on the connection for a minute, to generate socket activity without generating any output. In a way, it's the opposite of the IDLE command. IDLE is sent by clients to keep a connection open, while KEEPALIVE tells the server to send a message. Both are intended for use by people going through home router/NAT appliances with short inactivity timeouts.

See also: IDLE, terminfo()
& LIGHT
  Flag:  LIGHT  (all types)

  Things, players, and exits which have the LIGHT flag set on them (and are not also set DARK) appear in the contents of DARK rooms.
  
  Setting a room LIGHT causes everything - even DARK objects - to show up in the room's contents list.

See also: DARK
& LINK_OK
  Flag: LINK_OK  (rooms, things)

  If a room or object is LINK_OK, anyone who passes the room's @lock/link can link exits to it (but still not from it). Also, LINK_OK overrides the TRUST protection against @trigger (although not @force or @set). 
  
  Anyone who passes a LINK_OK object's @lock/parent can @parent an object to it.

See also: @link, TRUST, @parent, PARENTS, OPEN_OK
& OPEN_OK
  Flag: OPEN_OK  (rooms)
  
  When set on a room, anyone who passes the rooms @lock/open can open exits in the room with @open (or move exits to the room with @teleport).
  
See also: @open, LINK_OK
& MONIKER
  Flag:  MONIKER  (all types)

  The names of objects with this flag set will be displayed in color using the object's @moniker, even if monikers are not usually enabled for that type of object (via the 'monikers' @config option). See 'help monikers' for more details on monikers.
  
  This flag can only be set by Wizards or Royalty.
  
See also: MONIKERS, @moniker, moniker()
& MONITOR
  Flag:  MONITOR  (players, things, rooms)
 
  The MONITOR flag activates the ^-listen patterns on an object. Objects which have ^-listen patterns but are not set MONITOR do not check those patterns. Unlike $-commands, ^-listens are not inherited from parents by default; LISTEN_PARENT must be set as well as MONITOR to enable this.

  The NO_COMMAND attribute flag disables ^-listen matching for a single attribute; see 'help attribute flags' for details.

  If using the LISTEN Attribute Tree, you must set the Root Attribute !NO_COMMAND. By default this Attribute/Attribute Root has been set NO_COMMAND by the system. Attributes which are set NO_COMMAND will not be checked for ^-listen patterns.
  
  In order to trigger an object's ^-listen patterns, you must pass both its @lock/use and its @lock/listen.

  This flag used to allow players to hear when someone connected to the game, but that is now controlled by the HEAR_CONNECT flag.  
  
See also: LISTENING, @listen, LISTEN_PARENT, HEAR_CONNECT
& MYOPIC
  Flag:  MYOPIC  (players)

  Players set MYOPIC will not see the dbref number or flag list of objects they control after their names. It's useful if you don't like to see object numbers.
  
  Anything owned by a MYOPIC player is also treated as MYOPIC.

See also: DBREF, TERSE
& MISTRUST
  Flag:  MISTRUST  (things, rooms, exits)
  
  The MISTRUST flag prevents an object from controlling another object via Control @locks, Zone @locks on ZMOs or SHARED players, or from controlling other objects with the same owner. It also prevents the object from inheriting the no_pay and no_quota powers from its owner.
  
  This flag can be used when you with a single player to retain ownership of objects that other players will control or run arbitrary code on, and don't want those objects to be able ot affect your other objects.
  
  Note that if a MISTRUST object is set WIZARD it will still control all objects in the database, and that MISTRUST does not prevent no_pay or other powers from being applied to the object directly.

See also: control, TRUST
& NOACCENTS
  Flag:  NOACCENTS  (players)

  This flag causes all accented characters to be converted to non-accented alternatives before being sent to a connection. See HELP STRIPACCENTS() for caveats.
  
  To strip accents for a specific connection, instead of all connections, you can use 
    @sockset <descriptor>=stripaccents,yes

See also: i18n, accent(), stripaccents(), @sockset
& NO_COMMAND
  Flag:  NO_COMMAND  (all types)
  
  The NO_COMMAND flag disables the checking of $-commands on an object. The server runs faster when fewer objects are checked for $-commands; thus, any object which does not have $-commands on it should be set NO_COMMAND. Many MUSHes choose to have all objects initially set NO_COMMAND at creation. The flag has no effect on exits, which are never checked for $-commands.
  
  There is also a NO_COMMAND attribute flag, which disables $-command AND ^-listen checking for a single attribute. See 'help attribute flags'.

See also: USER-DEFINED COMMANDS
& NO_LEAVE
& NOLEAVE
  Flag: NO_LEAVE (objects)
  
  When this flag is set on an object, players cannot "leave" it. Attempts to leave the object will trigger its @LFAIL, @OLFAIL, and @ALFAIL, if set.
  
  For more specific control, you can set an @lock/leave.

See also: leave, @lock
& NO_LOG
  Flag:  NO_LOG  (all types)

  When set on an object, prevents the logging of commands that object runs. Useful on globals objects when the log_commands config option is turned on.
  
  Only settable by Wizards.
& NO_TEL
  Flag:  NO_TEL  (rooms)

  The NO_TEL flag prevents objects in a room from being @teleported; mortals in the room cannot use @teleport, nor can other objects @teleport them out. This flag is checked on the "absolute room" of an object; thus, if you are in a container in a room which is NO_TEL, you cannot use @teleport from that container. There is no way to get out of a NO_TEL room except by exiting in some "normal" manner, or by going "home". Puzzle rooms, prisons, etc, would probably benefit from this flag.
  
See also: JUMP_OK, Z_TEL
& NO_WARN
& NOWARN
  Flag: NO_WARN  (all types)

  When this flag is set on an object, its owner will not receive any building warnings from that object. When it is set on a player, that player will not receive any building warnings at all.

See also: warnings, @warnings, @wcheck
& NOSPOOF
& PARANOID
  Flag:  NOSPOOF  (all types)
  Flag:  PARANOID  (all types)

  If an object is set NOSPOOF, messages of all kinds will be tagged with the name of the person/object causing them. This prevents spoofing and lets you see where such messages originated. When a NOSPOOF object is also set PARANOID, the dbref of the emitting object is also shown. You will not see nospoof information for your own messages unless you are also set PARANOID.

  When a player is set NOSPOOF or PARANOID, everything it owns is also treated as having the flag.
  
  Note that NOSPOOF output can be spammy. Nospoof information is not matched against @listen or ^-listen patterns.
  
  The nospoof tag is [Source:], and the paranoid tag is [Source(#dbref)].
    
See also: SPOOFING, @emit, @pemit, @remit, @oemit, @nspemit
& ON-VACATION
  Flag:  ON-VACATION  (players)

  This flag may be used by the MUSH to allow players to indicate when they have left for vacation, to prevent themselves from being purged for inactivity. Its usefulness depends on game policy.
  
  You will be notified (periodically and on connect) if you leave this flag set, to remind you to unset it when you return from vacation.
& OPAQUE
  Flag:  OPAQUE  (all types)

  When set on players and things, OPAQUE prevents others who look at the object from seeing its inventory. It also stops anyone inside the object from using look/outside to see the object's location.
  
  When set on an exit in a TRANSPARENT room, the exit is displayed as if the room weren't TRANSPARENT.

  Meaningless for rooms.

See also: TRANSPARENT, look
& ORPHAN
  Flag:  ORPHAN  (all types)

  Normally, all objects have an ancestor at the top of their @parent chain, and attributes, locks, etc, are inherited from the ancestor after all real @parents have been checked. When an object is set ORPHAN, its ancestor is ignored.

See also: @parent, ancestors
& PUPPET
  Flag:  PUPPET  (things)
  
  Things which are set PUPPET relay all sound they hear to their owner. Puppets won't normally relay sound if they are in the same room as their owner, but will if the VERBOSE flag is also set.
  
  If you want to relay sound to someone other than the object's owner, consider @forwardlist instead.

See: @force, PUPPETS, @forwardlist
& QUIET
  Flag:  QUIET  (all types)

  This flag suppresses several acknowledgement messages from commands, such as 'Set', 'Triggered', 'Teleported', etc. 
& ROYALTY
  Flag:  ROYALTY  (all types)

  The Royalty flag gives an object a limited subset of Wizard powers. Royalty can use the admin WHO, @teleport any object to any location, use @hide, and many other things. Unlike Wizards, they do not implicitly control all objects.
  
  Only Wizards can set players royalty, though players who are already set royalty can set their own objects royalty as well.
  
  Royalty grants the following @powers implicitly: functions, idle, link_anywhere, login, long_fingers, no_quota, open_anywhere and see_all. See 'help <power> power' for more info.

See also: WIZARD, @power
& SAFE
  Flag:  SAFE  (all types)

  Objects set SAFE cannot be destroyed with @destroy (@nuke must be used instead). If the "really_safe" @config option is on, objects set SAFE will not be destroyed when their owner is @destroyed, but will be @chown'd to God instead.
  
  There is also a SAFE attribute flag, which protects a single attribute from being altered; see 'help attribute flags' for more information.
  
See also: @destroy, DESTROY_OK
& STICKY
  Flag:  STICKY  (all types)

  If a thing or player is STICKY, it goes home when dropped. It also goes home when an object carrying it teleports or goes home, unless the object controls it.
  
  If a room is STICKY, its drop-to is delayed until the last person leaves.
  
  This flag is meaningless for exits.
  
See also: home, @teleport, DROP-TOS
& SUSPECT
  Flag:  SUSPECT  (all types)

  This flag is only settable by wizards. Players with this flag have their connects, disconnects, and name changes reported to all connected wizards. Actions by any object with this flag are also logged to the MUSH log files.
& TERSE
  Flag:  TERSE  (players, things)

  When an object is set TERSE, it does not see the descriptions, or success and failure messages in rooms. This is a useful flag if you're on a slow connection or you're moving through a familiar area and don't want to see tons of text.

  When a player is TERSE, all of their objects are considered to be TERSE.

See also: MYOPIC
& TRANSPARENT
  Flag:  TRANSPARENT  (all types)

  Transparent rooms show the "Obvious Exits" list in a long format; instead of showing all exits on a single line, each exit is displayed on its own line, with the name of its location. Any exits set OPAQUE are still shown in short format, so you can mix the two.

  Transparent exits show the description and contents of the destination room, as well as the exit's desc, when looked at. If the exit is also set CLOUDY, the destination's contents is not shown.
  
  Example:
    > @set here=transparent
    > look
    A Room
    Obvious Exits:
      Yellow Brick Road leads to Oz.
      Looking Glass leads to Wonderland.
      Locked Door leads nowhere.

See also: OPAQUE, CLOUDY, @exitformat
& UNFINDABLE
  Flag:  UNFINDABLE  (all types)
  
  If a player is set UNFINDABLE, he cannot be found by the @whereis command. You also cannot use loc(), locate(), and similar functions to find his location, unless you have the see_all power or equivalent.
  
  If a room is set UNFINDABLE, you cannot locate any of its contents via any means (@whereis, the loc() function, etc.) unless you are see_all.
  
  Wizards, Royalty, and players with the Hide and Idle @powers who are idle for longer than the idle_timeout @config option who are set UNFINDABLE will automatically be @hidden.
  
See also: loc(), @whereis, @hide
& UNINSPECTED
  Flag: UNINSPECTED (rooms)

  This flag has no hardcoded purpose, but may be used by MUSH staff to indicate that a room has been inspectedapproved by staff yet.

See also: UNREGISTERED
& UNREGISTERED
  Flag: UNREGISTERED (players)
  
  This flag may be used by the MUSH to support on-line registration. The only restriction on UNREGISTERED players is that they may not be granted @powers.
  
See also: UNINSPECTED
& VERBOSE
  Flag:  VERBOSE  (all types)

  An object set VERBOSE echoes the commands it executes to its owner before executing them. This differs from the PUPPET flag in that the owner sees the command itself, rather than the output from the command.  This flag is extremely useful in debugging, especially if used in conjunction with the PUPPET and DEBUG flags.
  
  Setting the VERBOSE flag on a PUPPET also causes the puppet to relay sound to its owner, even when they are in the same room.
  
  Example:
    > @create Test
    Created: Object #5.
    > @set Test=VERBOSE
    Test - VERBOSE set.
    > @force Test=say capstr(hello)
    #5] say capstr(hello)
    Test says, "Hello"
    
See also: PUPPET, DEBUG
& VISUAL
  Flag:  VISUAL  (all types)

  When this flag is set on an object, it allows any other player who passes the object's @lock/examine to examine it and see all the object's attributes, and other information such as parent, zone, home, location, etc. It does not allow them to make changes to the object. Very useful for getting help with code.
  
  There is also a VISUAL attribute flag, which only affects a single attribute, and a VISUAL lock flag, which affects @locks. See 'help attribute flags' and 'help @lset' for details.

See also: examine, brief, @lock
& WIZARD
  Flag:  WIZARD  (all types)

  Objects set WIZARD control all other objects on the MUSH (except God), can use a wide variety of commands, perform many actions remotely via dbref number or *<player>, and have many powers and privileges which mortal players do not.
  
  Only God can set or clear the WIZARD flag on players, though wizards may set objects they own WIZARD. WIZARD objects share the same powers as WIZARD players, with the exception that they cannot @nuke players.
  
See also: ROYALTY, @power
& Z_TEL
  Flag:  Z_TEL  (things, rooms)

  The Z_TEL flag, when set on a zoned room or on the ZMO of a room, prevents objects in the room from being @teleported out of the zone - that is, objects can only be @teleported to a room which is zoned to the same ZMO. Setting this flag on the ZMO affects all rooms zoned to it. Like NO_TEL, the "home" command will still work. This flag is intended for use in puzzle rooms and IC areas.

See also: ZONES, ZONE MASTERS, @chzone, ZONE MASTER ROOMS, NO_TEL, JUMP_OK
& SHARED
& ZONE
  Flag:  SHARED   (players) 

  The SHARED flag is used to designate a player as a Shared Player. Objects owned by a Shared Player are controlled by anyone who passes the player's zone @lock.

See also: SHARED PLAYERS, @lock
& LISTEN_PARENT
  Flag:  LISTEN_PARENT (players, things, rooms)
  
  When set on an object which also has the MONITOR flag set, this flag causes ^-listen patterns to be checked on the object's parents as well as on the object.

See also: MONITOR, LISTENING
& POWERS LIST
  Powers can be granted only by wizards, using the @power command. Powers cannot be granted to players who are set UNREGISTERED. Powers normally give the player the ability to use a limited set of wizard/admin powers. See 'help <power> power' for more info on any power.

  announce              Can use @wall command.  
  boot                  Can use @boot command.
  builder               Can use Builder commands.
  chat_privs            Can use Admin channels.
  debit                 Can use give with a negative amount.
  functions             Can use @function command.
  guest                 Guest. Restricted command set.
  halt                  Can @halt others' objects and do @allhalt.
  hide                  Can hide on the WHO list.
  hook                  Can use the @hook command.
  idle                  No inactivity timeout.
  link_anywhere         Can @link an exit to anyplace.
  login                 Not subject to login restrictions.
  long_fingers          Can do things remotely, like "get".
  many_attribs          Can exceed max_attrs_per_obj.

  Continued in 'help powers2'.
& POWERS2
& POWERS LIST2
  no_pay *              Doesn't need money for anything
  no_quota *            Has an unlimited quota
  open_anywhere         Can @open an exit from any room.
  pemit_all             Can @pemit to HAVEN/ulocked players.
  pick_dbref            Can recycle specific garbage dbrefs when creating objects.
  player_create         Can use @pcreate command.
  poll                  Can use @poll command.
  queue                 Has queue limit equal to the size of the database.
  quotas                Can use @quota commands on other players.
  search                Can do @search, @stats, and @entrances on anything.
  see_all               Sees everything as if it were Visual.
  see_queue             Can do @ps on anyone, and @ps/all.
  send_oob              Can use oob(), and the xch_cmd and send pueblo tags
  sql_ok                Can perform SQL queries
  tport_anything        Can @teleport anything.
  tport_anywhere        Can @teleport to anywhere.
  can_spoof             Can use @ns*emit, ns*emit() and @*emit/spoof
  can_dark              Can @set themselves dark
  can_http              Can use @http
  
  * When these powers are set on a player, all the objects they own which are not set MISTRUST are also considered to have the power.

See also: help @power, and especially @power/list
& ANNOUNCE POWER

  The Annouce @power lets objects set the Message of the Day via @motd, and use the @wall command to send a message to all connected players. Wizards have the power implicitly.
  
See also: @wall, @motd, CHAT_PRIVS POWER, loud, CAN_SPOOF POWER
& BOOT POWER

  Objects with the Boot power can @boot other players from the MUSH. Wizards have the power implicitly.
  
See also: @boot
& BUILDER POWER
  BUILDER 

  On some MUSHes, building (@dig, @open, and/or @create) is restricted to those with the BUILDER @power. You can check to see if building is restricted on a MUSH with '@command @dig', etc.

See also: @dig, @open, @create, @link, PLAYER_CREATE POWER
& CHAT_PRIVS POWER

  The Chat_Privs power allows non-wizard, non-royalty objects to use channels which have been restricted to 'Admin' with @channel/priv.
  
See also: @channel
& DEBIT POWER

  The Debit power lets objects take pennies from players with the 'give' command. Wizards have this power implicitly.
  
See also: give, money, NO_PAY POWER
& FUNCTIONS POWER

  The Functions power allows an object to use the @function command to add or delete functions. Wizards and royalty have this power implicitly.
  
See also: @function
& GUEST POWER

  Objects set Guest are very limited: they cannot control anything in the database (including themselves), which prevents them from setting flags or attributes, etc (though, for backwards compatability, they can still examine themselves). They cannot join channels, or create objects. MUSHes often restrict other commands so that guests cannot use them.
  
  It's also possible to connect to a Guest player without using a password, allowing them to be used by newcomers to visit a game without making a character.
  
  Guests also have (and receive) a different amount of pennies to normal players (determined by the max_guest_pennies and guest_paycheck @config options).  They receive a different message when they connect (set via the guest_file config option). The way Guest connections work can be controlled via the max_guests @config option, and Guest logins can be disabled entirely with the guests @config option.
& HALT POWER

  The Halt power allows an object to @restart any object, @halt any object or pid, and to use @halt/all and @restart/all. Wizards have the power implicitly.

See also: @halt, @restart, @wait, QUEUE POWER, SEE_QUEUE POWER, HALT
& HIDE POWER

  The Hide power allows players to use the @hide command, as well as the 'ch' command at the login screen. Players who have both this power and the Idle power will be set Hidden automatically when their connection reaches the idle time limit.
  
  Wizards have this power implicitly.
  
See also: @hide, hidden(), ch, IDLE POWER
& HOOK POWER

  Objects with the Hook @power can use the @hook command to hook built-in commands. Intended for startup objects which don't need to be wizard. Wizards have this power implicitly.
  
See also: @hook, @command
& IDLE POWER

  The Idle power stops a player from being disconnected when he has been idle for the idle_timeout. Instead, you will be hidden (if you also have the Hide power), or will simply remain connected. Wizards and Royalty have the power implicitly.

See also: HIDE POWER
& LINK_ANYWHERE POWER

  The Link_Anywhere power allows an object to link exits to any location. Can be useful for variable exits. Wizards and Royalty have the power implicitly.

See also: LINK_OK, OPEN_ANYWHERE POWER, @link
& LOGIN POWER

  The Login power allows a player to connect to the MUSH, even when logins have been disabled (via the "logins" @config option). Wizards and royalty have the power implicitly.

See also: @sitelock
& LONG_FINGERS POWER

  The Long_Fingers power allows objects to run a number of commands (including "look", "with", "get" and others) on objects which they are not nearby. Wizards and Royalty have the power implicitly.
& MANY_ATTRIBS POWER

  The Many_Attribs power allows an object to have up to a million attributes, rather than the usual limit set in the max_attrs_per_object @config option. Useful for database objects.
& NO_PAY POWER

  The No_Pay power gives an object infinite pennies; it will never run out. Use carefully! Pennies are intended to prevent runaway code (infinite loops) which can lag the game. It's recommended that, instead of setting objects no_pay, you regularly give them large amounts of money instead, as this will allow them to function correctly without letting them loop indefinitely.
  
  Wizards used to have this power implicitly, but no longer do, for the reasons given above. (Wizards can still give infinite numbers of pennies, to others or themselves, however.)
  
  God is implicitly no_pay and, if you have the power and are not set MISTRUST, your objects are implicitly no_pay.
  
See also: give, DEBIT POWER
& NO_QUOTA POWER

  The No_Quota power lets you create an unlimited number of objects, regardless of @quota settings. Wizards, Royalty, and their objects have this power implicitly.
  
  If you have this power, and are not set MISTRUST, your objects have the power implicitly.
  
See also: QUOTA POWER, @quota
& OPEN_ANYWHERE POWER

  The Open_Anywhere power lets you @open exits from any location. Wizards and Royalty have the power implicitly.
  
See also: @open, OPEN_OK, @lock/open
& PEMIT_ALL POWER

  The Pemit_All power lets you page or @pemit any object, regardless of their @lock/page. Wizards have this power implicitly.
  
See also: LOUD, page, @pemit, @lock/page, CAN_SPOOF POWE
& PLAYER_CREATE POWER

  This power allows objects to use @pcreate. Wizards have the power implicitly.
  
See also: @pcreate
& POLL POWER

  Allows objects to change the @poll. Wizards have the power implicitly.
  
See also: @poll
& PUEBLO_SEND POWER
& SEND_OOB POWER

  The Send_OOB power allows objects to send out-of-band strings, including potentially unsafe Pueblo/HTML strings (via tag() and similar functions) and messages via oob(). Wizards have the power implicitly.
  
  This power used to be called Pueblo_Send; it remains an alias for backwards compatability.
  
See also: oob(), Pueblo, tag(), tagwrap(), html()
& QUEUE POWER

  Normally, the number of action lists an object can queue is limited by the queue_quota @config option. Objects with this power can queue additional action lists, equal to the number of objects in the database. Wizards have the power implicitly.
  
See also: SEE_QUEUE POWER
& QUOTAS POWER

  Objects with this power can see and change anyones quotas. Wizards have the power implicitly.
  
See also: QUOTA, NO_QUOTA POWER, @quota
& SEARCH POWER

  The Search power allows someone to use @search and @stats on objects they can't examine. It also allows them to use the objmem() and playermem() functions.
  
See also: SEE_ALL POWER, @search, @stats, objmem(), playermem(), lsearch()
& SEE_ALL POWER

  The See_All power allows an object to examine anything in the database. Wizards and Royalty have the power implicitly.
& SEE_QUEUE POWER

  The See_Queue power allows an object to use @ps, lpids() and related functions on any object/queue. Wizards and Royalty have this power implicitly.
  
See also: @ps, lpids(), getpids(), pidinfo(), HALT POWER
& SQL_OK POWER

  This power lets an object use @sql, sql() and related commands and functions, if the MUSH is connected to an SQL server. Wizards have the power implicitly.
  
See also: @sql, sql(), @mapsql, mapsql(), sqlescape()
& TPORT_ANYTHING POWER
& TPORT_ANYWHERE POWER

  The Tport_Anything power allows an object to teleport any object to a location they are allowed to teleport to.
  
  Tport_Anywhere allows an object to teleporting anything it is allowed to teleport to any location.
  
See also: HEAVY, @teleport, NO_TEL, Z_TEL
& CAN_SPOOF POWER

  The Can_Spoof power lets you use the @ns*emit commands and ns*emit() functions, which show messages without nospoof information. It also lets you use the /spoof switch to various @*emit commands, which shows nospoof information as the enactor rather than the executor. Wizards have this power implicitly.
  
See also: @nspemit, @pemit
& CAN_DARK POWER

  Objects with this power can set themselves DARK, and use the "cd" command at the connection screen to connect set dark.
  
See also: DARK, @hide, HIDE POWER
& PICK_DBREF POWER

  Objects with this power can use the optional dbref arguments to object creation commands to specify garbage objects to reuse, instead of the one at the head of the stack of garbage.
& FUNCTIONS
& FUNCTION
  Functions are specialized commands used to manipulate strings and other input. Functions take the general form: [FUNCTION(<input>)]

  The brackets are used to delimit and force evaluation of the function (or nested functions). The brackets can also be used to group functions for the purposes of string concatenation. In general, more than one pair of brackets is not required, but you can nest an arbitrary number of brackets.

  Examples:
    > say first(rest(This is a nice day))
    You say, "is"

    > @va me=This is a
    > @vb me=nice day
    > say first(rest(v(va) [v(vb)]))
    You say, "is"

  See 'help functions2' for more.
& FUNCTIONS2
  There are two types of functions, "built-in functions" and "global user functions", also known as "@functions". You can get a complete list of functions on this game with "@list/functions".

  Built-in functions are written in the game hardcode, while @functions are written in softcode, and then made global with the "@function" command. Both are used in exactly the same manner. For more information on @functions, see 'help @function'.

See also: MUSHCODE, FUNCTION LIST
& FUNCTION LIST
& FUNCTION TYPES
  Several major variants of functions are available. The help topics are listed below, together with a quick summary of the function type and some examples of that type of function.

  Attribute functions: attribute-related manipulations (GET, UFUN)
  Bitwise functions: Manipulation of individual bits of numbers (SHL, BOR)
  Boolean functions: produce 0 or 1 (false or true) answers (OR, AND)
  Channel functions: Get information about channels (CTITLE, CWHO)
  Communication functions: Send messages to objects (PEMIT, OEMIT)
  Connection functions: Get information about a player's connection (CONN)
  Dbref functions: return dbref info related to objects (LOC, LEXITS)
  Html functions: output html tags for Pueblo-compatible clients
  Information functions: find out something about objects (FLAGS, MONEY)
  List functions: manipulate lists (REVWORDS, FIRST)
  Mail functions: manipulate @mail (MAIL, FOLDERSTATS)
  Math functions: number manipulation, generic or integers only (ADD, DIV)
  Regular expression functions: Regular expressions (REGMATCH, REGEDIT)
  SQL functions: Access SQL databases (SQL, SQLESCAPE)
  String functions: string manipulation (ESCAPE, FLIP)
  Time functions: Formatting and display of time (TIME, CONVSECS)
  Utility functions: general utilities (ISINT, COMP)

  The command "@list/functions" lists all functions on the game.
  The command "@function" lists only the game's custom global functions defined via the @function command.

& Attribute functions
  These functions can access or alter information stored in attributes on objects.

  aposs()        attrib_set()   default()      edefault()     eval()
  flags()        get()          grep()         grepi()        hasattr()
  hasattrp()     hasattrval()   hasflag()      lattr()        lflags()
  nattr()        obj()          pfun()         poss()         reglattr()
  regrep()       regrepi()      regxattr()     set()          subj()
  udefault()     ufun()         ulambda()      uldefault()    ulocal()
  v()            wildgrep()     wildgrepi()    xattr()        xget()
  zfun()

See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES
& Bitwise functions
  These functions treat integers as a sequence of binary bits (either 0 or 1) and manipulate them.

  For example, 2 is represented as '0010' and 4 as '0100'. If these two numbers are bitwise-or'ed together with BOR(), the result is 6, or (in binary) '0110'. These functions are useful for storing small lists of toggle (Yes/No) options efficiently.

  baseconv()    band()        bnand()       bnot()        bor()
  bxor()        shl()         shr()

& Boolean functions
  Boolean functions all return 0 or 1 as an answer.

  Your MUSH may be configured to use traditional PennMUSH booleans, in which case non-zero numbers, non-negative db#'s, and strings are all considered "true" when passed to these functions. Alternatively, your MUSH may be using TinyMUSH 2.2 booleans, in which case only non-zero numbers are "true". Check @config tiny_booleans.

  and()         cand()        cor()         eq()          gt()
  gte()         lt()          lte()         nand()        neq()
  nor()         not()         or()          t()           xor()

See also: BOOLEAN VALUES, @config
& Communication functions
  Communication functions are side-effect functions that send a message to an object or objects.

  cemit()       emit()        lemit()       message()     nsemit()
  nslemit()     nsoemit()     nspemit()     nsprompt()    nsremit()
  nszemit()     oemit()       pemit()       prompt()      remit()
  zemit()

See also: Channel functions, Mail functions
& Connection functions
  Connection functions return information about the connections open on a game, or about specific connections.

  cmds()        conn()        connlog()     connrecord()  doing()
  height()      host()        hidden()      idle()        ipaddr()
  lports()      lwho()        lwhoid()      mwho()        mwhoid()
  nmwho()       nwho()        player()      ports()       pueblo()
  recv()        sent()        ssl()         terminfo()    width()
  xmwho()       xmwhoid()     xwho()        xwhoid()      zmwho()
  zwho()
& Dbref functions
  Dbref functions return a dbref or list of dbrefs related to some value on an object.

  children()    con()         entrances()   exit()        followers()
  following()   home()        lcon()        lexits()      loc()
  locate()      lparent()     lplayers()    lsearch()     lvcon()
  lvexits()     lvplayers()   namelist()    next()        nextdbref()
  num()         owner()       parent()      pmatch()      rloc()
  rnum()        room()        where()       zone()

See also: DBREF, Information functions
& Information functions
  Information functions return values related to objects or the game.

  accname()      alias()        andflags()     andlflags()    andlpowers()
  config()       controls()     csecs()        ctime()        elock()
  findable()     flags()        fullalias()    fullname()     getpids()
  hasattr()      hasattrp()     hasflag()      haspower()     hastype()
  iname()        lflags()       lock()         lockflags()    lockowner()
  locks()        lpids()        lstats()       money()        moniker()
  msecs()        mtime()        mudname()      mudurl()       name()
  nattr()        nearby()       objid()        objmem()       orflags()
  orlflags()     orlpowers()    pidinfo()      playermem()    poll()
  powers()       quota()        restarts()     type()         version()
  visible()

See also: Dbref functions
& List functions
  List functions take at least one list of elements and return transformed lists or one or more members of those lists. Most of these functions can take an arbitrary <delimiter> argument to specify what delimits list elements; if none is provided, a space is used by default.

  elements()    extract()     filter()      filterbool()  first()
  fold()        grab()        graball()     index()       itemize()
  items()       iter()        last()        ldelete()     linsert()
  lreplace()    lockfilter()  map()         match()       matchall()
  member()      mix()         munge()       namegrab()    namegraball()
  randword()    remove()      rest()        revwords()    setdiff()
  setinter()    setunion()    shuffle()     sort()        sortby()
  sortkey()     splice()      step()        table()       unique()
  wordpos()     words()

See also: LISTS
& Math functions
  Math functions take one or more floating point numbers and return a numeric value.
  abs()         acos()        add()         asin()        atan()
  atan2()       bound()       ceil()        cos()         ctu()
  dist2d()      dist3d()      e()           exp()         fdiv()
  floor()       fmod()        fraction()    ln()          lmath()
  log()         max()         mean()        median()      min()
  mul()         pi()          power()       root()        round()
  sign()        sin()         sqrt()        stddev()      sub()
  tan()         trunc()       val()

  These functions operate only on integers (if passed floating point numbers, they will return an error or misbehave):
  dec()         div()         floordiv()    inc()         mod()
  remainder()

  Math functions are affected by a number of @config options, including the TinyMUSH compatability options null_eq_zero and tiny_math.

See also: Vector Functions
& Vector functions
  These functions operate on n-dimensional vectors. A vector is a delimiter-separated list of numbers (space-separated, by default):

  vadd()        vcross()      vdim()        vdot()        vmag()
  vmax()        vmin()        vmul()        vsub()        vunit()

See also: Math functions
& Regular expression functions
  These functions take a regular expression (regexp, or re) and match it against assorted things.

  regedit()     regeditall()   regeditalli()  regediti()     reglattr()
  reglattrp()   regmatch()     regmatchi()    regnattr()     regnattrp()
  regrab()      regraball()    regraballi()   regrabi()      regrep()
  regrepi()     reswitch()     reswitchall()  reswitchalli() reswitchi()
  regxattr()    regxattrp()

See also: string functions, regexp
& SQL functions
  These functions perform queries or other operations on an SQL database to which the MUSH is connected, if SQL support is available and enabled.

  sql()         sqlescape()   mapsql()

& String functions
  String functions take at least one string and return a transformed string, parts of a string, or a value related to the string(s).

  accent()         after()          align()          alphamax()
  alphamin()       art()            before()         brackets()
  capstr()         case()           caseall()        cat()
  center()         chr()            comp()           cond()
  condall()        decode64()       decompose()      decrypt()
  digest()         edit()           encode64()       encrypt()
  escape()         flip()           foreach()        if()
  ifelse()         lcstr()          left()           lit()
  ljust()          lpos()           merge()          mid()
  ord()            ordinal()        pos()            regedit()
  regmatch()       repeat()         right()          rjust()
  scramble()       secure()         sha0()           space()
  spellnum()       squish()         strallof()       strcat()
  strdelete()      strfirstof()     strinsert()      stripaccents()
  stripansi()      strlen()         strmatch()       strreplace()
  switch()         tr()             trim()           ucstr()
  urldecode()      urlencode()      wrap()

See also: STRINGS
& Time functions
  These functions return times or format times.

  convsecs()    convutcsecs() convtime()    convutctime() ctime()
  etime()       etimefmt()    isdaylight()  mtime()       restarttime()
  secs()        starttime()   stringsecs()  time()        timecalc()
  timefmt()     timestring()  utctime()     uptime()

See also: TIMEZONES
& Utility functions
  These functions don't quite fit into any other category.

  allof()       ansi()        atrlock()     beep()        benchmark()
  checkpass()   clone()       create()      die()         dig()
  endtag()      firstof()     functions()   fn()          html()
  ibreak()      ilev()        inum()        isdbref()     isint()
  isnum()       isobjid()     isregexp()    isword()      itext()
  letq()        localize()    link()        list()        listq()
  lnum()        lset()        null()        numversion()  objeval()
  open()        pcreate()     r()           rand()        s()
  scan()        set()         setq()        setr()        slev()
  soundex()     soundslike()  speak()       stext()       suggest()
  tag()         tagwrap()     tel()         testlock()    textentries()
  textfile()    unsetq()      valid()       wipe()        @@()
  uptime()

& @@()
& NULL()
  @@(<expression>)
  null(<expression>[, ... , <expression>])

  The @@() function does nothing and returns nothing. It does not evaluate its argument. It could be used for commenting, perhaps.

  The null() function is similar, but does evaluate its argument(s), so side-effects can occur within a null(). Useful for eating the output of functions when you don't use that output.

See also: @@
& ABS()
  abs(<number>)

  Returns the absolute value of a number.

  Examples:
    > say abs(-4)
    You say, "4"

    > say abs(2)
    You say, "2"

See also: sign()
& ACCENT()
  accent(<string>, <template>)

  The accent() function will return <string>, with characters in it possibly changed to accented ones according to <template>. Both arguments must be the same size.

  Whether or not the resulting string is actually displayed correctly is client-dependent. Some OSes uses different character sets than the one assumed (Unicode and ISO 8859-1), and some clients strip these 8-bit characters.

  For each character in <string>, the corresponding character of <template> is checked according to the table in 'help accents', and a replacement done. If either the current <string> or <template> characters aren't in the table, the <string> character is passed through unchanged.

  See 'help accent2' for some examples.

See also: stripaccents(), NOACCENTS, @nameaccent, accname(), ACCENTS
& ACCENTS
  Below is the table of possible accents which can be used with accent() and @nameformat.

  Accent                         Template   String
  Name       Description         Character  Character
  --------------------------------------------------------------
  grave      Backward slant      `          A,E,I,O,U,a,e,i,o,u
             above letter (À)
  acute      Forward slant       '          A,E,I,O,U,Y,a,e,i,o,u,y
             above letter (Á)
  tilde      Wavy line above     ~          A,N,O,a,n,o
             letter (Ñ)
  circumflex carat above         ^          A,E,I,O,U,a,e,i,o,u
             letter (Â)
  umlaut     Two dots above      :          A,E,I,O,U,,a,e,i,o,u,y
  diaeresis  letter (Ä)
  ring       Small circle above  o          A,a
             letter (Å)
  cedilla    Small tail below    ,          C,c
             letter (Ç)

  Continued in 'HELP ACCENTS2'
& ACCENTS2
  These are non-accent special characters, mostly punctuation and non-roman letters.

                      Template   String
  Description         Character  Character
  --------------------------------------------------------------
  Upside-down ? (¿)       u          ?
  Upside-down ! (¡)       u          !
  << quote mark («)       "          <
  >> quote mark (»)       "          >
  German sharp s (ß)      B          s
  Capital thorn (Þ)       |          P
  Lower-case thorn (Þ)    |          p
  Capital eth (Ð)         -          D
  Lower-case eth (ð)      &          o

  See 'HELP ACCENTS3' for examples
& ACCENT2
& ACCENTS3
  Some examples of accent() and their expected outputs:

    > think accent(Aule, ---:)
    Aul(e-with-diaeresis)
    Aulë

    > think accent(The Nina was a ship, The Ni~a was a ship)
    The Ni(n-with-~)a was a ship
    The Niña was a ship

    > think accent(Khazad ai-menu!, Khaz^d ai-m^nu!)
    Khaz(a-with-^)d ai-m(e-with-^)nu!
    Khazâd ai-mênu
& ACCNAME()
  accname(<object>)

  accname() returns the name of <object>, applying the object's
  @nameaccent, if any.

See also: name(), fullname(), iname(), ACCENTS
& ACOS()
  acos(<cosine>[, <angle type>])

  Returns the angle that has the given <cosine> (arc-cosine), with the angle expressed in the given <angle type>, or radians by default.

  See 'HELP ANGLES' for more on the <angle type>.

See also: asin(), atan(), cos(), ctu(), sin(), tan()
& ADD()
  add(<number1>, <number2>[, ... , <numberN>])

  Returns the sum of the given numbers.

See also: MATH FUNCTIONS, lmath()
& AFTER()
  after(<string1>, <string2>)

  Returns the portion of <string1> that occurs after <string2>. If <string2> isn't in <string1>, the function returns nothing. This is case-sensitive.

  Examples:
    > say after(foo bar baz,bar)
    You say, " baz"

    > say after(foo bar baz,ba)
    You say, "r baz"

See also: before(), rest()
& ALIGN()
& LALIGN()
  align(<widths>, <col>[, ... , <colN>[, <filler>[, <colsep>[, <rowsep>]]]])
  lalign(<widths>, <colList>[, <delim>[, <filler>[, <colsep>[, <rowsep>]]]])

  Creates columns of text, each column designated by <col> arguments. Each <col> is individually wrapped inside its own column, allowing for easy creation of book pages, newsletters, or the like. In lalign(), <colList> is a <delim>-separated list of the columns.

  <widths> is a space-separated list of column widths. '10 10 10' for the widths argument specifies that there are 3 columns, each 10 spaces wide. You can alter the behavior of a column in multiple ways. (Check 'help align2' for more details)

  <filler> is a single character that, if given, is the character used to fill empty columns and remaining spaces. <colsep>, if given, is inserted between every column, on every row. <rowsep>, if given, is inserted between every line. By default, <filler> and <colsep> are a space, and <rowsep> is a newline.

  Continued in 'help align2'
& ALIGN2
  You can modify column behavior within align(). The basic format is:

  [justification]Width[options][(ansi)]

  Justification: Placing one of these characters before the width alters the spacing for this column (e.g: <30). Defaults to < (left-justify).
    < Left-justify       - Center-justify        > Right-justify
    _ Full-justify       = Paragraph-justify

  Other options: Adding these after the width will alter the column's behaviour in some situtations
    . Repeat for as long as there is non-repeating text in another column.
    ` When this column runs out of text, merge with the column to the left
    ' When this column runs out of text, merge with the column to the right
    $ nofill: Don't use filler after the text. If this is combined with merge-left, the column to its left inherits the 'nofill' when merged.
    x Truncate each (%r-separated) row instead of wrapping at the colwidth
    X Truncate the entire column at the end of the first row instead of wrapping
    # Don't add a <colsep> after this column. If combined with merge-left, the column to its left inherits this when merged.

  Ansi: Place ansi characters (as defined in 'help ansi()') within ()s to define a column's ansi markup.

  See 'help align3' for examples.
See also: center(), ljust(), rjust(), table()
& ALIGN3
  Examples:

    > &line me=align(<3 10 20$,([ljust(get(%0/sex),1,,1)]), name(%0),name(loc(%0)))
    > th iter(lwho(),u(line,##),%b,%r)
      (M) Walker     Tree
      (M) Ashen-Shug Apartment 306
          ar
      (F) Jane Doe   Nowhere

    > &line me=align(<3 10X 20X$,([ljust(get(%0/sex),1,,1)]), name(%0),name(loc(%0)))
    > th iter(lwho(),u(line,##),%b,%r)
      (M) Walker     Tree
      (M) Ashen-Shug Apartment 306
      (F) Jane Doe   Nowhere

        See 'help align4' for more examples.
& ALIGN4
    > &haiku me = Alignment function,%rIt justifies your writing,%rBut the words still suck.%rLuke

    > th [align(5 -40 5,,[repeat(-,40)]%r[u(haiku)]%r[repeat(-,40)],,%b,+)]

         +----------------------------------------+
         +          Alignment function,           +
         +       It justifies your writing,       +
         +       But the words still suck.        +
         +                  Luke                  +
         +----------------------------------------+

  See 'help align5' for more examples.
& ALIGN5
  > &dropcap me=%b_______%r|__%b%b%b__|%r%b%b%b|%b|%r%b%b%b|_|
  > &story me=%r'was the night before Christmas, when all through the house%rNot a creature was stirring, not even a mouse.%rThe stockings were hung by the chimney with care,%rIn hopes that St Nicholas soon would be there.
  > th align(9'(ch) 68, u(dropcap), u(story))

   _______
  |__   __| 'was the night before Christmas, when all through the house
     | |    Not a creature was stirring, not even a mouse.
     |_|    The stockings were hung by the chimney with care,
  In hopes that St Nicholas soon would be there.

  The dropcap 'T' will be in ANSI cyan-highlight, and merges with the 'story'
  column.

  > th align(>15 60,Walker,Staff & Developer,x,x)
  xxxxxxxxxWalkerxStaff & Developerxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  > th align(>15 60$,Walker,Staff & Developer,x,x)
  xxxxxxxxxWalkerxStaff & Developer
& ALLOF()
  allof(<expr>[, ... , <exprN>], <osep>)

  Evaluates every <expr> argument (including side-effects) and returns the results of those which are true, in a list separated by <osep>. The output separator argument is required, and can be a string of any length (including an empty string; use %b for a space).

  The meaning of true or false depends on configuration options as explained in the 'BOOLEAN VALUES' help topics.

    > &s me=Bats are similar to Rats which are afraid of Cats
    > say allof(grab(v(s),rats),grab(v(s),mats),grab(v(s),bats),)
    You say, "Rats Bats"

    > say allof(#-1,#101,#2970,,#-3,0,#319,null(This Doesn't Count),|)
    You say, "#101|#2970|#319"

    > say allof(foo, 0, #-1, bar, baz,)
    You say, "foobarbaz"
    > say allof(foo, 0, #-1, bar, baz,%b)
    You say, "foo bar baz"

See also: firstof(), BOOLEAN VALUES, strallof(), filter()
& ALPHAMAX()
  alphamax(<word>[, ... , <wordN>])

  Takes any number of <word> arguments, and returns the one which is lexicographically biggest. That is, the <word> would be last in alphabetical order.

  This is equivilent to last(sort(<word> ... <wordN>,a)).

See also: alphamin(), max()
& ALPHAMIN()
  alphamin(<word>[, ... , <wordN>])

  Takes any number of <word> arguments, and returns the one which is lexicographically smallest. That is, the word that would be first in alphabetical order.

  This is equivilent to first(sort(<word> ... <wordN>,a)).

See also: alphamax(), min()
& AND()
& CAND()
  and(<boolean1>, <boolean2>[, ... , <booleanN>])
  cand(<boolean1>, <boolean2>[, ... , <booleanN>])

  These functions take any number of boolean values, and return 1 if all are true, and 0 otherwise. and() will always evaluate all its arguments (including side effects), while cand() stops evaluation after the first false argument.

See also: BOOLEAN VALUES, nand(), or(), xor(), not(), lmath()
& ANDFLAGS()
& ANDLFLAGS()
  andflags(<object>, <string of flag letters>)
  andlflags(<object>, <list of flag names>)

  These functions return 1 if <object> has all of the given flags, and 0 if it does not. andflags() takes a string of single flag letters, while andlflags() takes a space-separated list of flag names. In both cases, a ! before the flag means "not flag".

  If there is a syntax error like a ! without a following flag, '#-1 INVALID FLAG' is returned. Unknown flags are treated as being not set.

  Example: Check to see if %# is set Wizard and Dark, but not Ansi.
    > say andflags(%#, WD!A)
    > say andlflags(%#, wizard dark !ansi)

See also: orflags(), flags(), lflags()
& ANDLPOWERS()
  andlpowers(<object>, <list of powers>)

  This function returns 1 if <object> has all the powers in a specified list, and 0 if it does not. The list is a space-separated list of power names. A '!' preceding a flag name means "not power".

  Thus, ANDLPOWERS(me, no_quota no_pay) would return 1 if I was powered no_quota and no_pay. ANDLPOWERS(me, poll !guest) would return 1 if I had the poll power but not the guest power.

  If there is a syntax error like a ! without a following flag, '#-1 INVALID POWER' is returned. Unknown powers are treated as being not set.

See also: powers(), orlpowers(), POWERS LIST, @power
& ANSI()
  ansi(<codes>[ ... <codesN>], <string>)

  This allows you to mark up a string using ANSI terminal effects, 16-color codes, and 256 XTERM colors (specified as color names or hex values).

  The old-style <ansi-codes> are listed in "help ansi2".
  Each block of space-separated <codes> can be one or more old-style ANSI codes, as listed in "help ansi2", or a foreground and/or background color. Background colors are prefixed with a "/". Each color can be one of:

    * +<colorname> (for a list of valid names, see "help colors()")
    * a hexcode, optionally in angle brackets (#000000, <#ff0055>, etc)
    * a list of red, green and blue values from 0-255, in angle brackets (<0 0 0>, <255 0 85>, etc)
    * a number from 0-255; this is the same as using "+xterm<number>", for Rhost compatability.

  For example, "ansi(+orange/#0000ff,Test)" would color "Test" in orange, on a blue background. In the event that your client does not support those colors, PennMUSH will downgrade the color to the closest fit that your client can understand.

  Codes are parsed from left to right so, with later codes overriding earlier ones. So, for example:
    ansi(y /+green B <#ffffff>, test)
  would show white text on an ANSI-blue background.

  See 'help ansi3' for more examples.
See also: ANSI, COLOR, @sockset, colorstyle, colors()
& ANSI2
  Old-style valid color codes are:

        f - flash                       F - not flash
        h - hilite                      H - not hilite
        u - underscore                  U - not underscore
        i - inverse                     I - not inverse
        n - normal

        d - default foreground          D - default background
        x - black foreground            X - black background
        r - red foreground              R - red background
        g - green foreground            G - green background
        y - yellow foreground           Y - yellow background
        b - blue foreground             B - blue background
        m - magenta foreground          M - magenta background
        c - cyan foreground             C - cyan background
        w - white foreground            W - white background

  For example, "ansi(fc, Test)" would hilight "Test" in flashing cyan. Default foreground and background use the client's default color for fore and back.
& ANSI3

  Bright yellow text on a blue background:
  > think ansi(yB, foo)

  Orange text on an ANSI-green background:
  > think ansi(G+orange, bar)

  Underlined pink text on a purple background
  > think ansi(u+lightsalmon/#a020f0, ugly)

  ANSI-blue text on a bisque background
  > think ansi(+yellow/+bisque b, the 'b' overrides the earlier '+yellow')
& APOSS()
& %a
  aposs(<object>)

  Returns the absolute possessive pronoun - his/hers/its/theirs - for an object. The %a substitution returns the absolute possessive pronoun of the enactor.

See also: obj(), poss(), subj()
& ART()
  art(<string>)

  This function returns the proper article, "a" or "an", based on whether or not <string> begins with a vowel.
& ASIN()
  asin(<sine>[, <angle type>])

  Returns the angle with the given <sine> (arc-sine), with the angle expressed in the given <angle type>, or radians by default.

  See 'HELP ANGLES' for more on the angle type.

See also: acos(), atan(), cos(), ctu(), sin(), tan()
& ATAN()
& ATAN2()
  atan(<tangent>[, <angle type>])
  atan2(<number1>, <number2>[, <angle type>])

  Returns the angle with the given <tangent> (arc-tangent), with the angle expressed in the given <angle type>, or radians by default.

  atan2(x, y) is like atan(fdiv(x, y)), except y can be 0, and the signs of both arguments are used in determining the sign of the result. It is useful in converting between cartesian and polar coordinates.

  See 'HELP ANGLES' for more on the angle type.

See also: acos(), asin(), cos(), ctu(), sin(), tan()
& ATRLOCK()
  atrlock(<object>/<attrib>[, [on|off]])

  When given a single <object>/<attribute> pair as an argument, returns 1 if the attribute is locked, 0 if unlocked, and #-1 if the attribute doesn't exist or can't be read by the function's caller.

  When given a second argument of "on" (or "off"), attempts to lock (or unlock) the specified attribute, as per @atrlock.

  A locked attribute is one which has the "locked" attribute flag, so this function is roughly equivilent to:

    hasattr(<object>/<attrib>, locked)
    set(<object>/<attribute>, [!]locked)

  except that the attribute's owner is also changed when you lock it via atrlock().

See also: @atrlock, @atrchown, hasflag()
& ATTRIB_SET()
  attrib_set(<object>/<attrib>[, <value>])

  Sets or clears an attribute. With a <value>, it sets the attribute, without one, it clears the attribute. This is an easier-to-read replacement for the old set(<object>, <attrib>:<value>) notation, and a less destructive replacement for wipe() that won't destroy entire attribute trees in one shot.

  If there is a second argument, then attrib_set() will create an attribute, even if the second argument is empty (in which case attrib_set() will create an empty attribute). If the empty_attrs configuration option is off, the attribute will be set to a single space. This means that attrib_set(me/foo,%0) will _always_ create an attribute.

See also: set(), @set
& BAND()
  band(<integer>, <integer>[, ... , <integerN>])

  Does a bitwise AND of all its arguments, returning the result (a number with only the bits set in every argument set in it).

See also: BITWISE FUNCTIONS, lmath()
& BASECONV()
  baseconv(<number>, <from base>, <to base>)

  Converts <number>, which is in base <from base> into base <to base>. The bases can be between 2 (binary) and 64, inclusive.

  Numbers 36 and under use the standard numbers:

  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  All bases over 36 use base64 url string:

  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

  In base 63 and base 64, - is always treated as a digit. Using base64 as a 'from' will also treat + as 62 and / as 63.
& BEEP()
  beep([<number>])

  Returns <number> "alert" bell characters. <number> must be in the range 1 to 5, or, if unspecified, defaults to 1. This function may only be used by royalty and wizards.

& BEFORE()
  before(<string1>, <string2>)

  Returns the portion of <string1> that occurs before <string2>. If <string2> isn't in <string1>, <string1> is returned. This is case-sensitive.

  Examples:
     > say before(foo bar baz,bar)
     You say, "foo"
     > say before(foo bar baz,r)
     You say, "foo ba"
     > say before(foo bar baz,a)
     You say, "foo b"

See also: after(), first()
& BENCHMARK()
  benchmark(<expression>, <number>[, <sendto>])

  Evaluates <expression> <number> times, and returns the average, minimum, and maximum time it took to evaluate <expression> in microseconds. If a <sendto> argument is given, benchmark() instead pemits the times to the object <sendto>, and returns the result of the last evaluation of <expression>.

  Example:
    > think benchmark(iter(lnum(1,100), ##), 200)
    Average: 520.47   Min: 340   Max: 1382
    > think benchmark(iter(lnum(1,100), %i0), 200)
    Average: 110.27   Min: 106   Max: 281
& BRACKETS()
  brackets(<string>)

  Returns a count of the number of left and right square brackets, parentheses, and curly braces in the string, in that order, as a space-separated list of numbers. This is useful for finding missing or extra brackets in MUSH code. <string> is evaluated.

  Example:
    > @desc me=This is [ansi(h,a test)] of the { brackets() function.
    > think brackets(v(desc))
    1 1 2 2 1 0
& BNAND()
  bnand(<integer1>, <integer2>)

  Returns <integer1> with every bit that was set in <integer2> cleared.

See also: BITWISE FUNCTIONS
& BNOT()
  bnot(<integer>)

  Returns the bitwise complement of <integer>. Every bit set in it is cleared, and every clear bit is set.

See also: BITWISE FUNCTIONS
& BOR()
  bor(<integer>, <integer>[, ... , <integerN>])

  Does a bitwise OR of all its arguments, returning the result. (A number with a bit set if that bit appears in any of its arguments).

See also: BITWISE FUNCTIONS, lmath()
& BOUND()
  bound(<number>, <lower bound>, <higher bound>)

  bound() returns <number> if it is between <lower bound> and <higher bound>. If it's lower than <lower bound>, <lower bound> is returned. If it's higher than <higher bound>, <higher bound> is returned.

  If you just want to know whether <number> is within the range of <lower> to <higher>, consider using lte(<lower>, <number>, <higher>) instead to get a boolean result.

See also: ceil(), floor(), round(), trunc()
& BXOR()
  bxor(<integer>, <integer>[, ... , <integerN>])

  Does a bitwise XOR of all its arguments, returning the result. (A number with a bit set if it's set in only one of its arguments).

See also: BITWISE FUNCTIONS, lmath()
& CAPSTR()
  capstr(<string>)

  Returns <string> with the first character capitalized.

  Example:
    > think capstr(foo bar baz)
    Foo bar baz

See also: lcstr(), ucstr()
& CAT()
& STRCAT()
  cat(<string>[, ... , <stringN>])
  strcat(<string1>[, ... , <stringN>])

  These functions concatenate multiple strings together. cat() adds a space between each string; strcat() does not.

  Example:
    > say cat(foo bar, baz blech)
    You say, "foo bar baz blech"
    > say strcat(foo bar, baz blech)
    You say, "foo barbaz blech"
& CENTER()
  center(<string>, <width>[, <fill>[, <rightfill>]])

  This function will center <string> within a field <width> characters wide, using the <fill> string for padding on the left side of the string, and <rightfill> for padding on the right side. <rightfill> defaults to the mirror-image of <fill> if not specified. <fill> defaults to a space if neither <fill> nor <rightfill> are specified.

  If <string> divides <width> into uneven portions, the left side will be one character shorter than the right side.

  Examples:
    > say center(X,5,-)
    You say, "--X--"

    > say center(X,5,-=)
    You say, "-=X=-"

    > say center(.NEAT.,15,-,=)
    You say, "----.NEAT.====="

    > say center(hello,16,12345)
    You say, "12345hello543215"

See also: align(), ljust(), rjust()
& CHECKPASS()
  checkpass(<player>, <string>)

  Returns 1 if <string> matches <player>'s password, and 0 otherwise. If <player> has no password, this function will always return 1.

  This function can only be used by wizards.

See also: @password, @newpassword
& CHR()
& ORD()
  chr(<number>)
  ord(<character>)

  ord() returns the numerical value of the given character. chr() returns the character with the given numerical value.

  Examples:
    > say ord(A)
    You say, "65"
    > say chr(65)
    You say, "A"
& CLONE()
  clone(<object>[, <new name>[, <dbref>[, preserve]]])

  This function clones <object>, as per @clone, and returns the dbref number of the clone, or #-1 if the object could not be cloned.

  The clone will have the same name as the original object unless you give a <new name> for it. Normally, the clone will be created with the first available dbref, but wizards and objects with the pick_dbref power may give the <dbref> of a garbage object to use instead.

  If the optional fourth argument is the string preserve, acts as @clone/preserve.

See also: @clone, create(), dig(), open()
& CMDS()
  cmds(<player|descriptor>)

  Returns the number of commands issued by a player during this connection as indicated by WHO.

  You must be a Wizard, Royalty or See_All to use this function on anyone but yourself.

See also: CONNECTION FUNCTIONS
& SENT()
  sent(<player|descriptor>)

  Returns the number of characters sent by a player during this connection as indicated by SESSION.

  You must be a Wizard, Royalty or See_All to use this function on anyone but yourself.

See also: Connection Functions
& RECV()
  recv(<player|descriptor>)

  Returns the number of characters received by a player during this connection as indicated by SESSION.

  You must be a Wizard, Royalty or See_All to use this function on anyone but yourself.

See also: Connection Functions
& COLORS()
  colors()
  colors(<wildcard>)
  colors(<colors>, <format>)

  With no arguments, colors() returns an unsorted, space-separated list of colors that PennMUSH knows the name of. You can use these colors in ansi(+<colorname>,text). The colors "xterm0" to "xterm255" are not included in the list, but can also be used in ansi().

  With one argument, returns an unsorted, space-separated list of colors that match the wildcard pattern <wildcard>.

  With two arguments, colors() returns information about specific colors. <colors> can be any string accepted by the ansi() function's first argument. <format> must be one of:

   hex, x:      return a hexcode in the format #rrggbb.
   rgb, r:      return the RGB components as a list (0 0 0 - 255 255 255)
   xterm256, d: return the number of the xterm color closest to the given <color>.
   xterm256x,h: return the number of the xterm color in base 16.
   16color, c:  return the letter of the closest ANSI color code (possibly including 'h' for highlight fg colors).
   name:     return a list of names of all the colors exactly matching the given colors, or '#-1 NO MATCHING COLOR NAME' if there is no exact match with a named color.
   auto:     returns the colors in the same format(s) they were given in.

  It can be used for working out how certain colors will downgrade to people using clients which aren't fully color-capable.

  <format> can also include the word "styles", in which case all ANSI styling options (f, u, i and h) present in <colors> are included in the output.

  See 'help colors2' for examples.
See also: ansi(), valid(), colorstyle
& colors2

  Examples:
    > think colors(*yellow*)
    greenyellow yellowgreen lightgoldenrodyellow lightyellow yellow lightyellow1 lightyellow2 lightyellow3 lightyellow4 yellow1 yellow2 yellow3 yellow4

    > think colors(+yellow, hex)
    #ffff00

    > think colors(+yellow, xterm256)
    226

    > think colors(+yellow, 16color)
    yh

    > think colors(/+yellow, 16color)
    Y

    > think colors(#ffff00, name)
    yellow yellow1

    > think colors(iuB+red, hex styles)
    ui#ff0000/#0000ee

    > think colors(+blue huyG/+black, auto)
    hy/+black

& COMP()
  comp(<value1>, <value2>[, <type>])

  comp() compares two values. It returns 0 if they are the same, -1 if <value1> is less than/precedes alphabetically <value2>, and 1 otherwise.

  By default the comparison is a case-sensitive lexicographic (string) comparison. By giving the optional <type>, the comparison can be specified:

      <type>            Comparison
        A               Maybe case-sensitive lexicographic (default)
        I               Always case-insensitive lexicographic
        D               Dbrefs of valid objects
        N               Integers
        F               Floating point numbers

  Whether or not the a sort type is case-sensitive or not depends on the particular MUSH and its environment.
See also: strmatch(), eq()
& CON()
  con(<object>)

  Returns the dbref of the first object in the <object>'s inventory.

  You can get the complete contents of any container you may examine, regardless of whether or not objects are dark. You can get the partial contents (obeying DARK/LIGHT/etc.) of your current location or the enactor (%#). You CANNOT get the contents of anything else, regardless of whether or not you have objects in it.

See also: lcon(), next()
& COND()
& CONDALL()
& NCOND()
& NCONDALL()
  cond(<cond>, <expr>[, ... , <condN>, <exprN>][, <default>])
  condall(<cond>, <expr>[, ... , <condN>, <exprN>][, <default>])
  ncond(<cond>, <expr>[, ... , <condN>, <exprN>][, <default>])
  ncondall(<cond>, <expr>[, ... , <condN>, <exprN>][, <default>])

  cond() evaluates <cond>s until one returns a true value. Should none return true, <default> is returned.

  condall() returns all <expr>s for those <cond>s that evaluate to true, or <default> if none are true.

  ncond() and ncondall() are identical to cond(), except it returns <expr>s for which <cond>s evaluate to false.

  Examples:
    > say cond(0,This is false,#-1,This is also false,#123,This is true)
    You say, "This is true"

    > say ncond(0,This is false,#-1,This is also false,#123,This is true)
    You say, "This is false"

    > say ncondall(0,This is false,#-1,This is also false,#123,This is true)
    You say, "This is falseThis is also false"

See also: firstof(), allof()
& CONFIG()
  config([<option>])

  With no arguments, config() returns a list of config option names. If <option> is given, config() returns the value of the given option Boolean configuration options will return values of "Yes" or "No".

  Example:
    > think config(money_singular)
    Penny

& CONN()
  conn(<player|descriptor>)

  This function returns the number of seconds a player has been connected. <player> should be the full name of a player or a dbref. You can also use a <descriptor> to get connection information for a specific connection when a player is connected more than once. Wizards can also specify the descriptor of a connection which is still at the login screen.

  This function returns -1 for invalid <player|descriptor>s, offline players and players who are dark, if the caller is not able to see them.

See also: CONNECTION FUNCTIONS
& CONTROLS()
  controls(<object>, <victim>[/<attribute>])

  With no <attribute>, this function returns 1 if <object> controls <victim>, or 0, if it does not. With an <attribute>, it will return 1 if <object> could successfully set <attribute> on <victim> (or alter <attribute>, if it already exists). If one of the objects does not exist, it will return #-1 ARGN NOT FOUND (where N is the argument which is the invalid object). If <attribute> is not a valid attribute name, it will return #-1 BAD ATTR NAME. You must control <object> or <victim>, or have the See_All power, to use this function.

See also: visible(), CONTROL
& CONVSECS()
& CONVUTCSECS()
  convsecs(<seconds>[, <timezone>])
  convutcsecs(<seconds>)

  This function converts <seconds> (the number of seconds which have elapsed since midnight on January 1, 1970 UTC) to a time string. Because it's based on UTC, but returns local time, convsecs(0) is not going to be "Thu Jan 1 00:00:00 1970" unless you're in the UTC (GMT) timezone.

  If a <timezone> argument is given, the return value is based on that timezone instead of the MUSH server's local time. See 'help timezones' for more information on valid timezones.

  If Extended convtime() is supported (see @config compile), negative values for <seconds> representing dates prior to 1970 are allowed.

  convutcsecs(<seconds>) is an alias for convsecs(<seconds>, utc).

  Examples:
    > say secs()
    You say, "709395750"

    > say convsecs(709395750)
    You say, "Wed Jun 24 10:22:54 1992"

    > say convutcsecs(709395750)
    You say, "Wed Jun 24 14:22:30 1992"

See also: convtime(), time(), timefmt()
& CONVTIME()
& CONVUTCTIME()
  convtime(<time string>,[<timezone>])
  convutctime(<time string>)

  This functions converts a time string to the number of seconds since Jan 1, 1970 GMT. A time string is of the format:
      Ddd MMM DD HH:MM:SS YYYY
  where Ddd is the day of the week, MMM is the month, DD is the day of the month, HH is the hour in 24-hour time, MM is the minutes, SS is the seconds, and YYYY is the year. If you supply an incorrectly formatted string, it will return #-1.

  convutctime() and convtime() with a second argument of 'utc' assume the timestring is based on UTC time. Other time zones can be specified too. If no <timezone> is given, the server's timezone is used.

  If the extended convtime() is supported (See @config compile), more formats for the date are enabled, including ones missing the day of week and year, and a 'Month Day Year' format. In this case, convtime() can also handle dates prior to 1970 (in which case a negative number will be returned).

  Example:
    > say time()
    You say, "Wed Jun 24 10:22:54 1992"

    > say convtime(Wed Jun 24 10:22:54 1992)
    You say, "709395774"

See also: convsecs(), time(), timezones
& COS()
  cos(<angle>[, <angle type>])

  Returns the cosine of <angle>. Angle must be in the given angle type, or radians by default.

  Examples:
    > say cos(90, d)
    You say, "0"

    > say cos(1.570796)
    You say, "0"

  See 'HELP ANGLES' for more on the angle type.

See also: acos(), asin(), atan(), ctu(), sin(), tan()
& PCREATE()
  pcreate(<name>, <password>[, <dbref>])

  Creates a player with a given <name> and <password>. This function can only be used by wizards.

  The optional third argument can be used to specify a garbage object to use for the new player.

See also: @pcreate, create(), dig(), open()
& CREATE()
   create(<object>[, <cost>[, <dbref>]])

   This function creates an object with name <object> for <cost> pennies, and returns the dbref number of the created object. It returns #-1 on error.

   Wizards may also specify a <dbref>; if this refers to a garbage object, the new object is created with this dbref.

See also: @create, pcreate(), dig(), open()
& CTIME()
& CSECS()
  ctime(<object>[, <utc>])
  csecs(<object>)

  ctime() returns the date and time that <object> was created. The time returned is in the server's local timezone, unless <utc> is true, in which case the time is in the UTC timezone.

  csecs() returns the time as the number of seconds since the epoch. Anyone can get the creation time of any object in the game.

See also: mtime(), time(), secs(), objid()
& ANGLES

  In any function which accepts an angle type, the argument can be one of 'd' for degrees, 'r' for radians, or 'g' for gradians. Gradians are not used often, but it's included for completeness.

  As a refresher, there are 180 degrees in pi radians in 200 gradians.

See also: acos(), asin(), atan(), cos(), ctu(), sin(), tan()
& CTU()
  ctu(<angle>, <from>, <to>)

  Converts between the different ways to measure angles. <from> controls what the angle is treated as, and <to> what form it is turned into. See HELP ANGLES for more information.

  Example:
    > say 90 degrees is [ctu(90, d, r)] radians
    You say, "90 degrees is 1.570796 radians"

See also: acos(), asin(), atan(), cos(), sin(), tan()
& DEC()
  dec(<integer>)
  dec(<string-ending-in-integer>)

  dec() returns the given <integer> minus 1. If given a string that ends in an integer, it decrements only the final integer portion. That is:

    > think dec(3)
    2

    > think dec(hi3)
    hi2

    > think dec(1.3.3)
    1.3.2

    > think dec(1.3)
    1.2

  Note especially the last example, which will trip you up if you use floating point numbers with dec() and expect it to work like sub().

  If the null_eq_zero @config option is on, using dec() on a string which does not end in an integer will return <string>-1. When null_eq_zero is turned off, it will return an error.

See also: inc(), sub()
& DECOMPOSE()
  decompose(<string>)

  decompose() works like escape() with the additional caveat that it inserts parse-able characters to recreate <string> exactly after one parsing. It takes care of multiple spaces, '%r's, and '%t's.

  Example:
    > think decompose(This is \[a [ansi(y,test)]\][space(3)])
    This is \[a%b[ansi(y,test)]\] %b%b

See also: @decompile2, escape(), secure(), ]
& DEFAULT()
  default([<obj>/]<attr>[, ... ,[<objN>]/<attrN>], <default>)

  This function returns the value of the first possible <obj>/<attr>, as if retrieved via the get() function, if the attribute exists and is readable by you. Otherwise, it evaluates <default>, and returns that. Note that <default> is only evaluated if none of the given attributes exist or can be read. Note further than an empty attribute counts as an existing attribute.

  This is useful for code that needs to return the value of an attribute, or an error message or default case, if that attribute does not exist.

  Examples:
    > &TEST me=apple orange banana
    > say default(me/Test, No fruits!)
    You say "apple orange banana"

    > &TEST ME
    > say default(me/Test, No fruits!)
    You say "No fruits!"

See also: get(), hasattr(), ufun(), edefault(), udefault(), uldefault(), strfirstof()
& STRDELETE()
& DELETE()
  strdelete(<string>, <first>, <len>)

  Return a modified <string>, with <len> characters starting after the character at position <first> deleted. In other words, it copies <first> characters, skips <len> characters, and then copies the remainder of the string. If <len> is negative, deletes characters leftwards from <first>. Characters are numbered starting at 0.

  Examples:
    > say strdelete(abcdefgh, 3, 2)
    You say, "abcfgh"

    > say strdelete(abcdefgh, 3, -2)
    You say, "abefgh"

  delete() is an alias for strdelete(), for backwards compatability.

See also: strreplace(), strinsert(), mid(), ldelete()
& DIE()
  die(<number of times to roll die>, <number of sides on die>[, <show>])

  This function simulates rolling dice. It "rolls" a die with a given number of sides, a certain number of times, and adds the results. For example, DIE(2, 6) would roll "2d6" - two six-sided dice, generating a result in the range 2-12. The maximum number of dice this function will roll in a single call is 700. If <show> is true, the result will be a space-seperated list of the individual rolls rather than their sum.

  Examples:
    > think die(3, 6)
    6
    > think die(3, 6, 1)
    5 2 1
See also: rand()
& DIG()
  dig(<name>[, <exit to>[, <exit from>[, <room dbref>, <to dbref>, <from dbref>]]])

  This function digs a room called <name>, and optionally opens and links <exit to> and <exit from>, like the normal @dig command. It returns the dbref number of the new room.

  Wizards and objects with the pick_dbref power can supply optional fourth through sixth arguments to specify garbage objects to use for the new room and exits.

See also: @dig, open(), @open, create(), pcreate()
& DIGEST()
& MD5
& SHA1
& CHECKSUM
& HASH
  digest(list)
  digest(<algorithm>, <string>)

  Returns a checksum (hash, digest, etc.) of <string> using the given <algorithm>. The result is a unique large number represented in base 16.

  Typically at least the following algorithms are supported:

  md4 md5 ripemd160 sha1 sha224 sha256 sha384 sha512 whirlpool

  Depending on the host's OpenSSL version and how it was configured, there might be more (or less) available. digest(list) returns the methods a particular server understands if the OpenSSL library version being used is recent enough (1.0.0 and higher), or '#-1 LISTING NOT SUPPORTED' on older versions. For portable code, stick with MD5 and the SHA family.

  digest(sha, whatever) is equivalent to sha0(whatever).

  Example:
   > think iter(digest(list), %i0(foo) => [digest(%i0, foo)], %b, %r)
   ...
   MD4(foo) => 0ac6700c491d70fb8650940b1ca1e4b2
   MD5(foo) => acbd18db4cc2f85cedef654fccc4a4d8
   MDC2(foo) => 5da2a8f36bf237c84fddf81b67bd0afc
   RIPEMD160(foo) => 42cfa211018ea492fdee45ac637b7972a0ad6873
   SHA(foo) => 752678a483e77799a3651face01d064f9ca86779
   SHA1(foo) => 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
   SHA224(foo) => 0808f64e60d58979fcb676c96ec938270dea42445aeefcd3a4e6f8db
   ...

See also: encode64(), encrypt()
& DIST2D()
  dist2d(<x1>, <y1>, <x2>, <y2>)

  Returns the distance between two points in the Cartesian plane that have coordinates (<x1>, <y1>) and (<x2>, <y2>).

See also: dist3d(), lmath()
& DIST3D()
  dist3d(<x1>, <y1>, <z1>, <x2>, <y2>, <z2>)

  Returns the distance between two points in space, with coordinates (<x1>, <y1>, <z1>) and (<x2>, <y2>, <z2>).

See also: dist2d(), lmath()
& DIV()
& FLOORDIV()
& FDIV()
  div(<number1>, <number2>[, ... , <numberN>])
  fdiv(<number1>, <number2>[, ... , <numberN>])
  floordiv(<number1>, <number2>[, ... , <numberN>])

  These functions divide <number1> by <number2> (and, for each subsequent argument, divide the previous result by <numberN>) and return the final result.

  div() returns the integer part of the quotient. floordiv() returns the largest integer less than or equal to the quotient; for positive numbers, they are identical, but for negative numbers they may differ. fdiv() returns the floating-point quotient.

  Examples:

   div(13,4)          ==>   3      and     floordiv(13,4)     ==>   3
   div(-13,4)         ==>  -3      but     floordiv(-13,4)    ==>  -4
   div(13,-4)         ==>  -3      but     floordiv(13,-4)    ==>  -4
   div(-13,-4)        ==>   3      and     floordiv(-13,-4)   ==>   3

   fdiv(13,4)         ==>  3.25            fdiv(-13,4)        ==> -3.25
   fdiv(13,-4)        ==>  -3.25           fdiv(-13,-4)       ==>  3.25

  Note that add(mul(div(%0,%1),%1),remainder(%0,%1)) always yields %0, and add(mul(floordiv(%0,%1),%1),modulo(%0,%1)) also always yields %0.

See also: modulo(), lmath()
& DOING()
  doing(<player|descriptor>)

  When given the name of a player or descriptor, doing() returns the player's @doing. If no matching player or descriptor is found, or the descriptor is not yet connected to a player, an empty string is returned.

See also: @poll, @doing, poll()
& E()
& EXP()
  e([<number>])

  With no argument, returns the value of "e" (2.71828182845904523536, rounded to the game's float_precision setting).

  If a <number> is given, it returns e to the power of <number>.

  exp() is an alias for e().
See also: power(), log()
& EDEFAULT()
  edefault([<obj>/]<attr>, <default case>)

  This function returns the evaluated value of <obj>/<attr>, as if retrieved via the get_eval() function, if the attribute exists and is readable by you. Otherwise, it evaluates <default case>, and returns that. <default case> is only evaluated if the attribute does not exist or cannot be read.

  Example:
    > &TEST me=You have lost [rand(10)] marbles.
    > say edefault(me/Test,You have no marbles.)
    You say "You have lost 6 marbles."

    > &TEST me
    > say edefault(me/Test,You have no marbles.)
    You say "You have no marbles."

See also: get(), eval(), ufun(), default(), udefault(), hasattr()
& EDIT()
  edit(<string>, <search>, <replace>[, ... , <searchN>, <replaceN>])

  For each given <search> and <replace> pair, edit() replaces all occurrences of <search> in <string> with the corresponding <replace>.

  If <search> is a caret (^), <replace> is prepended.
  If <search> is a dollar sign ($), <replace> is appended.
  If <search> is an empty string, <replace> is inserted between every character, and before the first and after the last.
  If <replace> is an empty string, <search> is deleted from the string.

  Example:
    > say edit(this is a test,^,I think%b,$,.,a test,an exam)
    You say "I think this is an exam."

  edit() can not replace a literal single ^ or $. Use regedit() for that.

See also: @edit, regedit()
& ELEMENTS()
  elements(<list of words>, <list of numbers>[, <delim>[, <osep>]])

  This function returns the words in <list of words> that are in the positions specified by <list of numbers>. The <list of words> are assumed to be space-separated, unless a <delim> is given. If <osep> is given, the matching words are separated by <osep>, otherwise by <delim>.

  If any of the <list of numbers> is negative, it counts backwards from the end of the list of words, with -1 being the last word, -2 the word before last, and so on.

  Examples:
    > say elements(Foo Ack Beep Moo Zot,2 4)
    You say "Ack Moo"

    > say elements(Foof|Ack|Beep|Moo,3 1,|)
    You say "Beep|Foof"

    > say elements(The last word is foo, -1)
    You say "foo"

See also: extract(), index(), grab()
& ELOCK()
  elock(<object>[/<locktype>], <victim>)

  elock() returns 1 if the <victim> would pass the @lock/<locktype> on <object>, and 0 if it would fail. Any locktype can be given, including user-defined "user:" @locks. If no <locktype> is given, it defaults to the Basic lock.

  You must be able to examine the lock, which means either that you must control <object>, it must be @set VISUAL, or the <locktype> lock must be @lset VISUAL.

  Examples:
    > @lock/drop Dancing Slippers=#0
    > think elock(Dancing Slippers/drop, Princess)
    0

    > @lock/user:test map==*Fred|=*George
    > think elock(map/test,*Snape)
    0

See also: @lock, locktypes, testlock(), lockfilter(), @lset
& EMIT()
& NSEMIT()
  emit(<message>)
  nsemit(<message>)

  Sends a message to the room, as per @emit.

  nsemit() works like @nsemit.

See also: pemit(), remit(), lemit(), oemit(), zemit()
& ENCODE64()
& DECODE64()
& base64
  encode64(<string>)
  decode64(<string>)

  encode64() returns <string> encoded using base-64 format.

  decode64() converts a base-64 encoded <string> back to its original form.

See also: encrypt(), digest()
& ENCRYPT()
& DECRYPT()
  encrypt(<string>, <password>[, <encode>])
  decrypt(<string>, <password>[, <encoded>])

  encrypt() returns an encrypted string produced by a simple password-based encrypted algorithm. Good passwords are long passwords. This is not high-security encryption.

  If the optional <encode> argument is true, the resulting string is further encoded in base-64 so that it only contains alphanumeric characters.

  decrypt() decrypts a string encrypted with encrypt(). The <encoded> argument indicates that the encrypted string was base-64 encoded.

See also: encode64(), digest()
& ENTRANCES()
  entrances([<object>[, <type>[, <begin>[, <end>]]]])

  With no arguments, the entrances() function returns a list of all exits, things, players, and rooms linked to your location, like @entrances. You can specify an object other than your current location with <object>. You can limit the type of objects found by specifying one or more of the following for <type>:
        a        all (default)
        e        exits
        t        things
        p        players
        r        rooms

  You can also limit the range of the dbrefs searched by giving <begin> and <end>. If you control <object>, or have the Search or See_All powers, all objects linked to <object> are returned. Otherwise, only objects you can examine will be included.

See also: lsearch(), @entrances
& EQ()
  eq(<number1>, <number2>[, ... , <numberN>])

  Takes two or more <number>s, and returns 1 if they are all equal, and 0 otherwise.

See also: neq(), lmath()
& ESCAPE()
  escape(<string>)

  The escape() function "escapes out" potentially "dangerous" characters, preventing function evaluation in the next pass of the parser. It returns <string> after adding the escape character ('\') at the beginning of the string, and before the following characters:

  %  ;  [  ]  {  }  \ ( ) , ^ $

  This function prevents code injection in strings entered by players. It is only needed when <string> will be passed through a command or function which will evaluate it again, which can usually be avoided. Since the function preserves the original string, it is, in most cases, a better choice than secure(), but decompose() is often better still.

See also: decompose(), secure(), ]
& EVAL()
& GET_EVAL()
  eval(<object>, <attribute>)
  get_eval(<object>/<attribute>)

  eval() and get_eval() are similar to ufun(), in that they evaluate the given <attribute> on <object>. However, they change the enactor (%#) to the object executing the eval (%!). It does not modify the stack (%0-%9), so the attribute being evaled sees the same values for them that the calling code does. Unless you need this behavior, it is better to use u() instead, which hides the caller's stack.

  Example:
    > &TEST Foo=%b%b%b-[name(me)] (%n)
    > &CMD Foo=$test: @emit ufun(me/test) ; @emit eval(me, test)
    > test
       -Foo (Mike)
       -Foo (Foo)

See also: get(), u(), xget(), edefault()
& EXIT()
  exit(<object>)

  Returns the dbref of the first exit in room <object>.

  You can get the complete exit list of any room you may examine, regardless of whether or not exits are dark. You can get the partial exit list (obeying DARK/LIGHT/etc.) of your current location or the enactor (%#). You CANNOT get the exit list of anything else, regardless of whether or not you have objects in it.

See also: lexits(), next()
& EXTRACT()
  extract(<list>[, <first>[, <length>[, <delimiter>]]])

  This function returns <length> elements of <list>, counting from the <first>th element. If <length> is not specified, the default is 1, so extract(<list>,3) acts like elements(<list>,3). If <first> is not specified, the default is the 1, so extract(<list>) acts like first(<list>).

  If <first> is negative, extract() will begin counting backwards from the end of <list>, so -1 starts at the last element, -2 the element before last, and so on.

  If <length> is negative, extract() will return up to and including the <length>th element from the right, so -1 will extract up to the last element, -2 up to the element before last, and so on.

  Examples:
    > think extract(This is a test string,3,2)
    a test

    > think extract(Skip the first and last elements, 2, -2)
    the first and last

    > think extract(Get just the last three elements,-3, 3)
    last three elements

See also: index(), elements(), grab()
& FILTER()
& FILTERBOOL()
  filter([<obj>/]<attr>, <list>[, <delimiter>[, <osep>[, ..., <argN>]]])
  filterbool([<obj>]/<attr>, <list>[, <delimiter>[, <osep>[, ..., <argN>]]])

  These functions returns the elements of <list> for which a user-defined function evaluates to "1" (for filter()), or to a boolean true value (for filterbool()). That function is specified by the first argument (just as with the ufun() function), and the element of the list being tested is passed to that user-defined function as %0. Up to 29 further <arg>s can be specified, and will be available in the function as v(1) to v(30).

  <delimiter> defaults to a space, and <osep> defaults to <delimiter>.

  filter(<obj>/<attr>, <list>) is roughly equivalent to squish(iter(<list>, switch(ufun(<obj>/<attr>, %i0),1,%i0,))) though the filter() version is much more efficient.

  Example:
    > &IS_ODD test=mod(%0,2)
    > say filter(test/is_odd, 1 2 3 4 5 6)
    You say, "1 3 5"

See also: anonymous attributes, firstof(), allof(), lockfilter(), boolean values
& FINDABLE()
  findable(<object>, <victim>)

  This function returns 1 if <object> can locate <victim>, or 0 if it cannot. If one of the objects does not exist, it will return #-1 ARGN NOT FOUND (where N is the argument which is the invalid object).

  The object executing the function needs to be see_all or control both <object> and <victim>.

See also: locate(), loc()
& FIRST()
  first(<list>[, <delimiter>])

  Returns the first element of a list.

See also: before(), rest(), last(), firstof(), strfirstof()
& FIRSTOF()
  firstof(<expr>[, ... , <exprN>], <default>)

  Returns the first evaluated <expr> that is true. If no <expr> arguments are true, <default> is returned.

  The meaning of true or false is dependent on configuration options as explained in the 'BOOLEAN VALUES' help topics.

  This function evaluates arguments one at a time, stopping as soon as one is true.

  Examples:
    > say firstof(0,2)
    You say, "2"

    > say firstof(10,11,0)
    You say, "10"

    > say firstof(grab(the cat,mommy),grab(in the hat,daddy),#-1 Error)
    You say, "#-1 Error"

    > say firstof(get(%#/royal cheese),#-1 This Has No Meaning,0,)
    You say, ""

See also: allof(), BOOLEAN VALUES, strfirstof(), filter()
& FLAGS()
  flags()
  flags([<object>[/<attribute>]])

  With no arguments, flags() returns a string consisting of the flag letters for each flag on the MUSH. Note that some flags have no letter, and mutlple flags may have the same letter (and so will appear multiple times).

  If an <object> is given, flags() returns 'P', 'T', 'R' or 'E', depending on whether <object> is a player, thing, room, or exit, followed by the flag letter for each flag set on <object>.

  With an <object>/<attribute>, the flag letters for each flag set on the given <attribute> are returned.

  Examples:
    > @create Test
    > @set Test=no_command puppet
    > think flags(Test)
    Tnp

    > think flags(me/describe)
    $vp

See also: lflags(), list()
& LFLAGS()
  lflags()
  lflags(<object>[/<attribute>])

  With an argument, lflags() returns a space-separated list consisting of the names of all the flags attached to <object>, or <object>'s <attribute>.

  Given no arguments, this function returns a space-separated list of all flag names known to the server, as per @list/flags.

  Examples:
    > @create Test
    > @set Test=no_command puppet
    > think flags(Test)
    NO_COMMAND PUPPET

    > think flags(me/describe)
    NO_COMMAND VISUAL

See also: flags(), list()
& FLIP()
& REVERSE()
  flip(<string>)

  flip() reverses a string. reverse() is an alias for flip().

  Example:
    > say flip(foo bar baz)
    You say, "zab rab oof"

See also: revwords()
& FMOD()
  fmod(<number>, <divisor>)

  Similar to remainder() but may take floating point arguments. The return value is <number> - n * <divisor>, where n is the quotient of <number> / <divisor>, rounded towards zero. The result has the same sign as <number> and a magnitude less than the magnitude of <divisor>.

  Example:
    > think fmod(6.1,2.5)
    1.1
See also: fdiv(), div(), mod(), lmath()
& FOLD()
  fold([<obj>/]<attr>, <list>[, <base case>[, <delimiter>]])

  This function "folds" a list through the user-defined function, set in the specified <obj>/<attribute>.

  If no <base case> is provided, fold() passes the first element of <list> as %0, and the second element of <list> as %1, to the user-defined function. The user-defined function is then called again, with the result of the first evaluation being %0, and the next (third) element of the list as %1. This is repeated until all the elements of the list have been used. The result of the last call of <obj>/<attr> is returned.

  If a base case is provided, it is passed as %0, and the first element of list is passed as %1, to the user-defined function. The process for the no-base-case fold() is then used.

  The number of times <attr> has been called is passed as %2, starting from 0.

  Note that it's not possible to pass a <delimiter> to fold without also giving a <base case>; see the examples for a way around this.

  See 'help fold2' for examples.
& FOLD2

  Examples:
    > &REP_NUM test=%0[repeat(%1,%1)]
    > say fold(test/rep_num,1 2 3 4 5)
    You say, "122333444455555"
    > say fold(test/rep_num,1 2 3 4 5,List:)
    You say, "List:122333444455555"

    > &ADD_NUMS test=add(%0,%1)
    > say fold(test/add_nums,1 2 3 4 5)
    You say, "15"

  If your list uses a delimiter, you need to give a <base case>. This can be a problem for dynamically generated lists. One solution is to use a register and pop the first element off the list. For example:
   > &GEN_LIST test=lnum(1,rand(5,10),|)
   > &ADD_NUMS test=add(%0,%1)
   > say letq(fl, u(gen_list), fold(test/add_nums, rest(%q<fl>,|), first(%q<fl>,|), |))
   You say, "36"

See also: anonymous attributes
& FOLLOWERS()
  followers(<object>)

  Returns the list of things and players following object. You must control <object>.

See also: following(), follow, unfollow
& FOLLOWING()
  following(<object>)

  Returns the list of things and players that the object is following. You must control <object>.

See also: followers(), follow, unfollow
& FOREACH()
  foreach([<object>/]<attribute>, <string>[, <start>[, <end>]])

  This function is similar to map(), but instead of calling the given <object>/<attribute> for each word in a list, it is called for each character in <string>.

  For each character in <string>, <object>/<attribute> is called, with the character passed as %0, and its position in the string as %1 (the first character has position 0). The results are concatenated.

  If <start> is given, everything before the first occurrence of <start> is copied as-is, without being passed to the <object>/<attribute>. If <end> is given, everything after the first occurrence of <end> is copied as-is. The <start> and <end> characters themselves are not copied.

  See 'help foreach2' for examples.
& FOREACH2

  Examples:
    > &add_one me=add(%0,1)
    > say foreach(add_one, 54321)
    You say, "65432"
    > say [foreach(add_one, This is #0# number, #, #)]
    You say, "This is 1 number"

    > &upper me=ucstr(%0)
    > say foreach(upper, quiet quiet >shout< quiet, >, <)
    You say, "quiet quiet SHOUT quiet"

    > &is_alphanum me=regmatch(%0, \[\[:alnum:\]\])%b
    > say foreach(is_alphanum,jt1o+)
    You say, "1 1 1 1 0 "

See also: map(), anonymous attributes
& FRACTION()
  fraction(<number>[, <whole>])

  This function returns a fraction representing the floating-point <number>. Since not all numbers can be expressed as a fraction, dividing the numerator by the denominator of the results will not always return the original <number>, but something close to it.

  If <whole> is true, and <number> is greater than 1.0 (or less than -1.0), the return value will be a whole number followed by the fraction representation of the decimal.

  Examples:
    > think fraction(.75)
    3/4

    > think fraction(pi())
    348987/111086

    > think fraction(2)
    2

    > think fraction(2.75)
    11/4

    > think fraction(2.75, 1)
    2 3/4
& FULLNAME()
  fullname(<object>)

  fullname() returns the full name of object <object>. It is identical to name() except that for exits, fullname() returns the complete exit name, including all aliases.

  Example:
    > say fullname(south)
    You say, "South;sout;sou;so;s"

See also: name(), accname(), iname(), alias(), fullalias()
& FUNCTIONS()
  functions([<type>])

  Returns a space-separated list of the names of functions. If <type> is "local", only @functions are listed. If "builtin", only builtin functions. If "all" or omitted, both are returned.

See also: list(), config()
& GET()
& XGET()
  get(<object>/<attribute>)
  xget(<object>, <attribute>)

  These functions return the string stored in an <object>'s <attribute> attribute, without evaluating it. You must be able to examine the attribute. get() and xget() are identical, apart from the argument separator.

    Example:
      > &test me=This is [a test].
      > think get(me/test)
      This is [a test].

See also: hasattr(), visible(), ufun(), default(), udefault()
& GETPIDS()
  getpids(<object>[/<attribute>])

  Returns a space-separated list of semaphore queue process ids waiting on the given <object> and semaphore <attribute>. If <attribute> is not given, pids for all semaphores on the object are returned.

See also: @ps, @wait, lpids(), pidinfo(), SEMAPHORES
& GRAB()
& REGRAB()
& REGRABI()
  grab(<list>, <pattern>[, <delimiter>])
  regrab(<list>, <regexp>[, <delimiter>])
  regrabi(<list>, <regexp>[, <delimiter>])

  These functions return the first word in <list> which matches the pattern. For grab(), <pattern> is a wildcard pattern ('help wildcards'). For regrab() and regrabi(), the pattern is a regular expression. regrabi() is case-insensitive. <delimiter> defaults to a space.

  Basically, this is a much more efficient way to do:
    elements(<list>, match(<list>, <pattern>[, <delimiter>])[, <delimiter>])
  or the regular expression variation thereof.

See also: graball(), match(), extract(), elements(), regmatch()
& GRABALL()
& REGRABALL()
& REGRABALLI()
  graball(<list>, <pattern>[, <delim>[, <osep>]])
  regraball(<list>, <regexp>[, <delim>[, <osep>]])
  regraballi(<list>, <regexp>[, <delim>[, <osep>]])

  These functions work identically to the grab() and regrab()/regrabi() functions, except they return all matches, not just the first: They return all words in the <list> which match <pattern>. If none match, an empty string is returned. <delim> defaults to a space, and <osep> defaults to <delim>.

  Examples:
    > say graball(This is a test of a test,test)
    You say "test test"
    > say graball(This|is|testing|a|test,tes*,|)
    You say "testing|test"
    > say regraball(This is testing a test,s$)
    You say "This is"

See also: match(), matchall(), grab(), regmatch()
& GREP()
& REGREP()
& WILDGREP()
& GREPI()
& REGREPI()
& WILDGREPI()
& PGREP()
  grep(<object>, <attrs>, <substring>)
  wildgrep(<object>, <attrs>, <pattern>)
  regrep(<object>, <attrs>, <regexp>)
  grepi(<object>, <attrs>, <substring>)
  regrepi(<object>, <attrs>, <regexp>)
  wildgrepi(<object>, <attrs>, <pattern>)
  pgrep(<object>, <attrs>, <substring>)

  These functions return a list of attributes on <object> containing <substring>, matching the wildcard <pattern>, or matching the regular expression <regexp>. <attrs> is a wildcard pattern for attribute names to search.

  Parsing _does_ occur before this function is invoked. Therefore, "special" characters will need to be escaped out.

  grep()/wildgrep()/regrep() are case-sensitive.
  grepi()/wildgrepi()/regrepi() are case-insensitive.

  pgrep() works like grep(), but also checks attributes inherited from parents.

See also: @grep, lattr(), WILDCARDS
& GT()
  gt(<number1>, <number2>[, ... , <numberN>])

  Takes two or more numbers, and returns 1 if and only if each number is greater than the number after it, and 0 otherwise.

See also: gte(), lt(), lte(), eq(), neq(), lmath()
& GTE()
  gte(<number1>, <number2>[, ... , <numberN>])

  Takes two or more numbers, and returns 1 if and only if each number is greater than or equal to the number after it, and 0 otherwise.

See also: gt(), lt(), lte(), eq(), neq(), lmath()
& HASATTR()
& HASATTRP()
& HASATTRVAL()
& HASATTRPVAL()
  hasattr(<object>, <attribute>)
  hasattrp(<object>, <attribute>)
  hasattrval(<object>, <attribute>)
  hasattrpval(<object>, <attribute>)

  The hasattr*() functions check to see if <object> has a given attribute. They return #-1 if the object does not exist or the attribute can't be examined by the player. Otherwise, they return 1 if the attribute is present and 0 if it is not.

  hasattr() checks to see if <attribute> exists on <object> only.

  hasattrp() also checks for <attribute> on <object>'s parent/ancestor.

  hasattrval() only returns 1 if <attribute> exists and is non-empty. An "empty" attr is one containing a null value (if the empty_attrs config option is on), or one containing a single space (if the option is off).

  hasattrpval() is like hasattrval() but also checks parents.

  All four functions will also work with one argument in the form of <object>/<attribute>.

See also: visible(), lattr()
& HASFLAG()
  hasflag(<object>[/<attrib>], <flag>)

  With no <attrib>, hasflag() returns 1 if <object> has the <flag> flag set. If <attrib> is specified, the attribute is checked for the <flag> attribute flag instead. If the flag is not present, 0 is returned.

  hasflag() will accept a full flag name ("Wizard") or a flag letter ("W"). You can check the flags of any object, whether you control them or not.

  Example:
    > think hasflag(me, wizard)
    1

See also: orlflags(), andlflags(), orflags(), andflags(), flags(), lflags(), attribute flags, @flag, haspower(), hastype()
& HASPOWER()
  haspower(<object>, <power>)

  Returns 1 if <object> has the named power, and 0 if it does not.

  You can check the powers of any object, whether you control it or not.

See also: @power, powers list, hasflag()
& HASTYPE()
  hastype(<object>, <type list>)

  Returns 1 if <object> belongs to one of the types given in <type list>, and 0 otherwise. Valid types are PLAYER, THING, ROOM, EXIT and GARBAGE.

  Example:
    > @create Test Object
    > think hastype(test object, PLAYER EXIT)
    0
    > think hastype(test object, PLAYER THING)
    1

See also: TYPES, type()
& HIDDEN()
  hidden(<player|descriptor>)

  If you can see hidden players, this function returns 1 if <player> (or the player connected to <descriptor>) is hidden, and 0 otherwise. If you cannot see hidden players, hidden() returns #-1.

See also: @hide
& HOME()
  home(<object>)

  Returns the object's 'home', where it is @link'd to. This is the home for a player or thing, the drop-to of a room, or source of an exit.

See also: @link
& HOST()
& HOSTNAME()
  host(<player|descriptor>)

  Returns the hostname a player is connected from, as shown on the wizard WHO. This may be more reliable that get(<player>/lastsite) if the player has multple connections from different locations, and the function is called with a descriptor argument.

  The caller can use the function on himself, but using on any other player requires privileged power such as Wizard, Royalty or SEE_ALL.

  hostname() is an alias for host().

See also: Connection Functions, ipaddr(), ports(), lports()
& IDLE()
& IDLESECS()
  idle(<player|descriptor>)

  This function returns the number of seconds a player has been idle, much as WHO does. <player name> must be the full name of a player, or a player's dbref. You can also specify a <descriptor>, useful if a player is connected multiple times, or for connections which are still at the login screen. Players who are not connected have an idle time of "-1", as do dark wizards, when idle() is used on them by a non-priv'ed player.

  idlesecs() is an alias for idle().

See also: Connection Functions, conn()
& IF()
& IFELSE()
  if(<condition>, <true expression>[, <false expression>])
  ifelse(<condition>, <true expression>, <false expression>)

  These functions evaluate the <condition> and return <true expression> if the <condition> is true, or <false expression> (if provided) if the <condition> is false. Only the returned <expression> is evaluated.

See also: BOOLEAN VALUES, switch(), @if, @break, cond()
& INAME()
  iname(<object>)

  iname() returns the name of <object>, as it would appear if you were inside it. It is identical to name() except that if the object has a NAMEFORMAT or NAMEACCENT attribute, it is used.

  You must be see_all, control <object>, or be inside it to use this function.

See also: @nameformat, @nameaccent, name(), fullname(), accname()
& INC()
  inc(<integer>)
  inc(<string-ending-in-integer>)

  inc() returns the integer plus 1. If given a string that ends in an integer, it increments only the final integer portion. That is:

  Examples:
    > think inc(3)
    4

    > think inc(hi3)
    hi4

    > think inc(1.3.3)
    1.3.4

  Note especially the last example, which will trip you up if you use floating point numbers with inc() and expect it to work like add().

  If the null_eq_zero @config option is on, using inc() on a string which does not end in an integer will return <string>1. When null_eq_zero is turned off, it will return an error.

See also: dec(), add(), sub()
& INDEX()
  index(<list>, <character>, <first>, <length>)

  This function is similar to extract(), except that it requires four arguments, while extract() uses defaults for its arguments if they aren't given. The function returns <length> items starting from the <first> position. Trailing spaces are trimmed.

  Examples:
    > say index(Cup of Tea | Mug of Beer | Glass of Wine, |, 2, 1)
    You say, "Mug of Beer"

    > say index(%rtoy boat^%rblue tribble^%rcute doll^%rred ball,^,2,2)
    You say, "
    blue tribble^
    cute doll"

See also: extract(), elements(), grab()
& INSERT()
& LINSERT()
  linsert(<list>, <position>, <new item>[, <delim>])

  If <position> is a positive integer, this inserts <new item> BEFORE the item at <position> from the left in <list>. That means that <new item> then becomes the <position>th element of <list>.

  If <position> is a negative integer, this inserts <new item> AFTER the item at the absolute value of <position> from the RIGHT in <list>. This is the same as reversing the list before inserting <new item>, and then reversing it again into correct order. For example, when <position> is -1, <new item> will be the last in the list; when <position> is -2, <new item> will be the second item from the right, and so on.

  If a <delim> is not given, a space is assumed. Null items are counted when determining position, as in 'items()'.

  Examples:
    > say linsert(This is a string,4,test)
    You say, "This is a test string"
    > say linsert(one|three|four,2,two,|)
    You say, "one|two|three|four"
    > say linsert(meep bleep gleep,-3,GOOP)
    You say, "meep GOOP bleep gleep"

  insert() is an alias for linsert(), for backwards compatability.

See also: lreplace(), ldelete(), strinsert()
& ISDAYLIGHT()
  isdaylight([<secs>[, <timezone>]])

  Returns 1 if it's daylight savings in the specified timezone at the given time. Defaults to the host server's time zone and current time if not specified.

See also: timezones, secs()
& ISDBREF()
& ISOBJID()
  isdbref(<string>)
  isobjid(<string>)

  isobjid() returns 1 if <string> is the object id of an existing object. If <string> is not a full objid, or is the objid of a garbage object, it returns 0.

  isdbref() functions the same, but will also return 1 if <string> is the dbref of an existing (or garbage) object.

  Examples:
    > @stats
    100 objects = 20 rooms, 20 exits, 20 things, 20 players, 20 garbage.
    The next object to be created will be #33.

    > think isdbref(#33)
    1
    > think isobjid(#33:1234567890)
    0

    > think csecs(#1)
    1324654503
    > think isdbref(#1)
    1
    > think isobjid(#)
    0
    > think isdbref(#1:1324654503)
    1
    > think isobjid(#1:1324654503)
    1
    > think isobjid(#1:9876543210)
    0

See also: DBREFS, OBJECT IDS, num(), objid()
& ISINT()
  isint(<string>)

  Returns 1 if its argument is an integer, and 0 otherwise. Integers can begin with a '+' or '-' sign, but the rest of the string must be digits.

See also: isnum()
& ISNUM()
  isnum(<string>)

  This function returns 1 if <string> is a number, and 0 if it is not. Numbers can begin with a '-' sign (for negatives), but the rest of the characters in the string must be digits, and an optional decimal point.

See also: isint()
& ISREGEXP()
  isregexp(<string>)

  This function returns 1 if <string> is a valid regular expression, and 0 if it is not.

See also: REGEXP
& ISWORD()
  isword(<string>)

  This function returns 1 if every character in <string> is a letter, or 0, if any character isn't a letter. Case does not matter.

& ITEMS()
  items(<list>, <delim>)

  items() counts the number of items in a list using an arbitrary <delim>. Null items are counted, so:

        items(X|X,|)     => 2     (2 X items)
        items(X||X,|)    => 3     (2 X items and 1 null item)
        items(X X,%b)    => 2     (2 X items)
        items(X%b%bX,%b) => 3     (2 X items and 1 null item)
        items(,|)        => 1     (a single null item)

   Another way to think about this is that items() counts the number of times <delim> appears in <list>, and adds 1.

See also: words()
& ITEMIZE()
& ELIST()
  itemize(<list>[, <delim>[, <conjunction>[, <punctuation>]]])
  elist(<list>[, <conjunction>[, <delim>[, <osep>[, <punctuation>]]]])

  These functions take the elements of <list> (separated by <delim> or a space by default), and:
   If there's just one, return it.
   If there's two, return <e1> <conjunction> <e2>
   If there's more than two, return <e1><punc> <e2><punc> ... <conj> <en>

  elist() uses <osep> after <punc>/<conj> instead of a space.
  The default <conjunction> is "and", default punctuation is ",".
  Examples:
    > say itemize(eggs) * [itemize(eggs bacon)]
    You say, "eggs * eggs and bacon"
    > say itemize(eggs bacon spam)
    You say, "eggs, bacon, and spam"
    > say itemize(eggs bacon spam, ,&,;)
    You say, "eggs; bacon; & spam"
& ITER()
& PARSE()
  iter(<list>, <pattern>[, <delimiter>[, <output separator>]])

  For each word in <list>, iter() evaluates <pattern> once, and returns a list of the results of those evaluations. Words in <list> are separated by <delimiter>, if given, and spaces if not. Words in the resulting list are separated by the given <ouput separator>, or a space if no output separator is given.

  Prior to each evaluation, every occurrence of the string "##" in <pattern> is replaced with the current word from <list>. However, because this replacement occurs before evaluation, it cannot be used well in nested iter()s, and should not be used on user input or untrusted <list>s, as the word will be evaluated. Instead, you can use the %iX substitution, or the itext() function. The substitution '%iL' refers to the outermost iter of the current expression, and is intended to replace ##.

  The string "#@" will be replaced with the position of the current word in <list>. Like "##", the replacement occurs before substitution. Use the inum() function for nested iter()s.

  If you nest iter()s, ## and #@ refer to the first/outermost iter(). The ilev() function can be used to get the current iter() nesting level.

  parse() is an alias for iter().

  See 'help iter2' for examples.
See also: itext(), inum(), ilev(), ibreak(), map(), @dolist
& ITER2
  Examples:
    > say iter(This is a test string., strlen(%i0))
    You say, "4 2 1 4 7"

    > say iter(lnum(5), mul(add(%i0,#@),2))
    You say, "2 6 10 14 18"

    > say iter(lexits(here), name(%i0) (owned by [name(owner(%i0))]))
    You say, "South (owned by Claudia) North (owned by Roy)"

    > &STRLEN_FN me=strlen(%0)
    > say iter(This is a test string., u(STRLEN_FN, %i0))
    You say, "4 2 1 4 7"

  Since this example just evaluates another attribute for each element of the list, it can be done more efficiently using map():
    > say map(strlen_fun, This is a test string.)

    > say iter(lnum(3), %i0, ,%r)
    You say, "0
    1
    2"

  An example of why using ## instead of %i0 can be insecure, and lead to unintended evaluation:
    > say iter((1\,1),add##)
    You say, "2"
    > say iter((1\,1),add%i0)
    You say, "add(1,1)"
& IBREAK()
  ibreak([<level>])

  The ibreak() function stops an iter() from running at the end of the current loop. When used in nested iter()s, you can give a <level> to specify how many iter()s to break from. iter() will stop evaluating at the end of the current loop, and NOT immediately after ibreak() is called.

  Examples:
    > say iter(1 2 3 4 5,switch(%i0,3,ibreak())Test %i0!)
    You say, "Test 1! Test 2! Test 3!"

    > say iter(1 2 3 4 5,switch(%i0,3,ibreak(),Test %i0!))
    You say, "Test 1! Test 2! "

    > say iter(a b c, iter(1 2 3, switch(%i0%i1, 2c, ibreak(2), %$0)))
    You say, "1a 2a 3a 1b 2b 3b 1c "

See also: iter(), itext(), inum(), ilev()
& ILEV()
& ITEXT()
& INUM()
& %i
& %i0
  ilev()
  itext(<n>)
  %i<n>
  inum(<n>)

  These functions return the equivilent of ## (itext) or #@ (inum) for iter() and @dolist, where an <n>=0 returns to the current iter or @dolist, <n>=1 refers to the iter()/@dolist which the current iter() or @dolist is nested in, etc. An <n> of "L" can be used to refer to the outermost iter()/@dolist. %i<n> is an alias for itext(<n>), where <n> can be from 0 to 9 (or "L").

  ilev() returns the current nesting depth, or -1 when used outside an iter() or @dolist. Thus, itext(ilev()) will return the outermost ##, equivilent to %iL.

  See 'help itext2' for examples.
See also: iter(), ibreak(), @dolist
& ITEXT2

  Examples:
    > say iter(red blue green, iter(fish shoe, #@:##))
    You say, "1:red 1:red 2:blue 2:blue 3:green 3:green"

    > say iter(red blue green, iter(fish shoe, inum(ilev()):[itext(1)]))
    You say, "1:red 1:red 2:blue 2:blue 3:green 3:green"

    > say iter(red blue green,iter(fish shoe, inum(0):[itext(0)]))
    You say, "1:fish 2:shoe 1:fish 2:shoe 1:fish 2:shoe"

    > say iter(red blue green,iter(fish shoe, %i1:%i0))
    You say, "red:fish red:shoe blue:fish blue:shoe green:fish green:shoe"

    > @dolist red blue green=say iter(fish shoe, %i1:%i0)
    You say, "red:fish red:shoe"
    You say, "blue:fish blue:shoe"
    You say, "green:fish green:shoe"

See also: iter(), @dolist
& IPADDR()
  ipaddr(<player|descriptor>)

  Returns the IP address of the connected player or descriptor. This may be more reliable than get(<player>/lastip) if the player has multple connections from different locations, and the function is called with a descriptor argument.

  The caller can use the function on himself, but using on any other player requires privileged power such as Wizard, Royalty or SEE_ALL.

See also: Connection Functions, hostname(), ports(), lports()
& LAST()
  last(<list>[, <delimiter>])

  Returns the last element of a list. Elements in <list> are separated by <delimiter>, if given, or by a space if not.

See also: first(), rest(), before(), after()
& LATTR()
& LATTRP()
& REGLATTR()
& REGLATTRP()
  lattr(<object>[/<attribute pattern>][, <output separator>])
  lattrp(<object>[/<attribute pattern>][, <output separator>])
  reglattr(<object>[/<regexp>][, <output separator>])
  reglattrp(<object>[/<regexp>][, <output separator>])

  lattr() returns a list of all the attributes on <object> which you can see, and which match the wildcard <attribute pattern>. If no <attribute pattern> is given, it defaults to "*". Note that this does not include branches in attribute trees; you must use the "**" wildcard to include those.

  The resulting list will be separated by <output separator>, or a space if no separator is given.

  reglattr() returns attributes whose names match the regexp <regexp>. The match is not case-sensitive (as attribute names are always upper-case), and the "`" branch separator has no special meaning in the pattern.

  lattrp() and reglattrp() also include attributes inherited from parents.

  When returning large numbers of attributes, the results may be truncated due to buffer limits. In these cases, you can use nattr() and xattr() to retrieve the results in smaller pieces.

See also: nattr(), xattr(), hasattr(), examine, grep(), wildcards
& NATTR()
& NATTRP()
& ATTRCNT()
& ATTRPCNT()
& REGNATTR()
& REGNATTRP()
  nattr(<object>[/<attribute pattern>])
  nattrp(<object>[/<attribute pattern>])
  regnattr(<object>[/<regexp>])
  regnattrp(<object>[/<regexp>])

  nattr() returns the number of attributes on <object> that you can see which match the given <attribute pattern>. It is considerably faster than words(lattr()) and doesn't suffer from buffer length constraints. It's designed primarily for statistical purposes. <attribute pattern> defaults to "*", which does not include branches in attribute trees; use "**" if you need to count attribute trees.

  regnattr() matches attribute names against the regular expression <regexp>.

  nattrp() and regnattrp() also count matching attributes on the parent.

  attrcnt() and attrpcnt() are aliases for nattr() and nattrp() respectively.

See also: lattr(), hasattr(), xattr(), wildcards
& LCON()
  lcon(<object>[, <type>])

  Returns a list of the dbrefs of objects which are located in <object>.

  You can get the complete contents of any object you may examine, regardless of whether or not objects are dark. You can get the partial contents (obeying DARK/LIGHT/etc.) of your current location or the enactor (%#). You CANNOT get the contents of anything else, regardless of whether or not you have objects in it.

  When used on exits, this function returns #-1.

  For compatability with other codebases, a <type> can be given to limit the results. Valid <type>s are:
    player             - equivalent to lplayers(<object>)
    connect            - equivalent to lvplayers(<object>)
    thing (or object)  - equivalent to lthings(<object>)
    listen             - return only listening objects
    puppet             - return only THINGs set PUPPET

See also: lexits(), lplayers(), lthings(), con(), next(), lvcon()
& LCSTR()
& LCSTR2()
  lcstr(<string>)
  lcstr2(<string>)

  Returns <string> with all letters converted to lowercase.

  If the MUSH is compiled with ICU Unicode support, lcstr2() does the same thing except the returned string might be a different length, and ansi colors and other markup are stripped.

  Example:
    > say lcstr(Foo BAR bAz)
    You say, "foo bar baz"

See also: capstr(), ucstr()
& LDELETE()
  ldelete(<list>, <position(s)>[, <delimiter>[, <osep>]])

  This function deletes the element(s) of <list> at the given <position(s)>. Elements of <list> are separated by <delimiter>, which defaults to a space. Null items are counted, as in 'items()'. Elements of <position(s)> must be numeric, and are always separated by a space, not by <delimiter>. Elements of the returned list are separated by <osep>, which defaults to the <delimiter>.

  If a <position> is negative, ldelete() counts backwards from the end of the list; a position of -1 deletes the last element, -2 the element before last, and so on.

  All position calculations are performed on the original list. That is, ldelete(a b c, -1 -1) will return "a b", not "a", and ldelete(a b c, -1 -2) returns "a", not "b".

  Examples:
    > say ldelete(This is a long test string,4)
    You say, "This is a test string"
    > say ldelete(lemon|orange|pear|apple,2 3,|)
    You say, "lemon|apple"
    > say ldelete(foo bar baz boing,3,,%b~%b)
    You say, "foo ~ bar ~ boing"

See also: strdelete(), remove(), linsert()
& LEFT()
  left(<string>, <length>)

  Returns the first <length> characters from <string>.

See also: right(), mid(), ljust()
& NSLEMIT()
& LEMIT()
  lemit(<message>)
  nslemit(<message>)

  lemit() emits a message in the caller's outermost room, as per @lemit.

  nslemit() like @nslemit.

See also: @lemit, remit()
& LETQ()
  letq([<reg1>, <value1>[, ... , <regN>, <valueN>], <expr>)

  letq() saves the current values of the given q-<reg>isters, sets them to new <value>s, evaluates <expr> and then restores the saved registers. It does not restore registers that are not listed. None of the values can see the updated contents of the registers -- they are only visible to <expr>.

  It returns the result of <expr>.

  Examples:
    > think setr(A, 1):[letq(A, 2, %qA)]:%qA
    1:2:1
    > think setr(A, 1)[setr(B,1)]:[letq(A, 2, %qA[setr(B,2)])]:%qA%qB
    11:22:12

See also: setq(), setr(), unsetq(), listq(), localize(), ulocal(), r()
& LEXITS()
  lexits(<room>)

  Returns a list of the dbrefs of exits in a room.

  You can get the complete exit list of any room you may examine, regardless of whether or not exits are dark. You can get the partial exit list (obeying DARK/LIGHT/etc.) of your current location or the enactor (%#). You CANNOT get the exit list of anything else, regardless of whether or not you have objects in it.

See also: lcon(), exit(), next(), lvexits()
& LJUST()
  ljust(<string>, <length>[, <fill>[, <truncate?>]])

  This function returns <string>, padded with the string <fill> until it's <length> characters long. <fill> can be more than one character in length, and defaults to a single space.

  If <string> is longer than <length>, it will be returned unaltered, unless <truncate?> is true, in which case only the first <length> characters of <string> are returned.

  Examples:
    > say ljust(foo,6)
    You say, "foo   "

    > say %r0[ljust(foo,6,-)]7%r01234567
    You say, "
    0foo---7
    01234567"

    > say ljust(foo,12,=+)
    You say, "foo=+=+=+=+="

    > say ljust(This is too long, 9)
    You say, "This is t"

See also: align(), center(), rjust(), left()
& LINK()
  link(<object>, <destination>[, <preserve>])

  This function links <object> to <destination>. While normally used on exits, it has all of the other capabilities of @link as well. It returns #-1 or 0 on failure, 1 on success. If the optional third argument is true, acts like @link/preserve.

See also: @link, open()
& LIST()
  list(<option>[, <type>])

  This is the function-equivilent of the @list command, and lists some useful information about the MUSH. <option> can be one of:

  motd        : Returns the current @motd
  wizmotd     : Returns the current @motd/wizard. Wiz/Roy only.
  downmotd    : Returns the current @motd/down. Wiz/Roy only.
  fullmotd    : Returns the current @motd/full. Wiz/Roy only.
  functions   : Returns a list of all built-in functions and @functions.
  commands    : Returns a list of all built-in commands and @commands.
  attribs     : Returns all standard attributes.
  locks       : Returns the built-in lock types. Similar to llocks().
  flags       : Returns all flags. Similar to lflags().
  powers      : Returns all @powers.

  "commands"/"functions" return both built-in and local commands/functions by default. You can specify a <type> of either "builtin", "local" or "all" to limit this if you wish.

See also: @list, flags(), lflags(), config(), functions(), @listmotd, @motd,
  llocks()
& LIT()
  lit(<string>)

  This function returns <string> literally - without even squishing spaces, and without evaluating *anything*. This can be useful for writing ASCII maps with spaces or whatever.

  It can be a bit tricky to get a literal string with spaces into an attrib, however, since spaces are usually squished in setting an attribute. This example illustrates how to make it work:

    > @va me=$test: think {[lit(near       far)]}
    Set.
    > ex me/va
    VA [#1]: $test: think {[lit(near       far)]}
    > test
    near       far

  Leaving out the {}'s will not work in the above.

See also: decompose()
& LMATH()
  lmath(<op>, <list>[, <delim>])

  This function performs generic math operations on <list>, returning the result. Each element of the list is treated as one argument to an operation, so that lmath(<op>, 1 2 3) is equivalent to <op>(1, 2, 3). Using @function, one can easily write ladd, lsub, etc as per TinyMUSH.

  Supported <op>'s are:
  add and band bor bxor dist2d dist3d div eq fdiv gt gte lt lte max mean median min modulo mul nand neq nor or remainder stddev sub xor

  Examples:
    > think lmath(add, 1|2|3, |)
    6

    > think lmath(max, 1 2 3)
    3

    > &FUN_FACTORIAL me=lmath(mul,lnum(1,%0))
    > think u(fun_factorial,5)
    120
& LN()
  ln(<number>)

  Returns the natural log of <number>. This is equivilent to log(<number>, e).

See also: log()
& LNUM()
  lnum(<number>)
  lnum(<start number>, <end number>[, <output separator>[, <step>]])

  With one argument, lnum returns a list of numbers, from 0 to <number - 1>. For example, lnum(4) returns the list "0 1 2 3". This is useful for creating loops.

  With two arguments, the numbers range from the first to the second argument. For example, lnum(1,4) => 1 2 3 4

  With three arguments, the output is separated by the separator given in the third argument. lnum(1,4,|) => 1|2|3|4

  A fourth argument dictates the step. By default, the step is 1.
  lnum(1,10,%b,2) -> 1 3 5 7 9
  lnum(0,10,%b,2) -> 0 2 4 6 8 10

& LOC()
  loc(<object>)

  For things and players, loc() returns the dbref of the object which contains <object>. For rooms, it returns the drop-to, if one is set, or #-1 otherwise. For exits, it returns the destination (the source is an exits home()). This will be #-1 for unlinked exits, #-2 for variable exits, and #-3 for exits @linked to "home".

  You must be able to examine <object>, or be near it, for this function to work. A special case exists when <object> is a player: As long as <object> is not set UNFINDABLE, and you are allowed to use the @whereis command, you can get <object>'s location.

  You can also get the location of the enactor using the %L substitution, whether you are near to/can examine it or not.

See also: locate(), rloc(), home(), where(), rnum(), room(), @link,
  UNFINDABLE, @whereis
& LOCALIZE()
  localize(<code>)

  localize() saves the q-registers, evaluates its argument, and restores the registers afterwards. It has the same effect as ulocal(), but doesn't require setting the code into an attribute.

  Examples:
    > say setr(0, Outside)-[setr(0, Inside)]-%q0
    You say, "Outside-Inside-Inside"

    > &INSIDE me=setr(0,Inside)
    > say setr(0, Outside)-[ulocal(INSIDE)]-%q0
    You say, "Outside-Inside-Outside"

    > say setr(0, Outside)-[localize(setr(0, Inside))]-%q0
    You say, "Outside-Inside-Outside"

See also: letq(), setq(), setr(), r(), ulocal(), uldefault()
& LOCATE()
  locate(<looker>, <name>, <parameters>)

  This function attempts to find an object called <name>, relative to the object <looker>. It's similar to the num() function, but you can be more specific about which type of object to find, and where to look for it. When attempting to match objects near to <looker> (anything but absolute, player name or "me" matches), you must control <looker>, have the See_All power or be nearby.

  <parameters> is a string of characters which control the type of the object to find, and where (relative to <looker>) to look for it.

  You can control the preferred types of the match with:
    N - No type (this is the default)
    E - Exits
    L - Prefer an object whose Basic @lock <looker> passes
    P - Players
    R - Rooms
    T - Things
    F - Return #-1 if what's found is of a different type than the preferred one.
    X - Never return #-2. Use the last dbref found if the match is ambiguous.

  If type(s) are given, locate() will attempt to find an object with one of the given types first. If none are found, it will attempt to find any type of object, unless 'F' is specified, in which case it will return #-1.

  Continued in 'help locate2'.
& LOCATE2

  You can control where to look with:
    a - Absolute match (match <name> against any dbref)
    c - Exits in the room <looker>
    e - Exits in <looker>'s location
    h - If <name> is "here", return <looker>'s location
    i - Match <name> against the names of objects in <looker>'s inventory
    l - Match <name> against the name of <looker>'s location
    m - If <name> is "me", return <looker>'s dbref
    n - Match <name> against the names of objects in <looker>'s location
    p - If <name> begins with a *, match the rest against player names
    z - English-style matching (my 2nd book) of <name> (see 'help matching')
    * - All of the above (try a complete match). Default when no match parameters are given.
    y - Match <name> against player names whether it begins with a * or not
    x - Only match objects with the exact name <name>, no partial matches
    s - Only match objects which <looker> controls. You must control <looker> or have the See_All power.

  Just string all the parameters together. Spaces are ignored, so you can use spaces between paramaters for clarity if you wish.

  See 'help locate3' for examples.
See also: num(), rnum(), pmatch(), room(), where(), rloc(), findable()
& LOCATE3

  Examples:
  Find the dbref of the player whose name matches %0, or %#'s dbref if %0 is "me".
    > think locate(%#, %0, PFym)
  'PF' matches objects of type 'player' and nothing else, 'm' checks for the string "me", and 'y' matches the names of players.

  Find the dbref of an object near %# called %0, including %# himself and his location. Prefer players or things, but accept rooms or exits if no players or things are found.
    > think locate(%#, %0, PThmlni)
  This prefers 'P'layers or 'T'hings, and compares %0 against the strings "here" and "me", and the names of %#'s location, his neighbours, and his inventory.
& LOCK()
  lock(<object>[/<locktype>][, <new value>])

  lock() returns the text string equivalent of the @lock on <object>. <locktype> can be any valid switch for @lock ("Enter", "user:foo", etc) and defaults to "Basic". You must be able to examine the lock.

  If a <new value> is given, lock() attempts to change the lock as @lock would first. You must control the object.

See also: @lock, locktypes, elock(), lockflags(), llockflags(), lset(), llocks(), lockowner(), lockfilter()
& LLOCKS()
& LOCKS()
  llocks([<object>])
  locks(<object>)

  llocks() and locks() both list @locks set on <object>, including user-defined locks (prefixed with USER:)

  If no object is given, llocks() returns all the predefined lock types available.

  Example:
    > @lock me==me
    > @lock/use me==me
    > @lock/user:itsme me==me
    > th llocks(me)
    Basic USER:ITSME Use

See also: lock(), lset(), lockflags(), llockflags(), lockowner()
& LOCKFILTER()
  lockfilter(<key>, <dbrefs>[, <delim>])

  lockfilter() goes through <dbrefs> and tests them all against the lock <key>, returning a list of all dbrefs that pass the <key>.

  <key> is evaluated from the caller's perspective.

  This is equivilent to filter(#lambda/testlock(<key>, %%0), <dbrefs>) but much more efficient, as the lock <key> is only parsed/compiled once.

  <delim> defaults to a space, and is the delimiter of <dbrefs> and the list returned by lockfilter().

  Examples:
    Get all male players with a name starting with 'W'.
    > think iter(lockfilter(NAME^W*&SEX:M*,lwho()),name(%i0))
    Walker WalkerBot Wilco

    List all wizroys online:
    > think iter(lockfilter(FLAG^WIZARD|FLAG^ROYALTY,lwho()),name(%i0))
    Sketch Viila Tanaku Raevnos Zebranky Cheetah Walker

    List all players with an IC age > 20.
    > think lockfilter(age:>20,lwho())
    #123 #456 #789

See also: @lock, lock(), elock(), lockkeys, filter(), testlock()
& LOCKFLAGS()
  lockflags(<object>[/<locktype>])
  lockflags()

  If an <object> is given, lockflags() returns a string consisting of the one-character abbreviations for all the lock flags on <object>'s <locktype> lock, or Basic lock if no locktype is given. You must be able to examine the lock.

  Given no arguments, this function returns a string consisting of all the flag letters the server knows.

See also: llockflags(), lset(), lock(), llocks(), lockowner()
& LLOCKFLAGS()
  llockflags(<object>[/<locktype>])
  llockflags()

  If an <object> is given, llockflags() returns a space-separated list of the lock flags on <object>'s <locktype> lock, or Basic lock if no locktype is given. You must be able to examine the lock.

  Given no arguments, this function returns a space-separated list of all the names of all lock flags known to the server.

See also: lockflags(), lset(), lock(), llocks(), lockowner()
& LOCKOWNER()
  lockowner(<object>[/<locktype>])

  This function returns the dbref of the player who owns the <locktype> lock on <object>, or the Basic lock if no <locktype> is given. You must be able to examine the lock to use this function.

See also: lockflags(), llockflags(), lset(), lock(), llocks()
& LSET()
  lset(<object>/<locktype>,[!]<flag>)

  This functions sets or clears flags on locks.

  See 'help @lset' for more information on what flags are available.

See also: lockflags(), llockflags(), lock(), lockowner()
& LOG()
  log(<number>[, <base>])

  Returns the logarithm (base 10, or the given base) of <number>. <base> can be a floating-point number, or 'e' for the natural logarithm.

See also: ln()
& LPARENT()
  lparent(<object>)

  This function returns a list consisting of <object>'s dbref (as per num()), the dbref of its parent, grandparent, greatgrandparent, etc. The list will not, however, show parents of objects which the player is not privileged to examine. Ancestor objects are not included.

See also: parent(), children(), PARENTS, ANCESTORS
& LPLAYERS()
  lplayers(<object>)

  This function returns the dbrefs of all players, connected or not, in <object>. DARK wizards aren't listed to mortals or those without the see_all power. You must be in <object> or control it to use this function.

See also: lvplayers(), lcon(), lthings()
& LTHINGS()
  lthings(<object>)

  This function returns the dbrefs of all things, dark or not, in <object>. You must be in <object> or control it to use this function.

See also: lvthings(), lcon()
& LPOS()
  lpos(<string>, <character>)

  This function returns a list of the positions where <character> appears in <string>, with the first character of the string being 0. Note that this differs from the pos() function, but is consistent with other string functions like mid() and strdelete().

  If <character> is a null argument, space is used. If <character> is not found anywhere in <string>, an empty list is returned.

  Example:
    > say lpos(a-bc-def-g, -)
    You say, "1 4 8"

See also: pos(), member(), match(), wordpos()
& LSEARCH()
& NLSEARCH()
& SEARCH()
& NSEARCH()
& LSEARCHR()
& CHILDREN()
& NCHILDREN()
  lsearch(<player>[, ... , <classN>, <restrictionN>])
  nlsearch(<player>[, ... , <classN>, <restrictionN>])
  lsearchr(<player>[, ... , <classN>, <restrictionN>])
  children(<object>)
  nchildren(<object>)

  This function is similar to the @search command, except it returns just a list of dbref numbers. The function must have at least three arguments. You can specify "all" or <player> for the <player> field; for mortals, only objects they can examine are included. If you do not want to restrict something, use "none" for <class> and <restriction>.

  The possible <class>es and <restriction>s are the same as those accepted by @search. lsearch() can accept multiple class/restriction pairs, and applies them in a boolean "AND" fashion, returning only dbrefs that fulfill all restrictions. See 'help @search' for information about them.

  children() is exactly the same as lsearch([me|all], parent, <object>), using "all" for See_All/Search players and "me" for others.

  nlsearch(...) and nchildren(...) return the count of results that would be returned by lsearch() or children() with the same args.

  Continued in 'help lsearch2'.
& LSEARCH2
& SEARCH2

  If <class> is one of the eval classes (EVAL, EEXITS, EROOMS, ETHINGS or EPLAYERS), note that any brackets, percent signs, or other special characters should be escaped, as the code in <restriction> will be evaluated twice - once as an argument to lsearch(), and then again for each object looked at in the search. Before the per-object evaluation, the string "##" is replaced with the object dbref.

  lsearch() is free unless it includes either an eval-class search or an elock search that contains an eval or indirect lock. Otherwise, it costs find_cost pennies to perform the lsearch.

  lsearchr() is like an lsearch() run through revwords(). Results are returned from highest dbref to lowest. search() is an alias for lsearch().

  See 'help lsearch3' for examples.

See also: @search, @find, lparent(), stats()
& LSEARCH3
& SEARCH3
  lsearch() Examples:

  lsearch(all, flags, Wc)                  <-- lists all connected wizards.
  lsearch(me, type, room)                  <-- lists all rooms owned by me.
  lsearch(me, type, room, flag, W)         <-- lists Wizard rooms owned by me.
  lsearch(me, type, room, 100, 200)        <-- same, but only w/db# 100-200
  lsearch(all, eplayer, \[eq(money(##),100)\]) <-- lists all players with 100 coins.
  lsearch(all, type, player, elock, (FLAG^WIZARD|FLAG^ROYALTY)&!FLAG^IC) ^-- list all wiz and roy players that are not IC.
  lsearch(all, type, player, elock, sex:m*) <- lists all players with an @sex beginning with 'm'
  lsearch(me, elock, !desc:*)              <-- lists all objects you own that don't have an @desc set
& LSTATS()
& STATS()
  lstats([<player>])

  This function returns the breakdown of objects in the database, in a format similar to "@stats". If <player> is "all" (the default), a breakdown is done for the entire database. Otherwise, the breakdown is returned for that particular player.

  Only wizards and those with the Search power can LSTATS() other players. The list returned is in the format:
  <Total objects> <Rooms> <Exits> <Things> <Players> <Garbage>

  stats() is an alias for lstats().
See also: nsearch()
& LT()
  lt(<number1>, <number2>[, ... , <numberN>])

  Takes two or more numbers, and returns 1 if and only if each number is less than the number after it, and 0 otherwise.

  Examples:
    > th lt(1,2)
    1
    > th lt(1,2,3)
    1
    > th lt(1,3,2)
    0

See also: lte(), gt(), gte(), lnum(), lmath()
& LTE()
  lte(<number1>, <number2>[, ... , <numberN>])

  Takes two or more numbers, and returns 1 if and only if each number is less than or equal to the number after it, and 0 otherwise.

See also: lt(), gt(), gte(), lnum(), lmath()
& LVCON()
  lvcon(<object>)

  This function returns the dbrefs of all objects that are inside <object> and visible (non-dark). You must be in <object> or control it to use this function.

See also: lcon(), lvplayers(), lvthings(), lvexits()
& LVEXITS()
  lvexits(<room>)

  This function returns the dbrefs of all visible (non-dark) exits from <room>. You must be in the room or control it to use this function.

See also: lexits(), lvcon(), lvplayers(), lvthings()
& LVPLAYERS()
  lvplayers(<object>)

  This function returns the dbrefs of all connected and non-dark players in an object. You must be in the object or control it to use this function.

See also: lplayers(), lvcon(), lvthings(), lvexits()
& LVTHINGS()
  lvthings(<object>)

  This function returns the dbrefs of all non-dark things inside an object. You must be in the object or control it to use this function.

See also: lthings(), lvplayers(), lvcon(), lvexits()
& LWHO()
& LWHOID()
  lwho([<viewer>[, <status>]])
  lwhoid([<viewer>[, <status>]])

  lwho() returns a list of the dbref numbers for all currently-connected players. When mortals use this function, the dbref numbers of hidden wizards or royalty do NOT appear on the dbref list.

  If a <viewer> is given, and used by a See_All object, lwho() returns the output of lwho() from <viewer>'s point of view.

  <status> can be used to include "#-1" dbrefs for unconnected ports, and must be one of "all", "online" (the default) or "offline". It is primarily useful when using a <status> with lports(), to make the dbrefs and ports match up. Only See_All players can see offline dbrefs.

  lwhoid() returns a list of objid's instead.

See also: mwho(), nwho(), xwho(), lports()
& MAP()
  map([<object>/]<attribute>, <list>[, <delim>[, <osep>]])

  This function works much like ITER(). The given <attribute> is evaluated once for each element of <list>, and the results of the evaluations are returned. For each evaluation, the current list element is passed to the attribute as %0, and its position in the list as %1. Elements of <list> are separated by <delim>, or a space if none is given, and the results are returned separated by <osep>, if given, or the delimiter otherwise.

  This is roughly equivilent to, though slightly more efficient than:
    iter(<list>, ulambda(<object>/<attribute>, %i0, inum(0)), <delim>, <osep>)

  Examples:
    > &times_two me=mul(%0,2)

    > say map(times_two, 5 4 3 2 1)
    You say, "10 8 6 4 2"

    > say map(times_two,1;2;3;4;5,;)
    You say, "2;4;6;8;10"

See also: anonymous attributes, iter(), @dolist
& ELEMENT()
& MATCH()
& MATCHALL()
  match(<list>, <pattern>[, <delimiter>])
  matchall(<list>, <pattern>[, <delimiter>[, <output separator>]])

  match() returns the index of the first element of <list> which matches the wildcard pattern <pattern>. The first word has an index of 1. If no matches are found, 0 is returned. element() is an alias for match().

  matchall() is similar, but returns the indexes of all matching elements. If no elements match, an empty string is returned.

  In both cases, elements of <list> are separated by <delimiter>, if it's given, or a space otherwise. The results of matchall() are separated by <ouput separator>, if given, and <delimiter> if not.

  To get the matching elements, instead of the indexes of where they appear in the list, use grab()/graball(). To see if a single string matches a wildcard pattern, use strmatch().

  See 'help match2' for examples.
See also: grab(), strmatch(), member(), reglmatch(), WILDCARDS
& MATCH2
  Examples:
    > say match(I am testing a test, test*)
    You say, "3"

    > say matchall(I am testing a test, test*)
    You say, "3 5"

    > say match(foo bar baz boing, sprocket)
    You say, "0"

    >say matchall(foo bar baz boing, sprocket)
    You say, ""
& REGLMATCH()
& REGLMATCHI()
& REGLMATCHALL()
& REGLMATCHALLI()
  reglmatch(<list>, <regexp>[, <delimiter>])
  reglmatchi(<list>, <regexp>[, <delimiter>])
  reglmatchall(<list>, <regexp>[, <delimiter>[, <output separator>]])
  reglmatchalli(<list>, <regexp>[, <delimiter>[, <output separator>]])

  These functions are the regexp versions of match() and matchall(). reglmatch() returns the position of the first element in <list> which matches the regular expression <regexp>. reglmatchi() does the same thing, but case-insensitively.

  reglmatchall() returns the positions of all elements in <list> which match <regexp>. reglmatchalli() is case-insensitive.

  In all cases, the elements of <list> are separated by <delimiter>, which defaults to a space. The elements outputted by reglmatchall() are separated by <output separator>, if one is given, or by <delimiter> if not.

  See 'help reglmatch2' for examples.
See also: regmatch(), regrab(), match(), REGEXP SYNTAX
& REGLMATCH2
  Examples:

  > say reglmatch(I am testing a test, test)
  You say, "3"

  > say reglmatch(I am testing a test, test$)
  You say, "5"

  > say reglmatchall(I am testing a test, test, , |)
  You say, "3|5"
& MAX()
  max(<number1>, <number2>[, ... , <numberN>])

  This function returns the largest number in its list of arguments. It can take any number of arguments.

See also: min(), lmath(), bound(), alphamax()
& AVG()
& MEAN()
  mean(<number1>, <number2>[, ... , <numberN>])

  Returns the mean (arithmetic average) of its arguments.

  avg() is an alias for mean(), for Rhost compatibility.

See also: median(), stddev(), lmath()
& MEDIAN()
  median(<number>, <number>[, ... , <numberN>)

  Returns the median (the middlemost numerically) of its arguments.

See also: mean(), stddev(), lmath()
& MEMBER()
  member(<list>, <word>[, <delimiter>])

  member() returns the position where <word> first occurs in <list>. If <word> is not present in <list>, it returns 0. Elements of <list> are <delimiter>-separated, or space-separated if no <delimiter> is given.

  member() is case-sensitive, and does not perform wildcard matching. If you need to do a wildcard match, use match(). To compare two strings (instead of a word and list elements), consider comp().

See also: match(), grab(), comp(), strmatch()
& MERGE()
  merge(<string1>, <string2>, <characters>)

  This function merges <string1> and <string2>, depending on <characters>. If a character in <string1> is the same as one in <characters>, it is replaced by the character in the corresponding position in <string2>. The two strings must be of the same length.

  Example:
    > say merge(AB--EF,abcdef,-)
    You say, "ABcdEF"

  Spaces need to be treated specially. An empty argument is considered to equal a space, for <characters>.

  Example:
    > say merge(AB[space(2)]EF,abcdef,)
    You say, "ABcdEF"

See also: splice(), tr()
& MESSAGE()
  message(<recipients>, <message>, [<object>/]<attribute>[, <arg0>[, ... , <arg9>][, <switches>]])

  message() is the function form of @message, and sends a message, formatted through an attribute, to a list of objects. See 'help @message' for more information. <switches> is a space-separated list of one or more of "nospoof", "spoof", "oemit" and "remit".

See also: @message, oemit(), remit(), speak()
& MID()
  mid(<string>, <first>, <length>)

  mid() returns <length> characters from <string>, starting from the <first> character. If <length> is positive, it counts forwards from the <first> character; for negative <length>s, it counts backwards. Note that the first character in <string> is numbered 0, not 1.

  Examples:
    > say mid(testing, 2, 2)
    You say, "st"
    > say mid(testing, 2, -2)
    You say, "es"

See also: left(), right(), strdelete()
& MIN()
  min(<number1>, <number2>[, ... , <numberN>])

  This function returns the smallest number in its list of arguments. It can take any number of arguments.

See also: max(), lmath(), bound(), alphamin()
& MIX()
  mix([<object>/]<attribute>, <list1>, <list2>[, ... , <list30>, <delim>])

  This function is similar to MAP(), except that it takes the elements of up to 30 lists, one by one, and passes them to the user-defined function as %0, %1, up to %9, respectively, for elements of <list1> to <list30>. Use v() to access elements 10 or higher. If the lists are of different sizes, the shorter ones are padded with empty elements. <delim> is used to separate elements; if it is not specified, it defaults to a space. If using more than 2 lists, the last argument must be a delimiter.

  See 'help mix2' for examples.
& MIX2
  Examples of mix():

    > &add_nums me=add(%0, %1)
    > say mix(add_nums,1 2 3 4 5, 2 4 6 8 10)
    You say, "3 6 9 12 15"

    > &lengths me=strlen(%0) and [strlen(%1)].
    > say mix(lengths, some random, words)
    You say, "4 and 5. 6 and 0."

    > &add_nums me=lmath(add, %0 %1 %2)
    > say mix(add_nums, 1:2:3, 4:5:6, 7:8:9, :)
    You say, "12:15:18"

See also: anonymous attributes, map(), step()
& MOD()
& MODULO()
& MODULUS()
& REMAINDER()
  modulo(<number>, <number>[, ..., <numberN>])
  remainder(<number>, <number>[, ..., <numberN>])

  remainder() returns the remainder of the integer division of the first number by the second (and subsequent) number(s) (ie, the remainder from calling div() with the same arguments).

  modulo() returns the modulo of the given numbers (from calling floordiv() with the same arguments).

  For positive numbers, these are the same, but they may be different for negative numbers:

     modulo(13,4)       ==>  1      and     remainder(13,4)    ==>  1
     modulo(-13,4)      ==>  3      but     remainder(-13,4)   ==>  -1
     modulo(13,-4)      ==>  -3     but     remainder(13,-4)   ==>  1
     modulo(-13,-4)     ==>  -1     and     remainder(-13,-4)  ==>  -1

  remainder()s result always has the same sign as the first argument. modulo()s result always has the same sign as the second argument.

  mod() and modulus() are aliases for modulo().

See also: div(), lmath()
& MONEY()
  money(<integer>)
  money(<object>)

  If given an integer, money() returns the appropriate name (either singular or plural) for that amount of money, as set in the money_singular and money_plural @config options.

  Otherwise, it returns the amount of money <object> has. If <object> has the no_pay power, the value of the 'max_pennies' @config option is returned. <object> must have the power itself, rather than inheriting it from its owner, in this case.

  Examples:
    > say money(Javelin)
    You say, "150"

    > say money(1)
    You say, "Penny"

    > say money(2)
    You say, "Pennies"

    > &counter CvC=$count *: @say %0 [money(%0)]. Ah.. ah.. ah.
    > count 2
    Count von Count says, "2 Pennies. Ah.. ah.. ah."

See also: score
& MTIME()
& MSECS()
  mtime(<object>[, <utc?>])
  msecs(<object>)

  mtime() returns the date and time that one of <object>'s attributes or locks was last added, deleted, or modified. The time returned is in the server's local timezone, unless <utc?> is true, in which case the time is in the UTC timezone.

  msecs() returns the time as the number of seconds since the epoch.

  Only things, rooms, and exits have modification times. You must be able to examine an object to see its modification time.

See also: ctime(), time(), secs(), convtime(), convsecs()
& MUDNAME()
& MUDURL()
  mudname()
  mudurl()

  These functions return the name of the MUSH and the MUSH's website address, as set in the 'mud_name' and 'mud_url' @config options.

  Example:
    > say mudname()
    You say, "TestMUSH"
    > say mudurl()
    You say, "http://www.testmush.com"

see also: config()
& MUL()
  mul(<number1>, <number2>[, ... , <numberN>])

  Returns the product of some numbers.

See also: lmath(), div(), fdiv()
& MUNGE()
  munge([<object>/]<attribute>, <list1>, <list2>[, <delimiter>[, <osep>]])

  This function takes two lists of equal length. It passes the entirety of <list1> to the user-defined function as %0, and the delimiter as %1. Then, this resulting list is matched with elements in <list 2>, and the rearranged <list2> is returned.

  This is useful for doing things like sorting a list, and then returning the corresponding elements in the other list. If a resulting element from the user-defined function doesn't match an element in the original <list1>, a corresponding element from <list2> does not appear in the final result. The elements are matched using an exact, case-sensitive comparision.

  <delimiter> defaults to a space, and <osep> defaults to <delimiter>.

  See 'help munge2' for examples.
& MUNGE2
  For example: Consider attribute PLACES, which contains "Fort Benden Ista", and another attribute DBREFS contains the dbrefs of the main JUMP_OK location of these areas, "#20 #9000 #5000". We want to return a list of dbrefs, corresponding to the names of the places sorted alphabetically. The places sorted this way would be "Benden Fort Ista", so we want the final list to be "#9000 #20 #5000". The functions, using munge(), are simple:

    > &sort me=sort(%0)
    > say munge(sort, v(places), v(dbrefs))
    You say, "#9000 #20 #5000"

  See 'help munge3' for another example.
& MUNGE3
  Another common task that munge() is well suited for is sorting a list of dbrefs of players by order of connection. This example uses #apply to avoid the need for the sort attribute, and also unlike the other example, it builds the list to sort on out of the list to return.

    > &faction_members me=#3 #12 #234
    > say munge(#apply/sort, map(#apply/conn, v(faction_members)), v(faction_members))
    You say, "#12 #234 #3"

See also: anonymous attributes
& MWHO()
& MWHOID()
  mwho()
  mwhoid()

  mwho() returns a list of the dbref numbers for all current-connected, non-hidden players. It's exactly the same as lwho() used by a mortal, and is suitable for use on privileged global objects who need an unprivileged who-list. In some cases, lwho(<viewer>) may be preferable to mwho(), as it includes hidden players for <viewer>s who can see them.

  mwhoid() returns a list of objids instead.

See also: lwho(), nwho()
& ALIAS()
& FULLALIAS()
  alias(<object>[, <new alias>])
  fullalias(<object>)

  alias() returns the first of <object>'s aliases. fullalias() returns all the aliases set for <object>. Note that, while any object can have an alias set, they are only meaningful for players and exits.

  With two arguments, alias() attempts to change the alias for <object> to <new alias>, as per @alias.

  Examples:
    > ex *Noltar/ALIAS
    ALIAS [#7$v]: $;No;Nol;Noli;Nolt
    > say alias(*Noltar)
    You say, "$"
    > say fullalias(*Noltar)
    You say, "$;No;Nol;Noli;Nolt"

See also: fullname()
& NAME()
  name(<object>[, <new name>])

  name() returns the name of object <object>. For exits, name() returns only the displayed name of the exit.

  With two arguments, name() attempts to rename <object> to <new name>, as per @name.

See also: fullname(), accname(), iname(), alias(), moniker()
& MONIKER()
& CNAME()
  moniker(<object>)

  Returns <object>'s accented name, with the color template from its @moniker applied. moniker() always returns the colored name, even if monikers are disabled via @config.

See also: MONIKERS, @moniker, name(), MONIKER, iname(), accname()
& NAMELIST()
  namelist(<player-list>[, [<object>/]<attribute>])

  namelist() takes a list of players of the form used by the page command and returns a corresponding list of dbrefs. Invalid and ambiguous names return the dbrefs #-1 and #-2, respectively.

  If an <object>/<attribute> is given, the specified attribute will be called once for each invalid name, with the name as %0 and the dbref returned (#-1 for an unmatched name, #-2 for an ambiguous one) as %1.

  Example:
    > &test me=pemit(%#,Bad name "%0")
    > say namelist(#1 Javelin "ringo spar" bogus, test)
    Bad name "bogus"
    You say, "#1 #7 #56 #-1"

See also: namegrab(), name(), locate(), num(), pmatch()
& NAMEGRAB()
& NAMEGRABALL()
  namegrab(<dbref list>, <name>)
  namegraball(<dbref list>, <name>)

  The namegrab() function returns the first dbref in the list that would match <name> as if you were checking num() or locate(). An exact match has priority over partial matches.

  namegraball() returns all dbrefs whose names would be matched by <name>.

  Examples: #0 = Room Zero, #1 = One, #2 = Master Room
    > say namegrab(#0 #1 #2,room)
    You say, "#0"
    > say namegrab(#0 #1 #2,master room)
    You say, "#2"
    > say namegraball(#0 #1 #2,room)
    You say, "#0 #2"

See also: namelist(), locate()
& NAND()
& NCAND()
  nand(<boolean1>[, ... , <booleanN>])
  ncand(<boolean1>[, ... , <booleanN>])

  These functions return 1 if at least one of their arguments are false, and 0 if all are true. nand() always evaluates all of its arguments, while ncand() stops evaluating after the first false value.

  Equivalent to not(and()) and not(cand()), but more efficient.

See also: lmath(), and(), cand(), or(), nor()
& NEARBY()
  nearby(<object 1>, <object 2>)

  Returns 1 if <object 1> is "nearby" <object 2>, and 0 otherwise. "Nearby" means the objects are in the same location, or that one is located inside the other. You must control at least one of the objects; if you don't, or if one of the objects can't be found, nearby() returns #-1.

See also: locate(), findable()
& NEQ()
  neq(<number1>, <number2>[, ... , <numberN>])

  Returns 0 if all the given <number>s are the same, and 1 otherwise. Basically the same as [not(eq(<number1>, <number2>[, ... , <numberN>]))] but more efficient.

See also: eq(), not(), lmath()
& NEXT()
  next(<object>)

  If <object> is an exit, then next() will return the next exit in <object>'s source room. If <object> is a thing or a player, then next() will return the next object in the contents list of <object>'s location. Otherwise, it returns a #-1. #-1 is also used to denote that there are no more exits or objects after <object>.

  You can get the complete contents of any container you may examine, regardless of whether or not objects are dark. You can get the partial contents (obeying DARK/LIGHT/etc.) of your current location or the enactor (%#). You CANNOT get the contents of anything else, regardless of whether or not you have objects in it. These rules apply to exits, as well.

See also: lcon(), lexits(), con(), exit()
& NEXTDBREF()
  nextdbref()

  This function returns the next dbref on the free list; when the next object is @created (or @dug, or @opened, or @pcreated, etc.), it will have this dbref.

See also: @stats, stats()
& NOR()
& NCOR()
  nor(<boolean1>[, ... , <booleanN>])
  ncor(<boolean1>[, ... , <booleanN>])

  These functions return 1 if all their arguments are false, and 0 if any are true. nor() always evaluates all arguments, while ncor() stops evaluating after the first true value.

  Equivalent to not(or()) and not(cor()), but more efficient.

See also: and(), or(), xor(), not(), nand(), lmath()
& NOT()
  not(<boolean>)

  not() returns 1 if <boolean> is false, and 0 if it's true.

  The definition of truth and falsehood depends on configuration settings; see 'help boolean values' for details.

See also: Boolean Functions, t(), and(), or(), nor(), xor()
& NUM()
  num(<object>)

  Returns the dbref number of <object>. <object> must reference a valid object, as per 'help matching'.

See also: locate(), rnum(), pmatch()
& NVCON()
& NCON()
  ncon(<object>)
  nvcon(<object>)

  These functions return a the number of objects inside <object>. They are identical to words(lcon(<object>)) and words(lvcon(<object>)), respectively, but are more efficient and do not suffer from buffer constraints.

See also: nexits(), nplayers(), xcon(), lcon(), lvcon()
& NVEXITS()
& NEXITS()
  nexits(<room>)
  nvexits(<room>)

  These functions return a count of the exits in a room. They are equivilent to words(lexits(<room>)) and words(lvexits(<room>)) respectively, though are more efficient, and don't suffer from buffer constraints.

See also: ncon(), nplayers(), xexits(), lexits(), lvexits()
& NVPLAYERS()
& NPLAYERS()
  nplayers(<object>)
  nvplayers(<object>)

  These functions return a count of the players in <object>. They are equivilent to words(lplayers(<object>)) and words(lvplayers(<object>)) respectively, though are more efficient and do not suffer from buffer constraints.

See also: ncon(), nexits(), xplayers(), lplayers(), lvplayers()
& NVTHINGS()
& NTHINGS()
  nthings(<object>)
  nvthings(<object>)

  These functions return a count of the things in a container. They are equivilent to words(lthings(<object>)) and words(lvthings(<object>)) respectively, though are more efficient and do not suffer from buffer constraints.

See also: ncon(), nexits(), xthings(), lthings(), lvthings()
& NMWHO()
& NWHO()
  nwho([<viewer>])
  nmwho()

  nwho() returns a count of all currently-connected players. When mortals use this function, hidden players are NOT counted. See_All players can specify a <viewer> to get a count of the number of players that <viewer> can see is online.

  nmwho() returns a count of all currently connected, non-hidden players. It's exactly the same as nwho() used by a mortal, and is suitable for use on privileged global objects that always need an unprivileged count of who is online.

  These functions are equivilent to words(lwho([<viewer>])) and words(mwho()), but are more efficient, and don't suffer from buffer constraints.

See also: lwho(), mwho(), xwho(), xmwho()
& OBJ()
& %o
  obj(<object>)

  Returns the objective pronoun - him/her/it - for an object. The %o substitution will return the objective pronoun of the enactor.

See also: subj(), poss(), aposs()
& OBJEVAL()
  objeval(<object>, <expression>)

  Allows you to evaluate <expression> from the viewpoint of <object>. If side-effect functions are enabled, you must control <object>; if not, you must either control <object> or have the see_all power. If <object> does not exist or you don't meet one of the criterion, the expression evaluates with your privileges.

See also: s()
& OBJID()
  objid(<object>)

  This function returns the object id of <object>, a value which uniquely identifies it for the life of the MUSH. The object id is the object's dbref, a colon character, and the object's creation time, in seconds since the epoch, equivilent to [num(<object>)]:[csecs(<object>)]

  The object id can be used nearly anywhere the dbref can, and ensures that if an object's dbref is recycled, the new object won't be mistaken for the old object.

  The substitution %: returns the object id of the enactor.

See also: num(), csecs(), ctime(), ENACTOR
& OBJMEM()
  objmem(<object>)

  This function returns the amount of memory, in bytes, being used by the object. It can only be used by players with Search powers.

See also: playermem()
& OEMIT()
& NSOEMIT()
  oemit([<room>/]<object> [... <object>], <message>)
  nsoemit([<room>/]<object> [... <object>], <message>)

  Sends <message> to all objects in <room> (default is the location of <object>(s)) except <object>(s), as per @oemit.

  nsoemit() works like @nsoemit.

& OPEN()
  open(<exit name>[, <destination>[, <source>[, <dbref>]]])

  This function attempts to open an exit named <exit name>. The exit will be opened in the room <source>, if given, or the caller's current location if no <source> is specified.

  If a <destination> is given, it will attempt to link the exit to <destination> after opening it.

  Wizards and objects with the pick_dbref power can specify a garbage dbref to use for the new exit.

  It returns the dbref of the newly created exit, or #-1 on error.

See also: @open, @link, dig(), link(), create(), pcreate()
& OR()
& COR()
  or(<boolean1>, <boolean2>[, ... , <booleanN>])
  cor(<boolean1>, <boolean2>[, ... , <booleanN>])

  These functions take a number of boolean values, and return 1 if any of them are true, and 0 if all are false. or() always evaluates all of its arguments, while cor() stops evaluating as soon as one is true.

See also: BOOLEAN VALUES, and(), nor(), firstof(), allof(), lmath()
& ORFLAGS()
& ORLFLAGS()
  orflags(<object>, <string of flag characters>)
  orlflags(<object>, <list of flag names>)

  These functions return 1 if <object> has any of the given flags, and 0 if it does not. orflags() takes a string of single flag letters, while orlflags() takes a space-separated list of flag names. In both cases, a ! before the flag means "not flag".

  If there is a syntax error like a ! without a following flag, '#-1 INVALID FLAG' is returned. Unknown flags are treated as being not set.

  Examples: Check to see if %# is set Wizard, Dark, or not set Ansi.
    > say orflags(%#, WD!A)
    > say orlflags(%#, wizard dark !ansi)

See also: andflags(), flags(), lflags(), orlpowers()
& ORLPOWERS()
  orlpowers(<object>, <list of powers>)

  This function returns 1 if <object> has at least one of the powers in a specified list, and 0 if it does not. The list is a space-separated list of power names. A '!' preceding a flag name means "not power".

  Thus, ORLPOWERS(me, poll login) would return 1 if I have the poll and login powers. ORLFLAGS(me, functions !guest) would return 1 if I have the functions power or are not a guest.

  If there is a syntax error like a ! without a following power, '#-1 INVALID POWER' is returned. Unknown powers are treated as being not set.

See also: powers(), andlpowers(), POWERS LIST, @power, orlflags()
& OWNER()
 owner(<object>[/<attribute>])
 owner(<object>[/<attribute>], <new owner>[, preserve])

  Given just an object, it returns the owner of the object. Given an object/attribute pair, it returns the owner of that attribute.

  If <new owner> is specified, the ownership is changed, as in @chown or @atrchown. If the optional third argument is "preserve", privileged flags and powers will be preserved ala @chown/preserve.
  If changing ownership, #-1 or 0 is returned on failure, 1 on success.

See also: lockowner(), @chown, @atrchown

& PARENT()
  parent(<object>[, <new parent>])

  This function returns the dbref number of an object's parent. You must be able to examine the object to do this. If you specify a second argument, parent() attempts to change the parent first. You must control <object>, and be allowed to @parent to <new parent>.
See also: @parent, ancestors, pfun()
& PEMIT()
& NSPEMIT()
& PROMPT()
& NSPROMPT()
  pemit(<object list|port numbers>, <message>)
  nspemit(<object list|port numbers>, <message>)
  prompt(<object list>, <message>)
  nsprompt(<object list>, <message>)

  With an <object list>, pemit() will send each object on the list a message, as per the @pemit/list command. It returns nothing. It respects page-locks and HAVEN flags on players. With <port numbers>, pemit() sends the message to the specified ports only, like @pemit/port/list.

  nspemit() works like @nspemit/list.

  prompt() adds a telnet GOAHEAD to the end of the message, as per the @prompt command. nsprompt() that works like @nsprompt.

See also: @prompt, @nsprompt, PROMPT_NEWLINES
& PI()
  pi()

  Returns the value of "pi" (3.14159265358979323846264338327, rounded to the game's float_precision setting).
& PIDINFO()
  pidinfo(<pid>[, <list of fields>[, <output separator>]])

  This function returns information about a process id if the player has permission to see the process. The <list of fields> is a space-separated list that may contain the following elements:

    queue       the queue ("wait" or "semaphore") for the process
    executor    the queueing object
    time        remaining time for timed queued entries (or -1)
    object      the semaphore object for semaphores (or #-1)
    attribute   the semaphore attribute for semaphores (or #-1)
    command     the queued command

  If <list of fields> is not provided, all fields are returned. The fields are separated by <output separator>, which defaults to a space.

See also: @ps, lpids(), getpids()
& PLAYERMEM()
  playermem(<player>)

  This function returns the amount of memory, in bytes, being used by everything owned by the player. It can only be used by players with Search powers.

See also: objmem()
& PLAYER()
  player(<port>)

  Returns the dbref of the player connected to a given port. Mortals can only use this function on their own ports, while See_All players can use it on any port.

See also: lports(), ports()
& PMATCH()
  pmatch(<name>)

  pmatch() attempts to find a player called <name>, which should be the full or partial name of a player (possibly prefixed with a "*") or a dbref. First, it checks to see if <name> is the dbref, full name, or alias of a player; if so, their dbref is returned. Otherwise, it checks for partial matches against the names of online players. If there are no matches, #-1 is returned. If there are multiple matches, pmatch() returns #-2. Otherwise, the matching player's dbref is returned.

  pmatch() does not check for the string "me". If you wish to do that, you should use locate (for example, locate(<player>, <name>, PFym)).

See also: num(), namelist(), locate()
& POLL()
  poll()

  This function returns the current @poll.

See also: @poll, doing(), @doing
& LPIDS()
  lpids([<object>[, <queue types>]])

  This function returns a list of queue process ids (pids). Only commands queued by objects with the same owner as <object> are listed. If you have the see_queue @power, you can specify "all" for <object> to get pids for everyone's queue entries. <object> defaults to the caller, or "all" for priviledged callers.

  <queue types> should be a list of one or more of the following words, to filter the pids returned:
    wait        --  Only return wait queues
    semaphore   --  Only return semaphore queues
    independent --  Only return commands queued by <object> specifically, instead of all objects with the same owner as <object>.
  If not specified, it defaults to "wait semaphore".

See also: @ps, getpids(), pidinfo()
& LPORTS()
& PORTS()
  lports([<viewer>[, <status>]])
  ports(<player name>)

  These functions return the list of descriptors ("ports") that are used by connected players. lports() returns all ports, in the same order as lwho() returns dbrefs, and ports() returns those a specific player is connected to, from most recent to least recent. Mortals can use ports() on themselves, but only See_All players can use ports() on others, or use lports().

  If lports() is given a <viewer>, only the ports of connections which <viewer> can see are returned, in the same way as lwho(<viewer>) works.

  The <status> argument for lports() controls whether or not ports which are not connected to (ie, at the login screen) are included, and must be one of "all", "online" or "offline".

  These port numbers also appear in the wizard WHO, and can be used with @boot/port, page/port, and the functions that return information about a connection to make them use a specific connection rather than the least-idle one when a player has multiple connections open. Players can get information about their own connections. See_all is needed to use them to get information about other people's ports.

See also: lwho(), player(), Connection Functions
& POS()
  pos(<needle>, <haystack>)

  This function returns the position that <needle> begins in <haystack>. Unlike most other string functions, the first character of <haystack> is numbered 1, not 0. If <needle> is not present in <haystack>, pos() returns #-1.

See also: member(), match(), lpos(), wordpos()
& POSS()
& %p
  poss(<object>)

  Returns the possessive pronoun - his/her/its - for an object. The %p substitution also returns the possessive pronoun of the enactor.

See also: subj(), obj(), aposs()
& POWER()
  power(<number>, <exponent>)

  Returns <number> to the power of <exponent>.

  (For the functional version of @power, see 'help powers()'.)

See also: root()
& POWERS()
  powers()
  powers(<object>)
  powers(<object>, <power>)

  With no arguments, powers() returns a space-separated list of all defined @powers on the MUSH. With one argument, it returns a list of the powers possessed by <object>.

  With two arguments, it attempts to set <power> on <object>, as per @power <object>=<power>.

See also: andlpowers(), orlpowers(), @power, POWERS LIST
& QUOTA()
  quota(<player>)

  Returns the player's quota, the maximum number of objects they can create if quotas are in effect. Returns 99999 for players with the No_Quota @power, so it's safe to use in numerical comparisons.

  You must control <player> or have the See_All or Quotas @powers to use this function.

See also: @quota, @squota, @allquota, QUOTAS, Quotas Power, No_Quota Power
& R()
& %q
& R-FUNCTION
  r(<register>[, <type>])

  The r() function can be used to access registers. It can retrieve the value of q-registers set with setq() and related functions, as well as the 30 stack values (the first ten of which are also available via %0-%9), and also iter() and switch() context (also available through itext() and stext(), respectively). The registers() function can be used to obtain a list of available registers.

  <type> defaults to "qregisters", and must be one of:

    qregisters - registers set with setq(), setr() and similar functions
    args       - the stack, usually accessed via %0-%9. There are up to 30 stack registers, plus named stack registers from regexp $-commands
    iter       - itext() context from iter() or @dolist. Must be an int, or "L" for the outermost itext().
    switch     - stext() context from switch() or @switch. Must be an int, or "L" for the outermost stext()
    regexp     - regexp capture names from re*() regexp functions

  qregisters can also be accessed via the %qX (for one-char register names) or %q<X> (for registers with longer names) substitutions.

See also: setq(), letq(), listq(), unsetq(), registers(), v(), itext(), stext(), ilev(), slev()
& RAND()
  rand()
  rand(<num>)
  rand(<min>, <max>)

  Return a random number.

  The first form returns a floating-point number in the range 0 <= n < 1.

  The second form returns an integer between 0 and <num>-1, inclusive (or between 0 and <num>+1, for negative <num>s).

  The third returns an integer between <min> and <max>, inclusive.

  If called with an invalid argument, rand() returns an error message
  beginning with #-1.

See also: randword()
& RANDWORD()
& PICKRAND()
  randword(<list>[, <delimiter>])

  Returns a randomly selected element from <list>. Elements of the list are separated by <delimiter>, which defaults to a space.

  pickrand() is an alias for randword().

See also: rand(), randextract()
& RANDEXTRACT()
  randextract(<list>[, <count>[, <delim>[, <type>[, <osep>]]]])

  Returns up to <count> random elements from the <delim>-separated <list>. The following <type>s are available:
    R - Grab <count> elements from <list> at random, but don't duplicate any elements
    L - Grab <count> elements from <list>, in order, starting at a random element
    D - Grab <count> elements from <list> at random, with duplicates allowed

  randextract() may return less than <count> elements for <type>s L and R, depending on the random element chosen and the length of <list>. Elements of the returned list are separated by <osep>, which defaults to <delim>. <delim> defaults to a single space, <count> defaults to 1, and <type> defaults to R.

  Examples:
    > say randextract(this is a test,3)
    You say "this test a"
    > say randextract(this@is@a@test,3,@)
    You say "this@a@test"
    > say randextract(this is a test,3,,L,*)
    You say "this*is*a"
    > say randextract(this is a test,6,,D)
    You say, "this test is this is is"

See also: rand(), randword()
& REGEDIT()
& REGEDITALL()
& REGEDITI()
& REGEDITALLI()
  regedit(<string>, <regexp>, <replace>[, ... , <regexpN>, <replaceN>])
  regediti(<string>, <regexp>, <replace>[, ... , <regexpN>, <replaceN>])
  regeditall(<string>, <regexp>, <replace>[, ... , <regexpN>, <replaceN>])
  regeditalli(<string>, <regexp>, <replace>[, ... , <regexpN>, <replaceN>])

  These functions edit <string>, replacing the part of the string which matches the regular expression <regexp> with the accompanying <replace>. In <replace>, the string "$<number>" is expanded during evaluation to the <number>th sub-expression, with $0 being the entire matched section. If you use named sub-expressions (?P<name>subexpr), they are referred to with "$<name>". Note that, with named sub-expressions, the "<>" are literal.

  regedit() only replaces the first match, while regeditall() replaces all matches. The versions ending in i are case insensitive. The <replace> argument is evaluated once for each match, allowing for more complex transformations than is possible with straight replacement.

  Examples:
    > say regedit(this test is the best string, (?P<char>.)est, $<char>rash)
    You say "this trash is the best string"
    > say regeditall(this test is the best string, (.)est, capstr($1)rash)
    You say "this Trash is the Brash string"

See also: edit(), @edit, regmatch(), regrab()
& REGMATCH()
& REGMATCHI()
  (Help text from TinyMUSH 2.2.4, with permission)
  regmatch(<string>, <regexp>[, <register list>])
  regmatchi(<string>, <regexp>[, <register list>])

  regmatch() checks to see if the entirety of <string> matches the regular expression <regexp>, and returns 1 if so and 0 if not. regmatchi() does the same thing, but case-insensitively. They are the regexp-equivilent of strmatch(); if you're looking for a regexp version of match(), see 'help reglmatch()'.

  If <register list> is specified, there is a side-effect: any parenthesized substrings within the regular expression will be set into the specified local registers. The syntax for this is X:Y, where X is the number (0 is the entire matched text) or name of the substring, and Y is the q-register to save it in. If X: isn't given, the nth substring based on the register's position in the list minus one is used. The first element will have the complete matched text, the second the first substring, and so on. This is to maintain compatibility with old code; it's recommended for new uses that the X:Y syntax be used.

  If <regexp> is not a valid regular expression, an error in the form "#-1 REGEXP ERROR: <description>" will be returned.

  See 'help regmatch2' for an example.

See also: regrab(), regedit(), valid(), reswitch(), strmatch(), regexp syntax
& REGMATCH2

  For example, in
    > think regmatch(cookies=30, (.+)=(\[0-9\]*) )
  (note use of escaping for MUSH parser), then the 0th substring matched is 'cookies=30', the 1st substring is 'cookies', and the 2nd substring is '30'. If <register list> is '0:0 1:3 2:5', then %q0 will become "cookies=30", %q3 will become "cookies", and %q5 will become "30".

  If <register list> was '0:0 2:5', then the "cookies" substring would simply be discarded. '1:food 2:amount' would store "cookies" in %q<food> and "30" in %q<amount>.

  See 'help regexp syntax' for an explanation of regular expressions.
& REMIT()
& NSREMIT()
  remit(<object list>, <message>)
  nsremit(<object list>, <message>)

  Sends a message to the contents of all the objects specified in <object list>, as per @remit/list.

  nsremit() works like @nsremit/list.

See also: @remit, pemit(), lemit()
& REMOVE()
  remove(<list>, <words>[, <delimiter>])

  This function removes the first occurrence of every word in the list <words> from <list>, and returns the resulting <list>. It is case sensitive.

  Elements of <list> and <words> are both separated by <delimiter>, which defaults to a space.

See also: linsert(), ldelete(), setdiff()
& RENDER()
  render(<string>, <formats>)

  This function renders the given <string> into a given format. Most useful when coding bots, or inserting text into an SQL database to display on a website. <formats> is a space-separated list of one or more of the following:

    ansi      --  Convert colors to raw ANSI tags (requires Can_Spoof power)
    html      --  Escape HTML entities (< to &lt;, etc) and convert Pueblo to HTML tags
    noaccents --  Downgrade accented characters, as per stripaccents()
    markup    --  Leave any markup not already converted by ansi/html as internal markup tags. Without this, unhandled markup
                  will be stripped, as per stripansi()

  Examples:
    > say render(<Test 1> & [tagwrap(u,Test 2)], html)
    You say, "&lt;Test 1&gt; &amp; <u>Test 2</u>"

See also: stripaccents(), stripansi(), Pueblo, @sql, tagwrap(), json()
& REPEAT()
  repeat(<string>, <number>)

  This function simply repeats <string>, <number> times. No spaces are inserted between each repetition.

  Example:
    > say repeat(Test, 5)
    You say, "TestTestTestTestTest"

See also: space()
& LREPLACE()
& REPLACE()
  lreplace(<list>, <position(s)>, <new item>[, <delimiter>[, <osep>]])

  This replaces the item(s) at the given <position(s)> in <list> with <new item>. <delimiter> defaults to a space, and <osep> defaults to <delimiter>. Null items are counted when determining position.

  If <position> is negative, it counts backwards from the end of the list. A <position> of -1 will replace the last element, -2 the element before last, and so on.

  Examples:
    > say lreplace(Turn north at the junction,2,south)
    You say, "Turn south at the junction"

    > say lreplace(Turn north at the junction,-1,crossroads)
    You say, "Turn north at the crossroads"

    > say lreplace(blue|red|green|yellow,3,white,|)
    You say, "blue|red|white|yellow"

    > say lreplace(this starts and ends the same, 1 -1, foo)
    You say, "foo starts and ends the foo"

  replace() is an alias for lreplace(), for backwards compatability.

See also: ldelete(), linsert(), setdiff(), splice(), strreplace()
& REST()
  rest(<list>[, <delimiter>])

  Returns a list minus its first element.

See also: after(), first(), last()
& REVWORDS()
  revwords(<list>[, <delimiter>[, <output separator>]])

  This function reverses the order of words in a list. List elements are separated by <delimiter>, which defaults to a space. Elements in the reversed list are separated by <ouput separator>, which defaults to the delimiter.

  Example:
    > say revwords(foo bar baz eep)
    You say, "eep baz bar foo"

See also: flip()
& RIGHT()
  right(<string>, <length>)

  Returns the <length> rightmost characters from <string>.

See also: left(), mid()
& RJUST()
  rjust(<string>, <length>[, <fill>[, <truncate?>]])

  This function returns <string>, padded on the left with the string <fill> until it's <length> characters long. <fill> can be more than one character in length, and defaults to a single space.

  If <string> is longer than <length>, it will be returned unaltered, unless <truncate?> is true, in which case only the last <length> characters of <string> are returned.

  Examples:
    > say -[rjust(foo,6)]-
    You say, "-   foo-"

    > say %r0[rjust(foo,6,-)]%r01234567
    You say, "
    0---foo7
    01234567"

    > say rjust(foo,12,=-)
    You say, "=-=-=-=-=foo"

    > say rjust(This is too long,9,,1)
    You say, " too long"

See also: align(), center(), ljust(), right()
& RLOC()
  rloc(<object>, <levels>)

  This function may be used to the get the location of <object>'s location (and on through the levels of locations), substituting for repeated nested loc() calls. <levels> indicates the number of loc()-equivalent calls to make; i.e., loc(loc(<object>)) is equivalent to rloc(<object>,2). rloc(<object>,0) is equivalent to num(<object>), and rloc(<object>,1) is equivalent to loc(<object>).

  If rloc() encounters a room, the dbref of that room is returned. If rloc() encounters an exit, the dbref of that exit's destination is returned. You must control <object>, be near it, or it must be a findable player.

See also: loc(), where(), room(), rnum(), locate()
& RNUM()
  rnum(<container>, <object>)

  This function looks for an object called <object> located inside <container>. If a single matching object is found, its dbref is returned. If several matching objects are found, #-2 is returned, and if nothing matches, or you lack permission, #-1 is returned.

  You must be in <container>, or be able to examine it, to use this function.

  This function has been deprecated and may be removed in a future patchlevel; locate(<container>, <object>, i) should be used instead.

See also: locate(), num(), rloc(), room()
& ROOM()
  room(<object>)

  Returns the "absolute" location of an object. This is always a room; it is the container of all other containers of the object. The "absolute" location of an object is the place @lemit messages are sent to and NO_TEL status determined. You must control the object, be See_All, or be near the object in order for this function to work. The exception to this are players; if <object> is a player, the ROOM() function may be used to find the player's absolute location if the player is not set UNFINDABLE.

See also: loc(), rloc(), rnum(), where()
& ROOT()
  root(<number>, <n>)

  Returns the n-th root of <number>. The 2nd root is the square root, the 3rd the cube root, and so on.

  Examples:
    > think root(27, 3)
    3
    > think power(3, 3)
    27

See also: sqrt(), power()
& ROUND()
& CEIL()
& FLOOR()
  round(<number>, <places>[, <pad>])
  floor(<number>)
  ceil(<number>)

  round() rounds <number> to <places> decimal places. <places> must be between 0 and config(float_precision). If the optional <pad> argument is true, the result will be padded with 0s if it would otherwise have fewer than <places> digits after the decimal point.

  floor() rounds <number> down, and ceil() rounds <number> up, to 0 decimal places.

  Examples:
    > think round(3.14159, 2)
    3.14
    > think round(3.5, 3, 1)
    3.500
    > think ceil(3.14159)
    4
    > think floor(3.14159)
    3

See also: bound(), trunc()
& FN()
  fn([<obj>/]<function name>[, <arg0>[, ... , <argN>]])

  fn() executes the built-in/hardcoded function <function name>, even if the function has been deleted or overridden with @function. It is primarily useful within @functions that override built-ins in order to be able to call the built-in.

  Example:
    > &BRIGHT_PEMIT #10=fn(pemit,%0,-->[ansi(h,%1)])
    > @function/delete PEMIT
    > @function PEMIT=#10,BRIGHT_PEMIT
    > think pemit(me,test)
    -->test   (in highlighted letters)

  To restrict the use of fn() to @functions only (to prevent players from skirting softcoded replacements), use @function/restrict fn=userfn.

  To prevent deleted functions from being used with fn(), @function/disable them prior to deleting.

  Continued in 'help fn2'.
& FN2
  If <obj> is specified, the built-in function will be executed as <obj>, rather than as the object which called fn(). This is useful when using fn() to replace a side-effect function, to ensure priviledge checks, etc, are done correctly. You must control <obj>, or (if function side effects are disabled) must be see_all.

  When an <obj> is given, debug information is automatically suppressed when evaluating the built-in function.

  Example:
    > &BRIGHT_PEMIT #10=fn(%@/pemit, %0, -->[ansi(h,%1)]))
    > @function/delete PEMIT
    > @function PEMIT=#10, BRIGHT_PEMIT
    > @lock/page *Mike=!=*Padraic

    (As Padraic)
    > think pemit(me,test)
    -->test  (in highlighted letters)
    > think pemit(*Mike,test)
    (nothing happens)

See also: @function, RESTRICT, attribute flags
& S()
& S-FUNCTION
  s(<string>)

  This function performs a second round of evaluation on <string>, and returns the result. It should be considered extremely dangerous to use on user input, or any other string which you don't have complete control over. There are very few genuine uses for this function; things can normally be achieved another, safer way.

  Example:
    > &test me=$eval *: say When we eval %0, we get [s(%0)]
    > eval \[ucstr(test)]
    You say, "When we eval [ucstr(test)], we get TEST"

See also: objeval(), decompose()
& SCAN()
  scan(<looker>, <command>[, <switches>])
  scan(<command>)

  This function works like @scan, and returns a space-separated list of dbref/attribute pairs containing $-commands that would be triggered if <command> were run by <looker>. You must control <looker> or be See_All to use this function. Only objects you can examine are included in the output.

  If no <looker> is specified, it defaults to the executor.

  <switches> is a space-separated list of strings to limit which objects are checked for $-commands. Valid switches are:
    room      --  check <looker>'s location and its contents
    me        --  check <looker>
    inventory --  check objects in <looker>'s inventory
    self      --  check <looker> and objects in <looker>'s inventory
    zone      --  check <looker>'s location's zone, and <looker>'s own zone
    globals   --  check objects in the Master Room
    all       --  all of the above (the default)
    break     --  once a match is found, don't check in other locations

  The order of searching for the "break" switch is the same as the order for normal $-command matching, as described in 'help evaluation order'.

See also: @scan, @sweep, MASTER ROOM, EVALUATION ORDER, $-COMMANDS
& SCRAMBLE()
  scramble(<string>)

  This function scrambles a string, returning a random permutation of its characters. Note that this function does not pay any attention to spaces or other special characters; it will scramble these characters just like normal characters.

  Example:
    > say scramble(abcdef)
    You say, "cfaedb"

See also: shuffle()
& SECS()
  secs()

  This function takes no arguments, and returns the number of elapsed seconds since midnight, January 1, 1970 UTC. UTC is the base time zone, formerly GMT. This is a good way of synchronizing things that must run at a certain time.

See also: convsecs(), time()
& SECURE()
  secure(<string>)

  This function returns <string> with all "dangerous" characters replaced by spaces. Dangerous characters are
    ( ) [ ] { } $ % , ^ ;
  Note that the use of this function is very rarely needed.

See also: decompose(), escape()
& SET()
  set(<object>[/<attribute>], <flag>)
  set(<object>, <attribute>:<value>)

  This function is equivalent to @set, and can be used to toggle flags and set attributes. The two arguments to the function are the same as the arguments that would appear on either side of the '=' in @set. This function returns nothing.

  The attribute-setting ability of set() is deprecated. You should use attrib_set() instead; it's easier to read, and allows you to clear attributes, too.

See also: attrib_set(), @set, wipe()
& SETDIFF()
  setdiff(<list1>, <list2>[, <delimiter>[, <sort type>[, <osep>]]])

  This function returns the difference of two sets -- i.e., the elements in <list1> that aren't in <list2>. The list that is returned is sorted. Normally, alphabetic sorting is done. You can change this with the fourth argument, which is a sort type as defined in 'help sorting'. If used with exactly four arguments where the fourth is not a sort type, it's treated instead as the output separator.

  Example:
    > say setdiff(foo baz gleep bar, bar moof gleep)
    You say, "baz foo"

See also: setinter(), setsymdiff(), setunion()
& SETSYMDIFF()
  setsymdiff(<list1>, <list2>[, <delimiter>[, <sort type>[, <osep>]]])

  This function returns the symmetric difference of two sets -- i.e., the elements that only appear in one or the other of the lists, but not in both. The list that is returned is sorted. Normally, alphabetic sorting is done. You can change this with the fourth argument, which is a sort type as defined in 'help sorting'. If used with exactly four arguments where the fourth is not a sort type, it's treated instead as the output separator.

  Example:
    > say setsymdiff(foo baz gleep bar, bar moof gleep)
    You say, "baz foo moof"

See also: setdiff(), setinter(), setunion()
& SETINTER()
  setinter(<list1>, <list2>[, <delimiter>[, <sort type>[, <osep>]]])

  This function returns the intersection of two sets -- i.e., the elements that are in both <list1> and <list2>. The list that is returned is sorted. Normally, alphabetic sorting is done. You can change this with the fourth argument, which is a sort type as defined in 'help sorting'. If used with exactly four arguments where the fourth is not a sort type, it's treated instead as the output separator.

  Example:
    > say setinter(foo baz gleep bar, bar moof gleep)
    You say, "bar gleep"

See also: setdiff(), setsymdiff(), setunion()
& SETQ()
& SETR()
  setq(<register1>, <string1>[, ... , <registerN>, <stringN>])
  setr(<register1>, <string1>[, ... , <registerN>, <stringN>])

  The setq() and setr() functions are used to copy strings into local registers assigned arbitrary names (Much like variables in other programming languages.) setq() returns a null string; it is a purely "side effect" function. setr() returns the value stored. Multiple registers can be assigned with a single setq() or setr(), with additional pairs of registers and values in the function's arguments. In this case, setr() returns the value stored in the first register listed. All arguments are evaluated before any registers are set; if you want to use the result of setting one register in setting another, use multiple setq()s.

  Registers set via setq() or setr() can be accessed via the r() function. Single-character registers can also be accessed via the %qN substitution, and ones with longer names via %q<NAME> (Note that the <>'s are required.) Attempting to access a register that hasn't been set results in an empty string.

  Register names are case insensitive: setq(A, foo) and setq(a, foo) both set the same register, and %qA and %qa both fetch its value.

  See 'help setq2' for more on limits, or 'help setq3' for examples.
See also: r(), listq(), unsetq(), letq(), localize(), ulocal(), registers()
& SETQ2
  Register names follow the same rules for attribute names, but they must be shorter than 64 characters in length.

  Register names other than a-z or 0-9 have a per-localize limit, defined with @config max_named_qregs. If setq or setr tries to set a named q-register and it exceeds the limit, it will return the string "#-1 TOO MANY REGISTERS". This is the only time setq will return a string. setq() and setr() with registers a-z or 0-9 have nothing to worry about.

  The maximum number of q-registers you can have set is configured via @config max_attrs_per_obj. That number is for the total number of q-registers set in a queue entry: Including across localize()d calls. Beyond that count, you can only use single character registers (a-z 0-9). Attempts to create a new register will simply fail silently, with the exception of setq().

  See 'help setq3' for examples.
& SETQ3
  The setq() function is probably best used at the start of the string being manipulated, such as in the following example:

    > &TEST object=strlen(%0)
    > &CMD object=$test *: say setq(0,u(TEST,%0))Test. %0 has length %q0.
    > test Foo
    Object says, "Test. Foo has length 3."

  In this case, it is a waste to use setq(), since we only use the function result once, but if TEST was a complex function being used multiple times within the same command, it would be much more efficient to use the local register, since TEST would then only be evaluated once. setq() can thus be used to improve the readability of MUSH code, as well as to cut down the amount of time needed to do complex evaluations.

  Swapping the contents of registers can be done without writing to temporary registers by setting both registers at once, so the code:

  > think setq(0,foo,one,bar)%q0%q<one> - [setq(0,r(one),one,%q0)]%q0%q<one>
  foobar - barfoo

  See 'help setq4' for scoping rules of setq().
& SETQ4
  The registers set by setq() can be used in later commands in the same thread. That is, the registers are set to null on all $-commands, ^-commands, A-attribute triggers, etc., but are then retained from that point forward through the execution of all your code. Code branches like @wait and @switch retain the register values from the time of the branch.

  Example:
    > say setr(what,foo); @wait 0=say %q<what>; say setr(what,bar)
    Object says "foo"
    Object says "bar"
    Object says "foo"
& LISTQ()
& UNSETQ()
  listq([<pattern>])
  unsetq([<pattern1> [<pattern2> [...]]])

  listq() returns a space-separated list of set q-registers with values available in the current q-register scope. If <pattern> is provided, then only those that match the wildcard pattern <pattern> will be returned.

  unsetq() without arguments clears all registers. Otherwise, unsetq() treats its argument as a list of register name patterns, and will unset all those registers within the local scope.

  If unsetq() is inside of a letq(), and does not have an argument, it will clear the registers that letq() has protected. unsetq() with arguments clears the specified registers.

  unsetq(<arg>) will clear all registers returned by listq(<arg>).

  Example:
    > think setq(name,Walker,num,#6061,loc,Bahamas)[listq()]
    LOC NAME NUM
    > think setq(name,Walker,num,#6061,loc,Bahamas)[listq(n*)]
    NAME NUM
    > think setq(name,Walker,num,#6061,loc,Bahamas)[unsetq(name)][listq()]
    LOC NUM
    > think setq(name,Walker,num,#6061,loc,Bahamas)[unsetq(n*)][listq()]
    LOC

See also: setq(), letq(), r(), localize(), registers()
& REGISTERS()
  registers([<pattern>[, <types>[, <osep>]]])

  The registers() function returns a list of the names of all existing registers of the specified <types>. <types> is a space-separated list containing zero or more of:

    qregisters - registers set with setq(), setr() and similar functions
    args       - %0-%9 arguments
    iter       - itext() context from iter() or @dolist
    switch     - stext() context from switch() or @switch
    regexp     - regexp capture names

  If <types> is empty, all types of registers are included. If <pattern> is specified, only registers whose name matches <pattern> will be included. The results are separated by <osep>, which defaults to a single space.

  The list returned may contain duplicates (for instance, if %0 and %q0 both have a value, the list will include "0" twice), and is not sorted in any particular order.

See also: listq(), setq(), setr(), letq(), r(), v(), stext(), itext()
& SETUNION()
  setunion(<list1>, <list2>[, <delimiter>[, <sort type>[, <osep>]]])

  This function returns the union of two sets -- i.e., all the elements of both <list1> and <list2>, minus any duplicate elements. The list returned is sorted. Normally, alphabetic sorting is done. You can change this with the fourth argument, which is a sort type as defined in 'help sorting'. If used with exactly four arguments where the fourth is not a sort type, it's treated instead as the output separator.

  Examples:
    > say setunion(foo baz gleep bar, bar moof gleep)
    You say, "bar baz foo gleep moof"

    > say setunion(1.1 1.0, 1.000)
    You say, "1.0 1.000 1.1"

    > say setunion(1.1 1.0, 1.000, %b, f)
    You say, "1.0 1.1"

See also: setdiff(), setinter(), setsymdiff()
& SHA0()
  sha0(<string>)

  Returns the SHA-0 cryptographic hash of the string. See RFC 3174 for more information. Deprecated; use digest() and higher strength algorithms instead. On servers with newer versions of OpenSSL that no longer provide the algorithm, returns #-1 NOT SUPPORTED.

See also: digest().
& SHL()
  shl(<number>, <count>)

  Performs a leftwards bit-shift on <number>, shifting it <count> times. This is equivalent to mul(<number>, power(2, <count>), but much faster.

See also: shr()
& SHR()
  shr(<number>, <count>)

  Performs a rightwards bit-shift on <number>, shifting it <count> times. This is equivalent to div(<number>, power(2, <count>), but much faster.

See also: shl()
& SHUFFLE()
  shuffle(<list>[, <delimiter>[, <osep>]])

  This function shuffles the order of the items of a list, returning a random permutation of its elements.

  <delimiter> defaults to a space, and <osep> defaults to <delimiter>.

  Example:
    > say shuffle(foo bar baz gleep)
    You say, "baz foo gleep bar"

See also: scramble(), pickrand()
& SIGN()
  sign(<number>)

  Essentially returns the sign of a number -- 0 if the number is 0, 1 if the number is positive, and -1 if the number is negative. This is equivalent to bound(<number>, -1, 1).

  Example:
    > say sign(-4)
    You say, "-1"

    > say sign(2)
    You say, "1"

    > say sign(0)
    You say, "0"

See also: abs(), bound()
& SIN()
  sin(<angle>[, <angle type>])

  Returns the sine of <angle>, which should be expressed in the given angle type, or radians by default.

  See 'HELP ANGLES' for more on the angle type.

See also: acos(), asin(), atan(), cos(), ctu(), tan()
& SORT()
  sort(<list>[, <sort type>[, <delimiter>[, <osep>]]])

  This sorts a list of words. If no second argument is given, it will try to detect the type of sort it should do. If all the words are numbers, it will sort them in order of smallest to largest. If all the words are dbrefs, it will sort them in order of smallest to largest. Otherwise, it will perform a lexicographic sort.

  The second argument is a sort type. See 'help sorting'.

  The optional third argument gives the list's delimiter character. If not present, <delimiter> defaults to a space. The optional fourth argument gives a string that will delimit the resulting list; it defaults to <delimiter>.

See also: sortby(), sortkey()
& SORTBY()
  sortby([<obj>/]<attrib>, <list>[, <delimiter>[, <output separator>]])

  This sorts an arbitrary list according to the ufun <obj>/<attrib>. This ufun should compare two arbitrary elements, %0 and %1, and return zero (equal), a negative integer (element 1 is less than element 2) or a positive integer (element 1 is greater than element 2), similar to the comp() function.

  A simple example, which imitates a normal alphabetic sort:
    > &ALPHASORT test=comp(%0,%1)
    > say sortby(test/ALPHASORT,foo bar baz)
    You say, "bar baz foo"

  A slightly more complicated sort. #1 is "God", #2 is "Amby", "#3" is "Bob":
    > &NAMESORT me=comp(name(%0),name(%1))
    > say sortby(NAMESORT,#1 #2 #3)
    You say, "#2 #3 #1"

  Warning: the function invocation limit applies to this function. If this limit is exceeded, the function will fail _silently_. List and function sizes should be kept reasonable.

See also: anonymous attributes, sorting, sort(), sortkey()
& SORTKEY()
  sortkey([<obj>/]<attrib>, <list>[, <sort type>[, <delimiter>[, <osep>]]])

  This function creates a list of keys by passing every element of <list> into the ufun given in <attrib>. The list is then sorted according to the sorting method in <sort type>, or is automatically guessed (as per 'help sorting').

  This is equivalent to:
    > &munge_sort me=sort(%0[, <sort type>])
    > say munge(munge_sort, map(<attrib>, <list>), <list>)

  Only there is no risk with delimiters occurring within the list.

  A simple example, which sorts players by their names:
    > @@ #1 is "God", #2 is "Amby", "#3" is "Bob"
    > &KEY_NAME me=name(%0)
    > say sortkey(key_name, #1 #2 #3)
    You say, "#2 #3 #1"

See also: anonymous attributes, sorting, sortby()
& SORTING
  In functions where you can specify a sorting method, you can provide one of these sort types:

  Type    Sorts:
   a       Sorts lexicographically (Maybe case-sensitive).
   i       Sorts lexicographically (Always case-insensitive).
   d       Sorts dbrefs.
   n       Sorts integer numbers.
   f       Sorts decimal numbers.
   m       Sorts strings with embedded numbers and dbrefs (as names).
   name    Sorts dbrefs by their names. (Maybe case-sensitive)
   namei   Sorts dbrefs by their names. (Always case-insensitive)
   conn    Sorts dbrefs by their connection time.
   idle    Sorts dbrefs by their idle time.
   owner   Sorts dbrefs by their owner dbrefs.
   loc     Sorts dbrefs by their location dbref.
   ctime   Sorts dbrefs by their creation time.
   mtime   Sorts dbrefs by their modification time.
   lattr   Sorts attribute names.

  The special sort key attr:<aname> or attri:<aname> will sort dbrefs according to their <aname> attributes. For example: Separating by &factions or &species attrs. attr is probably case-sensitive, and attri is case-insensitive.

  Prefixing the sort type with a minus sign, -, reverses the order of the sort.

  Whether or not the 'a' sort type is case-sensitive or not depends on the particular mush and its environment.

See also: sort(), sortby(), sortkey(), setunion(), setinter(), setdiff()
& SOUNDEX()
  soundex(<word>[, <hash type>])

  The soundex function returns the soundex pattern for a word. A soundex pattern represents the sound of the word, and similar sounding words should have the same soundex pattern. Soundex patterns consist of an uppercase letter and 3 digits.

  > think soundex(foobar)
  F160

  For details of how the algorithm works, see 'help soundex2'.

See also: soundslike()
& SOUNDEX2
  Here's how the soundex algorithm works:
  1. The first letter of the soundex code is the first letter of the word (exception: words starting with PH get a soundex starting with F)
  2. Each remaining letter is converted to a number:
      vowels, h, w, y ---------> 0
      b, p, f, v --------------> 1
      c, g, j, k, q, s, x, z --> 2
      d, t --------------------> 3
      l -----------------------> 4
      m, n --------------------> 5
      r -----------------------> 6
     At this stage, "foobar" is "F00106"
  3. Strings of the same number are condensed. "F0106"
  4. All 0's are removed, because vowels are much less important than consonants in distinguishing words. "F16"
  5. The string is padded with 0's or truncated to 4 characters. "F160"
  That's it. It's not foolproof (enough = "E520", enuf = "E510") but it works pretty well. :)

 The optional second argument can be 'soundex' (The default), for the transformation described above, or 'phone', for a different phonetic hash algorithm.
& SOUNDLIKE()
& SOUNDSLIKE()
  soundslike(<word>, <word>[, <hash type>])
  soundlike(<word>, <word>[, <hash type>])

  The soundslike function returns 1 if the two words have the same hash code (see 'help soundex()' for information), which means, in general, if they sound alike. The hash type can be 'soundex' (Default) or 'phone' for a different algorithm that might give better results with some words.

  Examples:
    > think soundslike(robin,robbyn)
    1
    > think soundslike(robin,roebuck, phone)
    0

See also: soundex()
& SPACE()
  space(<number>)

  Prints <number> spaces. Useful for times when you want to be able to use lots of spaces to separate things. Same as [repeat(%b, <number>)].

  Example:
    > say a[space(5)]b
    Amberyl says, "a     b"

See also: repeat()
& SPEAK()
& SPEAKPENN()
  speak(<speaker>, <string>[, <say string>[, [<transform obj>/]<transform attr>[, [<isnull obj>/]<isnull attr>[, <open>[, <close>]]]]])

  This function is used to format speech-like constructs, and is capable of transforming text within a speech string; it is useful for implementing "language code" and the like.

  If <speaker> begins with &, the rest of the <speaker> string is treated as the speaker's name, so you can use it for NPCs or tacking on titles (such as with @chatformat). Otherwise, the name of the object <speaker> is used.

  When only <speaker> and <string> are given, this function formats <string> as if it were speech from <speaker>, as follows.

  If <string> is...  the resulting string is...
  :<pose>            <speaker's name> <pose>
  ;<pose>            <speaker's name><pose>
  |<emit>            <emit>
  <speech>           <speaker's name> says, "<speech>"

  The chat_strip_quote config option affects this function, so if <speech> starts with a leading double quote ("), it may be stripped.

  If <say string> is specified, it is used instead of "says,".

  Continued in 'help speak2'.
& SPEAK2

  Examples:
    > say [name(me)]
    You say, "Wizard"

    > @emit [speak(me, :tests.)]
    Wizard tests.

    > @emit [speak(me, ;'s testing.)]
    Wizard's testing.

    > @emit [speak(me, |Test.)]
    Test.

    > @emit [speak(me, "Test.)]
    Wizard says, "Test."

    > @emit [speak(me, Test.)]
    Wizard says, "Test."

    > @emit [speak(me, Test., yells:)]
    Wizard yells: "Test."

    > @emit [speak(&Fido the Wonder Dog,:woofs!)]
    Fido the Wonder Dog woofs!

    > @emit [speak(&Mr. President,:has been misunderestimated.)]
    Mr. President has been misunderestimated.

  Continued in 'help speak3'.
& SPEAK3

  If <transform> is specified (an object/attribute pair or attribute, as with map() and similar functions), the speech portions of <string> are passed through the transformation function.

  Speech is delimited by double-quotes (i.e., "text"), or by the specified <open> and <close> strings. For instance, if you wanted <<text>> to denote text to be transformed, you would specify <open> as << and close as >> in the function call. Only the portions of the string between those delimiters are transformed. If <close> is not specified, it defaults to <open>.

  The transformation function receives the speech text as %0, the dbref of <speaker> as %1, and the speech fragment number as %2. For non-say input strings (i.e., for an original <string> beginning with the :, ;, or | tokens), fragments are numbered starting with 1; otherwise, fragments are numbered starting with 0. (A fragment is a chunk of speech text within the overall original input string.)

  Continued in 'help speak4'.
& SPEAK4

  Examples:
    > @va me="Fragment %2 is: %0"

    > @emit speak(me, test, ,va)
    Wizard says, "Fragment 0 is: test"

    > @emit speak(me, "test, ,va)
    Wizard says, "Fragment 0 is: test"

    > @emit speak(me, "test, yells:, va)
    Wizard yells: "Fragment 0 is: test"

    > @emit speak(me, :tests. "Hi.", ,va)
    Wizard tests. "Fragment 1 is: Hi."

    > @emit speak(me, ;'s testing. "Hi.", ,va)
    Wizard's testing. "Fragment 1 is: Hi."

    > @emit speak(me, |This is a test. "Hi.", ,va)
    This is a test. "Fragment 1 is: Hi."

    > @emit speak(me, :tests. "Hi." And... "Bye." The end., ,va)
    Wizard tests. "Fragment 1 is: Hi." And... "Fragment 2 is: Bye." The end.

    > @emit speak(me, :tests. "Hi." And... <<Bye.>> The end., ,va, , <<, >>)
    Wizard tests. "Hi." And... "Fragment 1 is: Bye." The end.

  Continued in 'help speak5'.
& SPEAK5

  If the result of transforming a given speech fragment is a null string, and <isnull> is specified (an object/attribute pair or attribute), that function is used evaluate an alternative result, with %0 as the dbref of <speaker>, and %1 as the speech fragment number.

  The <isnull> functionality can be useful for gracefully handling cases where speech may be processed down to nothing, such as with language code where no words are successfully translated.

  Consider this example, where the speech string may be randomly removed:

    > &MUTTER_FN me=if(rand(2),"%0",)
    > &NONE_FN me=capstr(subj(%0)) mutters something.
    > @emit speak(me, :tests. "Hello there.", mutters:, MUTTER_FN, NONE_FN)
    Wizard tests. "Hello there."
      OR
    Wizard tests. He mutters something.

  Continued in 'help speak6'.
& SPEAK6

  Elegantly handling an empty string when the type of speech is a plain say is a bit more difficult. In order to facilitate this, when the speech type is a plain say, the '<speaker> says,' is only prepended to the output if the transformation of the first speech fragment produces something non-null. Also note that quotes are not placed around such speech automatically, to allow the user's code to insert whatever is appropriate.

  Below is a more elegant version of the mutter example. Here, we find the use for say-speech fragments being numbered starting from 0 rather than 1 -- if the speech fragment number is 0, we know we haven't given any output yet.

    > &MUTTER_FN me=if(rand(2),"%0")
    > &NONE_FN me=switch(%1,0,name(%0),capstr(subj(%0)))] mutters something.
    > @emit speak(me, Hello there., mutters:, MUTTER_FN, NONE_FN)
    Wizard mutters: "Hello there."
      OR
    Wizard mutters something.

  Continued in 'help speak7'.
& SPEAK7

  Here's another example, where words between + signs are reversed, but those within double-quotes are untouched (demonstrating a technique useful in something where you want to allow users to mix ordinary speech with transformed speech).

    > &REV_FN me=switch(%2,0,backwards,capstr(subj(%1)) says backwards), "[revwords(%0)]"
    > @emit speak(me,:tests. "Normal speech." +Mixed up speech+ Success!,, REV_FN,,+)
    Wizard tests. "Normal speech." He says backwards, "speech up Mixed" Success!

& SPELLNUM()
  spellnum(<number>)

  Given a number, return its written-out representation in words.

  Example:
    > think spellnum(12345)
    twelve thousand three hundred forty-five

See also: ordinal()
& ORDINAL()
  ordinal(<integer>)

  Given an integer, return its written-out ordinal representation in words.

  Example:
    > think ordinal(1)
    first

See also: spellnum()
& SPLICE()
  splice(<list1>, <list2>, <word>[, <delimiter>])

  This function splices <list1> and <list2> together. <list1> and <list2> are space-separated lists of words.

  If a word in <list1> is the same as <word>, it is replaced by the word in the corresponding position in <list2>. Both lists must have the same
  number of words.

  Example:
    > say splice(foo bar baz,eek moof gleep,bar)
    You say, "foo moof baz"

See also: merge()
& MAPSQL()
  mapsql([<object>/]<attribute>, <query>[, <osep>[, <dofieldnames>]])

  Performs an SQL query if the MUSH is configured to connect to an SQL database server. This function requires a WIZARD flag or the Sql_Ok power.

  <query> is evaluated, so it's useful to either read it from another attribute with u() or use lit() to protect commas. If you will be interpolating user-provided values into the query, be careful to escape them with sqlescape().

  Each row of the result is passed to <attribute>, with the first nine columns available as %1-%9, and twenty more available via v(10) - v(29). %0 is set to the row number, which will start with 1. The fields will also be available as named arguments, with r(<field name>, args) returning the appropriate value.

  If <dofieldnames> evaluates to a true boolean, then the first call will be with row number (%0) set to 0, and %1-%9 and v(10) - v(29) will be set to the field names.

  See 'help sql examples' for examples.

See also: anonymous attributes, sqlescape(), sql(), @sql, @mapsql
& SQL()
  sql(<query>[, <row separator>[, <field separator>[, <register>]]])

  Performs an SQL query if the MUSH is configured to connect to an SQL database server. This function requires a WIZARD flag or the Sql_Ok power.

  By default, SELECT queries will return their data space-separated. Usually, it's more useful to specify a character to delimit rows returned (and sometimes another character to delimit the fields/columns returned, if they may contain spaces).

  <query> is evaluated, so it's useful to either read it from another attribute with u() or use lit() to protect commas. If you will be interpolating user-provided values into the query, be careful to escape them with sqlescape().

  A query that doesn't return any rows, such as an UPDATE or SELECT that has no matches will return a null string.

  If <register> is specified, and <query> alters the database (such as an UPDATE or INSERT query), there is a side-effect: the number of affected rows is stored into the specified q-register.

  See 'help sql examples' for examples.

See also: sqlescape(), mapsql(), @sql, setq(), r(), @mapsql
& SQL Examples

  Example of using sqlescape() to prevent injection attacks:
    > &SEL_GETID obj=SELECT id FROM mytable WHERE name = '[sqlescape(%0)]'
    > &DOIT obj=$do *: think setq(0,sql(u(SEL_GETID,%0),~,|)); @@ More cmds

  Using mapsql() to format results:
    > @@ Field, Type, Null?, Key?, Default, Extra
    > &each_row me=align(<15 <15 <5 <5 <10 <14,%1,%2,%3,%4,%5,%6)
    > &tabledesc me=mapsql(each_row,describe `[sqlescape(%0)]`,%r,1)
    > think u(tabledesc,quotes)
    Field           Type            Null  Key   Default    Extra
    quoteid         int(11)               PRI              auto_increment
    quote           text

    > &each_bb me=(%0) - %1 (%2)
    > &query me=SELECT `name`, count(*) AS `total` FROM `bbs` GROUP BY `name` ORDER BY `name`
    > think mapsql(each_bb, v(query), %r)
    (1) - Announcements (5)
    (2) - Advertisements (20)

  The same thing can be done using named arguments:
    > &each_bb me=(%0) - [r(name, args)] ([r(total, args)])

  Using sql() to update fields:
    > &update me=UPDATE `foo` SET `time` = '[sqlescape(%0)]' WHERE `loc` = '[sqlescape(%1)]'
    > &foo me=$foo *: think sql(u(update, %0, %L),,0)%q0 rows updated.
    > foo bar
    5 rows updated.

& SQLESCAPE()
  sqlescape(<string>)

  This function performs SQL-server-implemented escaping of <string>. It's important to escape arbitrary data before passing it to the sql() and mapsql() functions, or @sql command, to prevent SQL injection attacks.

  Example:
    > think sqlescape(You don't say)
    You don\'t say

    OR

    You don''t say


  When used in an SQL query, the results of an sqlescape() function should be enclosed in single quotes.

  You must be a WIZARD or have the Sql_Ok power to use this function.

See also: sql(), mapsql(), @sql, @mapsql
& SQRT()
  sqrt(<number>)

  Returns the square root of <number>. <number> cannot be negative.

See also: root()
& SQUISH()
  squish(<string>[, <character>])

  This function removes the leading and trailing <character>s from <string>, and condenses all inter-word <character>s to a single<character>. If no character is given, a space is used.

  Examples:

    > say squish(%b%bfoo bar%b%bbaz blech%b%b%beek%b)
    You say, "foo bar baz blech eek"
    > say squish(||a|| b|c|d|, |)
    You say, "a| b|c|d"

See also: trim()
& STARTTIME()
& RESTARTTIME()
  starttime()
  restarttime()

  starttime() returns the time the MUSH was last started, and restarttime() returns the time it was last restarted, including @shutdown/reboots. The times are in the same format as time().

  Example:
    > say starttime()%r[restarttime()]
    You say "Sat Dec  7 00:09:13 1991
    You say "Sat Dec  7 00:09:13 1991
    > @shutdown/reboot
    > say starttime()%r[restarttime()]
    You say "Sat Dec  7 00:09:13 1991
    Tue Sep 22 13:54:04 2015

See also: convtime(), restarts()
& RESTARTS()
  restarts()

  Returns the number of times the server has been rebooted with @shutdown/reboot since the last full startup.

See also: restarttime(), starttime()
& SSL()
  ssl(<player|descriptor>)

  This function returns 1 if the player is using an SSL connection, and 0 otherwise. If SSL connections are disabled, it always returns 0. You must be See_All to use this function on another player.

See also: terminfo()
& STEP()
  step([<obj>/]<attr>, <list>, <step>[, <delim>[, <osep>]])

  This function is similar to map(), except you can pass up to 30 elements of the list at a time, in %0-%9 and v(10)-v(29). <step> must be between 1 and 30, with a step of 1 equivalent to map(). If the elements of the list can't be split up evenly, the last evaluation will run with some of the registers unset; the %+ substitution or the registers() function can be used to see which/how many are set.

  Example:
    > &foo me=%0 - %1 - %2
    > think step(foo, a b c d e, 3,, %r)
    a - b - c
    d - e -

  Using registers() to avoid extra delimiters:
    > &foo me=iter(registers(,args),v(%i0),,%b-%b)
    > think step(foo, a b c d e, 3,, %r)
    a - b - c
    d - e

See also: map(), iter(), fold(), anonymous attributes, registers()
& STDDEV()
  stddev(<number1>, <number2>[, ... , <numberN>])

  Returns the sample standard deviation of its arguments.

See also: mean(), median(), lmath()
& STRFIRSTOF()
& STRALLOF()
  strfirstof(<expr>[, ... , <exprN>], <default>)
  strallof(<expr>[, ... , <exprN>], <osep>)

  strfirstof() returns the first <expr> which evaluates to a non-empty string (a string at least 1 character long). If all <expr>s evaluate empty, <default> is returned instead.

  strallof() returns all <expr>s which evaluate to non-empty strings, with each expression separated by <osep>.

  Examples:
    > say strfirstof(,  ,@@(Nothing),foo,default)
    You say, "foo"

    > say strfirstof(get(%#/fullname), u(%#/ansiname), %n)
    You say, "Mike"

    > say strallof(,  ,foo,@@(Nothing),%b,bar|baz,#-1,|)
    You say, "foo| |bar|baz|#-1"

See also: allof(), firstof(), first(), strlen(), cat(), default()
& STRINSERT()
  strinsert(<string>, <position>, <insert>)

  This function returns <string>, with <insert> added before the <position> character in <string>. Note that the first character in <string> is numbered 0, not 1.

  If <position> is less than 0, an error is returned. If <position> is greater than the length of <string>, <insert> is appended to it.

  Examples:
    > think strinsert(barbaz, 0, foo)
    foobarbaz
    > think strinsert(Myname, 2, %b)
    My name

See also: strdelete(), linsert(), strreplace()
& STRIPACCENTS()
  stripaccents(<string>[, <smart>])

  Returns the string with accented characters converted to non-accented. As with the accent() function, this assumes the ISO 8859-1 character set.

 If the second argument is true, it does more a intelligent conversion that might result in one character being turned into several. When it's false, or not given, one character in the input string corresponds to one character in the result.

See also: accent(), @nameaccent, accname(), stripansi(), render()
& STRIPANSI()
  stripansi(<string>)

  Returns the string with all ansi and HTML codes removed.

See also: stripaccents(), ansi(), tag(), render()
& STRLEN()
  strlen(<string>)

  Returns the length of the string (the number of characters in it).

  Example:
    > say strlen(foobar)
    You say, "6"

See also: words(), strfirstof()
& STRMATCH()
  strmatch(<string>, <pattern>[, <register list>])

  This function matches <pattern> against the entire <string>. It returns 1 if it matches and 0 if it doesn't. It is not case-sensitive, and <pattern> may contain wildcards.

  If <register list> is given, there is a side-effect: Wildcards and patterns are stored in q-registers, in the order they are given. <register list> is a space-separated list of register names.

  Examples:
    > say strmatch(Foo bar baz, *Baz)
    You say, "1"

    > say strmatch(Foo bar baz,*Foo)
    You say, "0"

    > say strmatch(Foo bar baz,*o*a*)
    You say, "1"

    > say strmatch(foo:bar,*:*,0 1)/%q0/%q1
    You say, "1/foo/bar"

    > say strmatch(foo:bar=baz,*:*=*,L1 L2 right)/%q<L1>/%q<L2>/%q<right>
    You say, "1/foo/bar/baz"

See also: comp(), match(), setq(), r()
& STRREPLACE()
  strreplace(<string>, <start>, <length>, <text>)

  Returns <string> with the <length> characters starting at <start> replaced by <text>. As with most other string functions, the first character is at position 0.

  If <start> is less than 0, an error is returned, and if <start> is greater than the length of <string>, <string> is returned.

  strreplace() attempts to preserve ansi: if <text> contains ansi, it will be kept the same. If <text> contains no ansi, but <string> does, <text> will be inserted with the same ansi as the text it replaces. To force <text> to be inserted with no ansi, even if <string> has ansi, wrap it in ansi(n,....).

  Examples:
    > say strreplace(abcXYZgh, 3, 3, def)
    You say, "abcdefgh"

    > think strreplace(Fix teh typo, 4, 3, the)
    Fix the typo

See also: strdelete(), strinsert(), ldelete(), lreplace()
& SUB()
  sub(<number1>, <number>[, ... , <number>])

  sub() subtracts <number> from <number1>. If more than one <number> argument is given, each is subtracted from the result of the previous subtraction in turn. The result of the final subtraction is returned.

See also: add(), dec(), lmath(), vsub()
& SUBJ()
& %s
  subj(<object>)

  Returns the subjective pronoun - he/she/it - for an object. You can also use the %s substitution to get the subjective pronoun of the enactor.

See also: aposs(), obj(), poss()
& RESWITCH()
& RESWITCHI()
& RESWITCHALL()
& RESWITCHALLI()
  reswitch(<str>, <re1>, <list1>[, ... , <reN>, <listN>][, <default>])
  reswitchall(<str>, <re1>, <list1>[, ... , <reN>, <listN>][, <default>])
  reswitchi(<str>, <re1>, <list1>[, ... , <reN>, <listN>][, <default>])
  reswitchalli(<str>, <re1>, <list1>[, ... , <reN>, <listN>][, <default>])

  These functions are just like switch() except they compare <string> against a series of regular expressions, not wildcard patterns.

  reswitch() and reswitchall() are case-sensitive.

  reswitch() and reswitchi() return the <list> which corresponds to the first matched <re>, while reswitchall() and reswitchalli() return the <list>s corresponding to all matched <re>s. If no <re>s match, all four functions return <default>.

  The string "#$" in the <list>s will be replaced with the value of <str>, /before/ <list> is evaluated. You can also use $N in <list> to refer to the Nth subpattern which matched in <re>, with $0 being the entire matching string. Use $<name> (the '<>' are literal) to refer to named subpatterns.

See also: switch(), regmatch(), regedit()
& SWITCH()
& SWITCHALL()
& CASE()
& CASEALL()
  switch(<str>, <expr1>, <list1>[, ... , <exprN>, <listN>][, <default>])
  switchall(<str>, <expr1>, <list1>[, ... , <exprN>, <listN>][, <default>])
  case(<str>, <expr1>, <list1>[, ... , <exprN>, <listN>][, <default>])
  caseall(<str>, <expr1>, <list1>[, ... , <exprN>, <listN>][, <default>])

  These functions match <string> against the <expr>essions, returning the corresponding <list>. If nothing is matched, the <default> is returned. switch() and case() return the <str> for the first matching <expr>, while switchall() and caseall() return the corresponding <list> for all <expr>s which match.

  switch() and switchall() use wildcard and lt/gt <expr>s, as described in 'help switch wildcards'. case() and caseall() do a case-sensitive exact match, like member() or comp(). In this case, $0-$9 will be set to the text that the nth wildcard character met.

  If the string "#$" appears in the <list> to be evaluated, it will be replaced with the evaluated value of <str> /before/ evaluation of <list>. This is not done in case() and caseall(), for TinyMUSH 3 compatibility. Note that this replacement happens before evaluation, which makes it unsafe when <str> contains user input, and makes it unsuitable for use in nested switch()es. It is strongly recommended you use the %$<n> substitution or stext() function instead, which solves these problems.

  See 'help switch2' for examples.

See also: reswitch(), stext(), slev(), if(), cond(), firstof()
& SWITCH2
  Examples:
    > say switch(test, *a*, foo, *b*, bar, *t*, neat, baz)
    You say, "neat"

    > say switchall(ack, *a*, foo, *b*, bar, *c*, neat, baz)
    You say, "fooneat"

    > say switch(moof, *a*, foo, *b*, bar, *t*, neat, baz)
    You say, "baz"

    > say switch(moof, *a*, foo, *b*, bar, *t*, neat, #$)
    You say, "moof"

    > say case(moof, *f, foo, moof, bar, baz)
    You say, "bar"

    > say switch(foo bazaar,f?o b*r,$0-$1)
    You say, "o-azaa"
& SWITCH WILDCARDS
  @switch, @select, switch() and switchall() normally do wildcard matching between their first argument and the <expr>ession arguments, with the normal * and ? special characters. However, if one of the <expr>essions starts with "<" or ">", a less than or greater than check is done instead of wildcard matching for that pair.

  switch(X, >Y, A, B) returns A if X is greater than Y, and B if it's not.
  switch(X, >=Y, A, B) returns A if X is greater than or equal to Y, and B if it's not.

  switch(X, <Y, A, B) returns A if X is less than Y, and B if it's not.
  switch(X, <=Y, A, B) returns A if X is less than or equal to Y, and B if it's not.

  If X and Y are numbers, the test is like using gt()/lt() or gte()/lte().

  If X and Y are non-numeric strings, the result of comp(X,Y) is used to determine which string is alphabetically before (less than) the other.

  If you need to have a leading < or > that's treated like a normal character in a wildcard match, use \\< or \\> (the \\ will turn into \ when the argument is evaluated, and then that single \ will stop the greater/less than check).

See also: WILDCARDS
& STEXT()
& SLEV()
& %$
& %$0
  slev()
  stext([<n>])
  %$<n>

  slev() returns the current nesting depth of switch*(), reswitch*() and @switch/@selects. stext() returns the <string> being matched for the current switch, or the <n>th switch where n=0 is the current switch, n=1 is the switch the current switch is nested in, and so on. It is a safer replacement for the "#$" token, which (because it is replaced before evaluation) is unsafe with user input, and unsuitable for use in nested switches.

  stext(L) returns the <string> for the outermost switch, and is equivilent to stext(slev()). %$<n> is equivilent to stext(<n>), for <n>s of 0-9 or L.

  Examples:
    > &cmd.whois me=$whois *: @pemit %#=switch(pmatch(%0),#-*, I don't know '%0', '%0' is %$0)
    > @switch foo=f*, say switch(bar, b*,%$1 %$0!)
    You say, "foo bar!"

See also: switch(), reswitch(), @switch
& T()
  t(<expression>)

  Returns 1 if <expression> is a true boolean value, and 0 otherwise. The definitions of true and false vary depending on the value of the 'tiny_booleans' @config option. See 'help boolean values' for details.

See also: not(), if(), cond(), @break, or(), and()
& TABLE()
  table(<list>[, <field width>[, <line length>[, <delimiter>[, <osep>]]]])

  This function returns the elements of <list> in a tabular format. All other parameters are optional. <field width> specifies how wide each table entry is allowed to be, and defaults to 10. If <field width> begins with a "<", it is left-aligned. ">" makes it right-aligned, and "-" makes it centered. Elements longer than <field width> are truncated to fit.

  <line length> is how wide a table row can be, and defaults to 78. <delimiter> is the delimiter used in <list>, and defaults to a space. <osep> is a single character to be used between entries in the table, and also defaults to a space.

  Examples:
    > think table(a b areallylongone d)
    a          b          areallylon d

    > think table(the quick brown fox, 10, 25, , |)
    the       |quick
    brown     |fox

See also: align()
& TAN()
  tan(<angle>[, <angle type>])

  Returns the tangent of <angle>, which should be expressed in the given angle type, or radians by default. See HELP ANGLES for more information.

See also: acos(), asin(), atan(), cos(), ctu(), sin()
& TEL()
  tel(<object>, <destination>[, <silent>[, <inside>]])

  This function will teleport <object> to <destination>, exactly as @teleport <object>=<destination>. <silent> is an optional boolean that, if true, makes the function act like @teleport/silent. <inside> is an optional boolean that, if true, makes the function act like @teleport/inside.

See also: @teleport
& TERMINFO()
  terminfo(<player|descriptor>)

  Returns a list with at least one element - the type of client used by the player, or "unknown" if the client being used doesn't support being asked to identify itself using RFC 1091.

  Other elements in the list describe client capabilities, and currently include:
  pueblo           present if the client is in Pueblo mode.
  telnet           present if the client understands the telnet protocol.
  gmcp             present if GMCP is negotiated via telnet; see help oob()
  ssl              present if the client is using an SSL/TLS connection.
  prompt_newlines  see 'help prompt_newlines'
  stripaccents     client is receiving 7-bit ascii, no accented characters

  One of the color styles shown in 'help colorstyle' will also be included.

  Other fields may be added in the future, if, for example, MXP support is ever added.

  You must have see_all, or use terminfo() on yourself, to see all information or use a <descriptor>. Mortals using terminfo() on another player will always receive "unknown" for the client name, and will not get telnet/gmcp/ssl/prompt_newlines in the output list.

See also: pueblo(), width(), height(), ssl(), @sockset, oob()
& OOB()
& GMCP
  oob(<player>, <package>[, <message>])

  This function sends an out-of-band message to <player> using the General MUD Communication Protocol (GMCP - http://www.gammon.com.au/gmcp). <package> is the name of the package/message type.

  You must be a wizard or have the Send_OOB power to send messages to anyone but yourself.

  If specified, <message> is a JSON-formatted message to be sent. Use the JSON() function to construct valid JSON.

  Returns the number of descriptors the message was sent to on success, or a string starting with #-1 on error.

See also: json()
& ISJSON()
  isjson(<text>)

  Return 1 if its argument is valid JSON, 0 if not.

  Examples:
  > think isjson(1)
  1
  > think isjson(true)
  1
  > think isjson(unquoted)
  0
  > think isjson("quoted")
  1

See also: json()
& JSON()
  json(<type>[, <data>[, ..., <dataN>])

  This function encodes <data> as a valid JSON (JavaScript Object Notation) message. <type> specifies the type of data to represent; valid <type>s and correspending <data>s are listed below.

  If any errors occur, json() returns a string starting with #-1.

  For <type>...   <data> should be...
  null            not given
  boolean         one arg, either "true", "1", "false" or "0"
  string          one arg, any string, including an empty string
  number          one arg, a valid number
  array           zero or more args, each themselves valid JSON
  object          zero or more pairs of arguments, the first a plain string (NOT a quoted JSON string), the second valid JSON of any type

  When <type> is "array" or "object", it's recommended that subsequent JSON arguments are created with nested calls to JSON().

  See 'help json2' for examples.
See also: oob(), isjson(), json_query(), json_map(), render()
& JSON2
  > think json(null)
  null

  > think json(string, Look\, it's "JSON"!)
  "Look, it's \"JSON\"!"

  > think json(array, json(number, pi()), json(string, Pie), json(bool, true))
  [3.141593, "Pie", true]

  > &oneobject me=json(object, name, json(string, name(%0)), dbref, json(string, %0), created, json(number, csecs(%0)))
  > think u(oneobject, #1)
  {"name": "One", "dbref": "#1", "created": 1431039583}

  > think json(array, u(oneobject, #0), u(oneobject, #1), u(oneobject, #2))
  [
   {"name": "Room Zero", "dbref": "#0", "created": 1431039583},
   {"name": "One", "dbref": "#1", "created": 1431039583},
   {"name": "Master Room", "dbref": "#2", "created": 1431039583}
  ]
& JSON_MAP()
  json_map([<object>/]<attribute>, <json>[, <osep>[, <arg>[, ..., <argN>]]])

  This function iterates over a JSON string, calling the specified <attribute> for each element of the JSON. If <json> represents a basic JSON type (null, boolean, string or number), the attribute will be called once. For arrays and objects, it will be called once for each element of the array/object.

  When the attribute is called, %0 will be the type of the json object and %1 will be the value. When <json> is an array, %2 will be the array position of the current element. For objects, %2 will be the label of the current element. You can pass user-specified arguments to the attribute; the first <arg> will be available as %3, the second as %4, and so on.

  <osep> defaults to a space.

  See 'help json_map2' for examples.
See also: json(), json_query()
& JSON_MAP2
  A very basic example:
  > &json me=We got [art(%0)] %0: %1

  > think json_map(me/json, "foo")
  We got a string: foo

  > think json_map(me/json, \["foo"\, 5\], %r)
  We got a string: foo
  We got a number: 5

  > think json_map(me/json, \["foo"\, \["bar"\, 10\]\], %r)
  We got a string: foo
  We got an array: ["bar",10]

  See 'help json_map3' for a more complex example.
& JSON_MAP3
  A JSON pretty-printer, using nested calls to json_map() to handle nested
  JSON objects/arrays:
  > &pretty_json me=u(me/pretty_json_sub,,%0,,0,strmatch(%0,\\{*))
  > &pretty_json_sub me=repeat(%t,%3)[if(%4,json(string,%2):%b)][switch(%1,\{*,\{%r[json_map(%=,%1,\,%r,inc(%3),1)]%r[repeat(%t,%3)]\},\[*,\[%r[json_map(%=,%1,\,%r,inc(%3),0)]%r[repeat(%t,%3)]\],json(%0,%1))]

  > &json me=[5, null, ["nested!", 999, {"foo":5, "bar":"\"Whee\""}], 7]
  > th u(me/pretty_json, v(json)
  [
      5,
      #-1,
      [
          "nested!",
          999,
          {
              "foo": 5,
              "bar": "\"Whee\""
          }
      ],
      7
  ]
& JSON_QUERY()
  json_query(<json>[, <action>[, <arg>, ...<argN>]])

  This function returns information about JSON data. <json> should be a valid JSON string, as returned by the json() function. There are 5 possible <action>s:

  Action...    Returns...
  type         The type of <json>, one of string, number, boolean, null, array or object. Default if no <action> is given.
  size         The size of <json>; this is 0 for null objects, 1 for strings/numbers/booleans, the number of array elements, or the number of key/value pairs for objects.
  exists       For arrays and objects, returns 1 if there is an object found by following the path specified in <arg>... and 0 if not. If the current arg is an integer and the current json element is an array, uses the <arg>th index of the array (Starting at 0) as the new current element. Otherwise, if the current json element is an object, treats the current <arg> as a key into the object and its value as the new current element.  Returns #-1 for other types.
  get          For arrays and objects, returns the json element found by following the path laid out in <args>... as described above. If no such element exists, returns an empty string. Returns #-1 for other JSON types.
  extract      Like get, but takes a single combined path arg as described in 'help json paths'. Some caveats: Returns 0 for false, 1 for true, and strings are unquoted.
  unescape     Only valid for JSON strings; returns the unescaped form of <json>.

  See 'help json_query2' for examples.
See also: json(), json_map()
& JSON_QUERY2
  Examples:

    > say json_query(true)
    You say, "boolean"

    > @set me=json:[json(array, "abc", "def", "gh\\"i")]
    > say v(json)
    You say, "["abc", "def", "gh\"i"]"

    > say json_query(v(json))
    You say, "array"
    > say json_query(v(json), size)
    You say, "3"
    > say json_query(v(json), get, 0)
    You say, ""abc""
    > say json_query(v(json), extract, $.\[2\])
    You say, "gh"i"
    > say json_query(json_query(v(json), get, 2), unescape)
    You say, "gh"i"

 See 'help json_query3' for more examples.
& JSON_QUERY3
 Examples:

    > @set me=json:[json(object, foo, "bar", baz, 12345, fnord, json(array, 1, 2, 3))]
    > say v(json)
    You say, "{"foo": "bar", "baz": 12345, "fnord": [1,2,3]}"
    > say json_query(v(json), exists, foo)
    You say, "1"
    > say json_query(v(json), exists, bar)
    You say, "0"
    > say json_query(v(json), get, baz)
    You say, "12345"
    > say json_query(v(json), get, fnord, 1)
    You say, "2"
    > say json_query(v(json), extract, $.fnord\[1\])
    You say, "2"
& JSON PATHS

  json_mod() and the extract argument for json_query() take a path string that describes what part of a JSON object or array to act on. All paths start with a $ to indicate the base JSON value, and 0 or more specifiers in the following formats:

  .FIELD - the name of a field in a JSON object.
  [N]    - the Nth element of a JSON array. Note that the brackets need to be escaped.

 See also: json_mod(), json_query()
& JSON_MOD()
  json_mod(<json>, <action>, <path>[, <json2>])

  Return a new JSON value based on applying <action> to <json>.

  insert - adds a new value <json2> at the given <path> if the data described by <path> doesn't exist.
  replace - replaces an existing value at the given <path> with <json2>.
  set     - Add or replace <json2> at the given <path>.
  patch   - Applies a merge patch (See https://tools.ietf.org/html/rfc7396) to <json> from <path>, which must be valid JSON.
  remove  - Removes the element from <json> pointed to by <path>
  sort    - Given a JSON array, sorts it based on the element at <path>.

  See 'HELP JSON_MOD2' for examples.
& JSON_MOD2
 Examples:

    > say json_mod(json(object, a,1,b,2), patch, json(object, a,42))
    You say, "{"a":43,"b":2}"

    > @set me=json:[json(object, foo, "bar", baz, 12345, fnord, json(array, 1, 2, 3))]
    > say v(json)
    You say, "{"foo": "bar", "baz": 12345, "fnord": [1,2,3]}"
    > say json_mod(v(json), set, $.foo, false)
    You say, "{"foo:false,"baz":12345,"fnord":[1,2,3]}"
    > say json_mod(v(json), insert, $.quux, 1)
    You say, "{"foo:"bar","baz":12345,"fnord":[1,2,3],"quux":1}"
    > say json_mod(v(json), replace, $.quux, 1)
    You say, "{"foo:"bar","baz":12345,"fnord":[1,2,3]}"
    > say json_mod(v(json), remove, $.fnord)
    You say, "{"foo":"bar","baz":12345}"
    > say json_mod(json(array, json(object, id, 2), json(object, id, 1), sort, $.id)
    You say, "[{"id":1},{"id":2}]
& TESTLOCK()
  testlock(<key>, <victim>)

  testlock() returns 1 if the <victim> would pass the lock defined in <key> as run by the caller, and 0 if it would fail.

  testlock() evaluates the lock from the caller's perspective.

  Example:
    > think testlock(TYPE^PLAYER&FLAG^WIZARD, *Gandalf)
    1
    > think testlock(TYPE^PLAYER&FLAG^WIZARD, *Bilbo)
    0

See also: @lock, lock(), elock(), lockfilter(), locktypes
& TEXTFILE()
& TEXTENTRIES()
& TEXTSEARCH()
& DYNHELP()
  textfile(<type>, <entry>)
  textentries(<type>, <pattern>[, <osep>])
  textsearch(<type>, <pattern>[, <osep>])

  textfile() returns the text of entries from cached text files (such as "help", "news", "events", etc.) All whitespace and newlines are included, so you may want to edit %r's and squish the result if you plan to use the text as a list of words rather than a display.

  textentries() returns any topic names which match the wildcard pattern <pattern>, with topic names separated by <osep>. These are the same topic names returned from "help <pattern>".

  textsearch() returns the names of all topics whose contents matches the given <pattern>, the same as "help/search <pattern>", with topic names separated by <osep>.

  Example:
    > say textentries(help, ?who())
    You say, "CWHO() LWHO() MWHO() NWHO() XWHO() ZWHO()"

    > say textsearch(help, pronouns, |)
    You say, "1.6.0P0|GENDER|SEX"

    > say textfile(help, ln\(\))
    You say, "  ln(<number>)

      Returns the natural log of <number>.

    See also: log()
    "
& TIME()
& UTCTIME()
  time()
  time(<timezone>)
  time(<dbref>)

  time() gives you the current time on the MUSH. By default this is the time on the server the MUSH is running on, and not the time of the caller.

  With an argument, time() returns the time in the specified timezone, or in the timezone set in the specified object's TZ attribute; for more information, see 'help timezones'.

  utctime() is an alias for time(utc).

Continued in HELP TIME2
& TIME2
  Examples (Assuming the server is the USA's Pacific timezone):

    > think utctime()
    Fri Mar 02 03:19:54 2012
    > think time(utc)
    Fri Mar 02 03:19:54 2012
    > think time()
    Thu Mar 01 19:19:54 2012
    > think time(-8)
    Thu Mar 01 19:20:25 2012
    > think time(US/Pacific)
    Thu Mar 01 19:20:25 2012

See also: timefmt(), timestring(), convsecs(), convtime(), TIMEZONES
& TIMECALC()
& SECSCALC()
 timecalc(<timestring>, <modifier>, ...)
 secscalc(<timestring>, <modifier>, ...)


 Takes a time and returns the resulting time after applying any modifiers. timecalc() returns a time is the same format as time(), and secscalc() as the seconds since the epoch. These functions can deal with a much broader range of times than the other time functions.

 <timestring> can be in the following formats:

  YYYY-MM-DD
  YYYY-MM-DD HH:MM
  YYYY-MM-DD HH:MM:SS
  YYYY-MM-DD HH:MM:SS.SSS
  HH:MM
  HH:MM:SS
  HH:MM:SS.SSS
  now (Current time in UTC)
  DDDDDDDDDD (Julian day, or seconds if followed by a unixepoch modifier)

Continued in HELP TIMECALC2
& TIMECALC2
 <modifier>s can be in the following formats:

  NNN days
  NNN hours
  NNN minutes
  NNN.NNNN seconds
  NNN months
  NNN years
  start of month
  start of year
  start of day
  weekday N
  unixepoch
  localtime (Converts a UTC time to local time)
  utc (Converts a local time to UTC)

  For details about what these formats and modifers mean, see https://www.sqlite.org/lang_datefunc.html

 Examples:
 > think timecalc(now, +100 years, localtime)
 Mon May 09 03:57:31 2118
 > think timecalc(secs(), unixepoch)
 Wed May 09 12:19:21 2018
& TIMEZONES
& @TZ

  The time(), timefmt() and convsecs() functions have an optional time zone argument that's used for formatting the time. Without this time zone specified, the one the game's server is running under is used.

  If the time zone argument is a dbref, the contents of that object's @TZ attribute is used as the zone. The attribute is not evaluated. If the object doesn't have this attribute, the server's time zone will be used.

  If it's the string 'UTC', that time zone is used instead of the local one. If it's a number between -24 and +24, it adds that many hours from UTC/GMT. Fractional times are supported, e.g., -1.5 hours.

  If the MUSH supports it (See @config compile), symbolic time zone names can also be used.

  valid(timezone, <tz>) tests if <tz> can be used as a timezone.

  See HELP TIMEZONES2 for a list of known time zones and HELP TIME2 for some examples.
& TIMEZONES2
  This is a list of IANA time zones names as of version 2011n of their database. See http://www.iana.org/time-zones for more information and sources.

  Africa/Abidjan                     Africa/Accra
  Africa/Addis_Ababa                 Africa/Algiers
  Africa/Asmara                      Africa/Asmera
  Africa/Bamako                      Africa/Bangui
  Africa/Banjul                      Africa/Bissau
  Africa/Blantyre                    Africa/Brazzaville
  Africa/Bujumbura                   Africa/Cairo
  Africa/Casablanca                  Africa/Ceuta
  Africa/Conakry                     Africa/Dakar
  Africa/Dar_es_Salaam               Africa/Djibouti
  Africa/Douala                      Africa/El_Aaiun
  Africa/Freetown                    Africa/Gaborone
  Africa/Harare                      Africa/Johannesburg
  Africa/Juba                        Africa/Kampala
  Africa/Khartoum                    Africa/Kigali
  Africa/Kinshasa                    Africa/Lagos
  Africa/Libreville                  Africa/Lome
  Africa/Luanda                      Africa/Lubumbashi
  Africa/Lusaka                      Africa/Malabo
  Africa/Maputo                      Africa/Maseru
  Africa/Mbabane                     Africa/Mogadishu
  Africa/Monrovia                    Africa/Nairobi
  Africa/Ndjamena                    Africa/Niamey
  Africa/Nouakchott                  Africa/Ouagadougou

Continued in HELP TIMEZONES3
& TIMEZONES3
  Africa/Porto-Novo                  Africa/Sao_Tome
  Africa/Timbuktu                    Africa/Tripoli
  Africa/Tunis                       Africa/Windhoek
  America/Adak                       America/Anchorage
  America/Anguilla                   America/Antigua
  America/Araguaina                  America/Argentina/Buenos_Aires
  America/Argentina/Catamarca        America/Argentina/ComodRivadavia
  America/Argentina/Cordoba          America/Argentina/Jujuy
  America/Argentina/La_Rioja         America/Argentina/Mendoza
  America/Argentina/Rio_Gallegos     America/Argentina/Salta
  America/Argentina/San_Juan         America/Argentina/San_Luis
  America/Argentina/Tucuman          America/Argentina/Ushuaia
  America/Aruba                      America/Asuncion
  America/Atikokan                   America/Atka
  America/Bahia                      America/Bahia_Banderas
  America/Barbados                   America/Belem
  America/Belize                     America/Blanc-Sablon
  America/Boa_Vista                  America/Bogota
  America/Boise                      America/Buenos_Aires
  America/Cambridge_Bay              America/Campo_Grande
  America/Cancun                     America/Caracas
  America/Catamarca                  America/Cayenne
  America/Cayman                     America/Chicago
  America/Chihuahua                  America/Coral_Harbour
  America/Cordoba                    America/Costa_Rica

Continued in HELP TIMEZONES4
& TIMEZONES4
  America/Cuiaba                     America/Curacao
  America/Danmarkshavn               America/Dawson
  America/Dawson_Creek               America/Denver
  America/Detroit                    America/Dominica
  America/Edmonton                   America/Eirunepe
  America/El_Salvador                America/Ensenada
  America/Fort_Wayne                 America/Fortaleza
  America/Glace_Bay                  America/Godthab
  America/Goose_Bay                  America/Grand_Turk
  America/Grenada                    America/Guadeloupe
  America/Guatemala                  America/Guayaquil
  America/Guyana                     America/Halifax
  America/Havana                     America/Hermosillo
  America/Indiana/Indianapolis       America/Indiana/Knox
  America/Indiana/Marengo            America/Indiana/Petersburg
  America/Indiana/Tell_City          America/Indiana/Vevay
  America/Indiana/Vincennes          America/Indiana/Winamac
  America/Indianapolis               America/Inuvik
  America/Iqaluit                    America/Jamaica
  America/Jujuy                      America/Juneau
  America/Kentucky/Louisville        America/Kentucky/Monticello
  America/Knox_IN                    America/Kralendijk
  America/La_Paz                     America/Lima
  America/Los_Angeles                America/Louisville
  America/Lower_Princes              America/Maceio

Continued in HELP TIMEZONES5
& TIMEZONES5
  America/Managua                    America/Manaus
  America/Marigot                    America/Martinique
  America/Matamoros                  America/Mazatlan
  America/Mendoza                    America/Menominee
  America/Merida                     America/Metlakatla
  America/Mexico_City                America/Miquelon
  America/Moncton                    America/Monterrey
  America/Montevideo                 America/Montreal
  America/Montserrat                 America/Nassau
  America/New_York                   America/Nipigon
  America/Nome                       America/Noronha
  America/North_Dakota/Beulah        America/North_Dakota/Center
  America/North_Dakota/New_Salem     America/Ojinaga
  America/Panama                     America/Pangnirtung
  America/Paramaribo                 America/Phoenix
  America/Port-au-Prince             America/Port_of_Spain
  America/Porto_Acre                 America/Porto_Velho
  America/Puerto_Rico                America/Rainy_River
  America/Rankin_Inlet               America/Recife
  America/Regina                     America/Resolute
  America/Rio_Branco                 America/Rosario
  America/Santa_Isabel               America/Santarem
  America/Santiago                   America/Santo_Domingo
  America/Sao_Paulo                  America/Scoresbysund
  America/Shiprock                   America/Sitka

Continued in HELP TIMEZONES6
& TIMEZONES6
  America/St_Barthelemy              America/St_Johns
  America/St_Kitts                   America/St_Lucia
  America/St_Thomas                  America/St_Vincent
  America/Swift_Current              America/Tegucigalpa
  America/Thule                      America/Thunder_Bay
  America/Tijuana                    America/Toronto
  America/Tortola                    America/Vancouver
  America/Virgin                     America/Whitehorse
  America/Winnipeg                   America/Yakutat
  America/Yellowknife                Antarctica/Casey
  Antarctica/Davis                   Antarctica/DumontDUrville
  Antarctica/Macquarie               Antarctica/Mawson
  Antarctica/McMurdo                 Antarctica/Palmer
  Antarctica/Rothera                 Antarctica/South_Pole
  Antarctica/Syowa                   Antarctica/Vostok
  Arctic/Longyearbyen                Asia/Aden
  Asia/Almaty                        Asia/Amman
  Asia/Anadyr                        Asia/Aqtau
  Asia/Aqtobe                        Asia/Ashgabat
  Asia/Ashkhabad                     Asia/Baghdad
  Asia/Bahrain                       Asia/Baku
  Asia/Bangkok                       Asia/Beirut
  Asia/Bishkek                       Asia/Brunei
  Asia/Calcutta                      Asia/Choibalsan
  Asia/Chongqing                     Asia/Chungking

Continued in HELP TIMEZONES7
& TIMEZONES7
  Asia/Colombo                       Asia/Dacca
  Asia/Damascus                      Asia/Dhaka
  Asia/Dili                          Asia/Dubai
  Asia/Dushanbe                      Asia/Gaza
  Asia/Harbin                        Asia/Hebron
  Asia/Ho_Chi_Minh                   Asia/Hong_Kong
  Asia/Hovd                          Asia/Irkutsk
  Asia/Istanbul                      Asia/Jakarta
  Asia/Jayapura                      Asia/Jerusalem
  Asia/Kabul                         Asia/Kamchatka
  Asia/Karachi                       Asia/Kashgar
  Asia/Kathmandu                     Asia/Katmandu
  Asia/Kolkata                       Asia/Krasnoyarsk
  Asia/Kuala_Lumpur                  Asia/Kuching
  Asia/Kuwait                        Asia/Macao
  Asia/Macau                         Asia/Magadan
  Asia/Makassar                      Asia/Manila
  Asia/Muscat                        Asia/Nicosia
  Asia/Novokuznetsk                  Asia/Novosibirsk
  Asia/Omsk                          Asia/Oral
  Asia/Phnom_Penh                    Asia/Pontianak
  Asia/Pyongyang                     Asia/Qatar
  Asia/Qyzylorda                     Asia/Rangoon
  Asia/Riyadh                        Asia/Riyadh87
  Asia/Riyadh88                      Asia/Riyadh89

Continued in HELP TIMEZONES8
& TIMEZONES8
  Asia/Saigon                        Asia/Sakhalin
  Asia/Samarkand                     Asia/Seoul
  Asia/Shanghai                      Asia/Singapore
  Asia/Taipei                        Asia/Tashkent
  Asia/Tbilisi                       Asia/Tehran
  Asia/Tel_Aviv                      Asia/Thimbu
  Asia/Thimphu                       Asia/Tokyo
  Asia/Ujung_Pandang                 Asia/Ulaanbaatar
  Asia/Ulan_Bator                    Asia/Urumqi
  Asia/Vientiane                     Asia/Vladivostok
  Asia/Yakutsk                       Asia/Yekaterinburg
  Asia/Yerevan                       Atlantic/Azores
  Atlantic/Bermuda                   Atlantic/Canary
  Atlantic/Cape_Verde                Atlantic/Faeroe
  Atlantic/Faroe                     Atlantic/Jan_Mayen
  Atlantic/Madeira                   Atlantic/Reykjavik
  Atlantic/South_Georgia             Atlantic/St_Helena
  Atlantic/Stanley                   Australia/ACT
  Australia/Adelaide                 Australia/Brisbane
  Australia/Broken_Hill              Australia/Canberra
  Australia/Currie                   Australia/Darwin
  Australia/Eucla                    Australia/Hobart
  Australia/LHI                      Australia/Lindeman
  Australia/Lord_Howe                Australia/Melbourne
  Australia/North                    Australia/NSW

Continued in HELP TIMEZONES9
& TIMEZONES9
  Australia/Perth                    Australia/Queensland
  Australia/South                    Australia/Sydney
  Australia/Tasmania                 Australia/Victoria
  Australia/West                     Australia/Yancowinna
  Brazil/Acre                        Brazil/DeNoronha
  Brazil/East                        Brazil/West
  Canada/Atlantic                    Canada/Central
  Canada/East-Saskatchewan           Canada/Eastern
  Canada/Mountain                    Canada/Newfoundland
  Canada/Pacific                     Canada/Saskatchewan
  Canada/Yukon                       CET
  Chile/Continental                  Chile/EasterIsland
  CST6CDT                            Cuba
  EET                                Egypt
  Eire                               EST
  EST5EDT                            Etc/GMT
  Etc/GMT+0                          Etc/GMT+1
  Etc/GMT+10                         Etc/GMT+11
  Etc/GMT+12                         Etc/GMT+2
  Etc/GMT+3                          Etc/GMT+4
  Etc/GMT+5                          Etc/GMT+6
  Etc/GMT+7                          Etc/GMT+8
  Etc/GMT+9                          Etc/GMT-0
  Etc/GMT-1                          Etc/GMT-10
  Etc/GMT-11                         Etc/GMT-12

Continued in HELP TIMEZONES10
& TIMEZONES10
  Etc/GMT-13                         Etc/GMT-14
  Etc/GMT-2                          Etc/GMT-3
  Etc/GMT-4                          Etc/GMT-5
  Etc/GMT-6                          Etc/GMT-7
  Etc/GMT-8                          Etc/GMT-9
  Etc/GMT0                           Etc/Greenwich
  Etc/UCT                            Etc/Universal
  Etc/UTC                            Etc/Zulu
  Europe/Amsterdam                   Europe/Andorra
  Europe/Athens                      Europe/Belfast
  Europe/Belgrade                    Europe/Berlin
  Europe/Bratislava                  Europe/Brussels
  Europe/Bucharest                   Europe/Budapest
  Europe/Chisinau                    Europe/Copenhagen
  Europe/Dublin                      Europe/Gibraltar
  Europe/Guernsey                    Europe/Helsinki
  Europe/Isle_of_Man                 Europe/Istanbul
  Europe/Jersey                      Europe/Kaliningrad
  Europe/Kiev                        Europe/Lisbon
  Europe/Ljubljana                   Europe/London
  Europe/Luxembourg                  Europe/Madrid
  Europe/Malta                       Europe/Mariehamn
  Europe/Minsk                       Europe/Monaco
  Europe/Moscow                      Europe/Nicosia
  Europe/Oslo                        Europe/Paris

Continued in HELP TIMEZONES11
& TIMEZONES11
  Europe/Podgorica                   Europe/Prague
  Europe/Riga                        Europe/Rome
  Europe/Samara                      Europe/San_Marino
  Europe/Sarajevo                    Europe/Simferopol
  Europe/Skopje                      Europe/Sofia
  Europe/Stockholm                   Europe/Tallinn
  Europe/Tirane                      Europe/Tiraspol
  Europe/Uzhgorod                    Europe/Vaduz
  Europe/Vatican                     Europe/Vienna
  Europe/Vilnius                     Europe/Volgograd
  Europe/Warsaw                      Europe/Zagreb
  Europe/Zaporozhye                  Europe/Zurich
  Factory                            GB
  GB-Eire                            GMT
  GMT+0                              GMT-0
  GMT0                               Greenwich
  Hongkong                           HST
  Iceland                            Indian/Antananarivo
  Indian/Chagos                      Indian/Christmas
  Indian/Cocos                       Indian/Comoro
  Indian/Kerguelen                   Indian/Mahe
  Indian/Maldives                    Indian/Mauritius
  Indian/Mayotte                     Indian/Reunion
  Iran                               Israel
  Jamaica                            Japan

Continued in HELP TIMEZONES12
& TIMEZONES12
  Kwajalein                          Libya
  MET                                Mexico/BajaNorte
  Mexico/BajaSur                     Mexico/General
  Mideast/Riyadh87                   Mideast/Riyadh88
  Mideast/Riyadh89                   MST
  MST7MDT                            Navajo
  NZ                                 NZ-CHAT
  Pacific/Apia                       Pacific/Auckland
  Pacific/Chatham                    Pacific/Chuuk
  Pacific/Easter                     Pacific/Efate
  Pacific/Enderbury                  Pacific/Fakaofo
  Pacific/Fiji                       Pacific/Funafuti
  Pacific/Galapagos                  Pacific/Gambier
  Pacific/Guadalcanal                Pacific/Guam
  Pacific/Honolulu                   Pacific/Johnston
  Pacific/Kiritimati                 Pacific/Kosrae
  Pacific/Kwajalein                  Pacific/Majuro
  Pacific/Marquesas                  Pacific/Midway
  Pacific/Nauru                      Pacific/Niue
  Pacific/Norfolk                    Pacific/Noumea
  Pacific/Pago_Pago                  Pacific/Palau
  Pacific/Pitcairn                   Pacific/Pohnpei
  Pacific/Ponape                     Pacific/Port_Moresby
  Pacific/Rarotonga                  Pacific/Saipan
  Pacific/Samoa                      Pacific/Tahiti

Continued in HELP TIMEZONES13
& TIMEZONES13
  Pacific/Tarawa                     Pacific/Tongatapu
  Pacific/Truk                       Pacific/Wake
  Pacific/Wallis                     Pacific/Yap
  Poland                             Portugal
  PRC                                PST8PDT
  ROC                                ROK
  Singapore                          Turkey
  UCT                                Universal
  US/Alaska                          US/Aleutian
  US/Arizona                         US/Central
  US/East-Indiana                    US/Eastern
  US/Hawaii                          US/Indiana-Starke
  US/Michigan                        US/Mountain
  US/Pacific                         US/Pacific-New
  US/Samoa                           UTC
  W-SU                               WET
  Zulu
& ETIME()
  etime(<seconds>[, <width>])

  This function formats a number of seconds using the same rules as the 'On for' and 'Idle' columens in WHO's output. The optional <width> argument controls the maximum size of the returned string.

  The elapsed time is split into years, weeks, days, hours, minutes and seconds fields. As many non-zero fields as can fit into <width> characters are used, in that order. If all fields are 0, seconds are displayed.

  Examples:
    > think etime(59)
    59s
    > think etime(60)
    1m
    > think etime(61)
    1m  1s
    > think etime(61, 5)
    1m

See also: etimefmt(), timestring(), stringsecs()
& ETIMEFMT()
  etimefmt(<format>, <secs>)

  This function is similar to timestring() - it formats a number of seconds into days, hours, minutes and seconds. However, its formatting is much more versatile than timestring(), as well as being more complex.

  Escape codes in <format> are replaced by the proper values, and other characters are left unchanged.

  A list of all codes is in 'help etimefmt2'.

  Examples:
    > say etimefmt(I have been connected for $2H:$2M., conn(%#))
    You say, "I have been connected for 01:32."
    > think etimefmt($2mm $2ss, 500) - [timestring(500)]
    8m 20s -  8m 20s

See also: timestring(), timefmt(), etime()
& ETIMEFMT2
  etimefmt()'s escape codes are similar to timefmt()'s. The time is broken up into days, hours, minutes, and seconds, and each value replaces the matching code.

  $s - The number of seconds.    $h - The number of hours.
  $m - The number of minutes.    $d - The number of days.
  $w - The number of weeks.      $y - The number of 365-day years.
  $$ - A literal $.

  You can also put a number between the $ and letter to specify a minimum width for the expanded code. The string is padded with spaces by default - use uppercase to pad with 0s instead ($3S, rather than $3s). An 'x' before the code (but after any number) will automatically add a d, h, m, or s suffix to the time, and a 'z' will not display anything if the field's value is 0. x and z can be combined.

 Normally, a particular time interval is shown using the remainder of the next largest interval - for example, $s with a time of 65 displays 5, not 65. The exception is $d, which only acts like this if $w or $y is also given. A 't' between the $ and code (But after a width) will print out the total seconds, minutes, etc. instead.

  See 'help etimefmt3' for more examples.
& ETIMEFMT3
  Examples:
    > think etimefmt($2h:$2M, 3700)
     1:01
    > think etimefmt(You have $m minutes and $s seconds to go, 78)
    You have 1 minutes and 18 seconds to go
    > think squish(etimefmt(Connected for $zxd $xzh $zxm $xzs, conn(me)))
    Connected for 5h 24m 45s
    > think etimefmt($txs is $xm$xs, 75)
    75s is 1m15s
& TIMEFMT()
  timefmt(<format>[, <secs>[, <timezone>]])

  This function returns the time and date, formatted according to <format>. <secs> is the time/date to format, as the number of seconds since the epoch (as returned by secs(), convtime(), etc). If no <secs> is given, the current date/time of the MUSH host is used. If no <timezone> is provided, the MUSH host's timezone is used; see 'help timezones' for valid formats for <timezone>. Note: Using a fractional timezone offset from GMT may result in timefmt() showing the time zone name (if displayed) as GMT. Using a symbolic name on a server that supports them should show the name correctly.

  A list of all codes for <format> is in 'help timefmt2'.

  Example:
    > think timefmt($A\, the $dth day of $B.)
    Monday, the 17th day of July.

See also: convsecs(), etimefmt(), timezones
& TIMEFMT2
  All escape codes start with a $. To get a literal $, use $$. Invalid codes will return #-1 INVALID ESCAPE CODE. Other text will be passed through unchanged.

  $a - Abbreviated weekday name  $p - AM/PM  ($P may also work)
  $A - Full weekday name         $S - Seconds after the minute
  $b - Abbreviated month name    $U - Week of the year from 1rst Sunday
  $B - Full month name           $w - Day of the week. 0 = Sunday
  $c - Date and time             $W - Week of the year from 1rst Monday
  $d - Day of the month          $x - Date
  $H - Hour of the 24-hour day   $X - Time
  $I - Hour of the 12-hour day   $y - Two-digit year
  $j - Day of the year           $Y - Four-digit year
  $m - Month of the year         $Z - Time zone
  $M - Minutes after the hour    $$ - $ character.
& TIMESTRING()
  timestring(<seconds>[, <pad flag>])

  The timestring function takes a number of seconds as input and returns the amount of time formatted into days, hours, minutes, and seconds. If <pad flag> is 1, all time periods will be used even if the number of seconds is less than a day, hour, or minute. If <pad flag> is 2, all numbers will be 2 digits long.

  Examples:
    > say timestring(301)
    You say, " 5m  1s"
    > say timestring(301,1)
    You say, "0d  0h  5m  1s"
    > say timestring(301,2)
    You say, "00d 00h 05m 01s"

See also: stringsecs(), convsecs(), etime(), etimefmt()
& STRINGSECS()
  stringsecs(<timestring>)

  The stringsecs() function takes a string of the form produced by timestring() or etime() and converts it back into seconds.

  Examples:
    > say stringsecs(5m 1s)
    You say, "301"

    > say stringsecs(3y 2m 7d 5h 23m)
    You say, "95232300"

See also: timestring(), etimefmt(), convtime(), etime()
& TR()
  tr(<string>, <find>, <replace>)

  This function translates every character in <string> that exists in <find> to the character at an identical position in <replace>. Ranges of characters separated by -'s are accepted. <find> and <replace> must be the same length after expansion of ranges. If a character exists more than once in <find>, only the last instance will be counted. The example below is the common ROT-13 algorithm for lower case strings, demonstrated with every letter explicitly listed, and with the equivalent but briefer character ranges. Literal -'s can be in <find> and <replace> if they are the first or last characters in the arguments.

   Examples:
     > say tr(hello,abcdefghijklmnopqrstuvwxyz,nopqrstuvwxyzabcdefghijklm)
     You say, "uryyb"
     > say tr(uryyb, a-z, n-za-m)
     You say, "hello"

See also: merge(), splice()
& TRIM()
& TRIMPENN()
& TRIMTINY()
  trim(<string>[, <characters to trim>[, <trim style>]])
  trimpenn(<string>[, <characters to trim>[, <trim style>]])
  trimtiny(<string>[, <trim style>[, <characters to trim>]])

  trim() strips leading and/or trailing occurrences of each of the <characters to trim> from <string>.

  <characters to trim> defaults to a space.

  If no <trim style> is specified, characters are trimmed from both the left and right sides of the string. If the 'l' trim style is specified, characters are only trimmed from the left side. If the 'r' trim style is specified, characters are only trimmed from the right side. If the 'b' trim style is specified, or a style is omitted, characters are trimmed off of both sides of the string.

  Normally, the arguments for trim() are in the same order as trimpenn(). However, if the tiny_trim_fun @config option is on, the <characters to trim> and <trim style> arguments are reversed. Use trimpenn() or trimtiny() if you want to specify a particular argument sequence no matter how the option is set.

  Examples:
    > say trim(%b%bfoo bar baz%b%b%beek%b%b)
    You say, "foo bar baz   eek"
    > say trim(***BLAM***,*)
    You say, "BLAM"
    > say trim(-----> WOW <---,-,r)
    You say, "-----> WOW <"
    > say trim(=~=~=~= Trim Test =~=~=~=,= ~)
    You say "Trim Test"

See also: squish(), edit()
& TRUNC()
& VAL()
  trunc(<string>)

  This function truncates floating point numbers to integers. It can also be used to return the leading numeric prefix of a string. If <string> does not start with a number, 0 is returned.

  Examples:
    > say trunc(3.141593)
    You say, "3"
    > say trunc(101Dalmations)
    You say, "101"

  val() is an alias for trunc().

See also: ceil(), floor(), bound(), round(), left()
& TYPE()
  type(<object>)

  This function returns the type of an object - one of PLAYER, THING, EXIT, ROOM or GARBAGE - or #-1 if the object can't be found.

  Examples:
    > @create Test
    > think type(Test)
    THING
    > think type(me)
    PLAYER
    > think type(here)
    ROOM

See also: hastype(), TYPES OF OBJECTS
& PFUN()
  pfun(<attribute>[, <arg0>[, ... , <arg29>]])

  This function evaluates <attribute> from the caller's @parent, passing up to 30 <arg>s as %0-%9 and v(10)-v(29). When the caller doesn't have an <attribute> attribute set, this is the same as

    ufun(me/<attribute>[, <args>])

  It differs from ufun() when the caller does have the attribute set - pfun() will ignore the attribute on the child, and evaluate the attribute as it would be inherited from the parent.

  Example:
    > @create ParentObject
    > @parent me=ParentObject
    > &foo me=ChildFoo
    > &foo ParentObject=ParentFoo
    > think ufun(me/foo)
    ChildFoo
    > think pfun(foo)
    ParentFoo

  Continued in 'help pfun2'.
& PFUN2
  This function does not have the security problems of using

    ufun(parent(me)/<attribute>)

  as the attribute is inherited (and evaluated by you, not the parent) - you don't need to be able to examine the parent object, and safer_ufun does not stop the evaluation. Note that no_inherit attribute flags are still checked, as with normal attribute inheritence.

  This function is particularly useful when you want to inherit an attribute tree from a parent, but add further branches.

  See 'help pfun3' for an example.

See also: ufun(), get(), parent(), zfun(), PARENTS
& PFUN3
  Example:

    > &root Parent=ParentRoot
    > &root`foo parent=ParentRoot`foo
    > think ufun(me/root) / [ufun(me/root`foo)]
    ParentRoot / ParentRoot`foo
    > &root`bar me=ChildRoot`bar
    > think ufun(me/root) / [ufun(me/root`foo)]
     / ParentRoot`foo

  Setting a ROOT`FOO attribute on the child automatically creates an empty ROOT attribute, which blocks the inherited ROOT attribute. The pfun() function allows you to get around this:

    > &root me=pfun(root)
    > think ufun(me/root) / [ufun(me/root`foo)] / [ufun(me/root`bar)]
    ParentRoot / ParentRoot`foo / ChildRoot`bar

  Good for inherited @chatformats which use CHATFORMAT`<channel> leaf attrs to store channel-specific formats and the like.
& U()
& UFUN()
& ULAMBDA()
  ufun([<object>/]<attribute>[, <arg0>[, ... , <arg29>]])
  ulambda([<object>/]<attribute>[, <arg0>[, ... , <arg29>]])

  ufun() evaluates <attribute> on <object> (or on the caller, if no <object> is given), and returns the result. Up to 30 <arg>s can be passed, available to the attribute as %0, %1, up to %9, and v(10) to v(29). This can be used to create "user defined functions".

  u() is an alias for ufun(), for TinyMUSH compatability.

  ulambda() is the same, but accepts anonymous attributes. See 'help lambda'.

  Continued in 'help ufun2'.
& U2
& UFUN2
  The attribute is evaluated by the object it's set on, with that object's priviledges, and NOT by the object using ufun(). Because of this, allowing arbitrary use of ufun() can be insecure.

  You must be able to examine an attribute to ufun() it. If the safer_ufun @config option is on, you must also have equal priviliges (in terms of mortal/Royalty/Wizard/God) to the object the attribute is on. However, attributes with the 'public' flag on can be evaluated by anyone. This is necessary for attributes like 'describe', but should not be set on attributes containing code unless you're sure it's safe for anyone to use them.

  Continued in 'help ufun3'.
& U3
& UFUN3
  Example:
    > &testcmd Object=$test *: say ufun(testfun, %0); @emit %0
    > &testfun object=[strlen(%0)] [ucstr(%0)]
    > test string
    Object says, "6 STRING"
    string

  A user-defined function may be as complex as you want it to be, subject to limits on recursion depth, number of function invocations, or cpu time that may be configured in the MUSH.

See also: anonymous attributes, udefault(), get(), ATTRIBUTES, ulocal(), pfun(), attribute flags, @include
& UCSTR()
& UCSTR2()
  ucstr(<string>)
  ucstr2(<string>)

  Returns <string> with all letters converted to uppercase.

  If the MUSH is compiled with ICU Unicode support, ucstr2() does the same thing except the returned string might be a different length, and ansi colors and other markup are stripped.

  Example:
    > say ucstr(Foo BAR baz)
    You say, "FOO BAR BAZ"
    > say ucstr2(grüßen)
    You say, "GRÜSSEN

See also: lcstr(), capstr()
& UDEFAULT()
& ULDEFAULT()
  udefault([<object>/]<attribute>, <default case>[, <arg0>[, ... , <arg29>]])
  uldefault([<object>/]<attribute>, <default case>[, <arg0>[, ... <arg29>]])

  If the given <attribute> on <object> (or the caller, if no <object> is given) can be read, the attribute is evaluated, and the result returned. Up to thirty <arg>s can be passed to the attribute, as per ufun().

  If the attribute cannot be read, <default case> is evaluated and returned instead. The <default case> is not evaluated if the attribute exists.

  uldefault() saves the global q-registers (%q0-%q9, %qa-%qz, etc) before evaluation, and restores them afterwards, as per ulocal().

  Examples:
    > &TEST me=center(%0,5,*)
    > say udefault(Test,-- BOOM --,ACK)
    You say "*ACK*"
    > &TEST me
    > say udefault(me/Test,-- BOOM --,ACK)
    You say "-- BOOM --"

See also: get(), eval(), ufun(), default(), edefault(), ulocal(), localize()
& ULOCAL()
  ulocal([<object>/]<attribute>[, <arg0>[, ... , <arg29>]])

  The ulocal() function is similar to ufun(); it evaluates <attribute> on <object> (or the caller, if no <object> is given), passing up to thirty <arg>s. However, before evaluating the attribute, ulocal() stores all the global q-registers (%q0-%q9, %qa-%qz), in the same way as the localize() function, and restores them after the attribute is evaluated. It's useful when you need to evaluate an attribute on an untrusted object which might alter the values of the registers.

  See 'help ulocal2' for examples.
& ULOCAL2
  Examples:
    > &FRUIT me=apples bananas oranges pears
    > &SUB-FUNCTION me=setq(0,v(FRUIT))[extract(%q0,match(%q0,%0),1)]
    > &TOP-FUNCTION me=setq(0,are delicious!)[ulocal(SUB-FUNCTION,%0)] %q0
    > say u(TOP-FUNCTION,b*)
    You say "bananas are delicious!"

  If SUB-FUNCTION had been called with u() instead of ulocal():
    > &TOP-FUNCTION me=setq(0,are delicious!)[u(SUB-FUNCTION,%0)] %q0
    > say u(TOP-FUNCTION,b*)
    You say "bananas apples bananas oranges pears"

  In this second example, in SUB-FUNCTION, %q0 was set to "apples bananas oranges pears", so that when the u() "returned" and TOP-FUNCTION evaluated %q0, this is what was printed. In the first example, ulocal() reset the value of %q0 to its original "are delicious!"

See also: ufun(), setq(), letq(), r(), localize()
& UNIQUE()
  unique(<list>[, <sort type>[, <delim>[, <osep>]]])

  unique() returns a copy of <list> with consecutive duplicate items removed. It does not sort the list. The optional <sort type> describes what type of data is in the list; see 'help sorting' for details. If no type is given, the elements are compared as strings. Elements of <list> are separated by <delim>, which defaults to a space. Each element of the output is separated by <osep>, which defaults to <delim>.

  Examples:
    > think unique(a b b c b)
    a b c b
    > think unique(1 2 2.0 3, f)
    1 2 3
    > think unique(1|2|3|3, n, |, _)
    1_2_3

See also: setunion(), sort()
& V()
& V-FUNCTION
  v(<variable>)
  v(<integer>)
  v(<attribute>)

  The first form of this function returns the value of the <variable> %-sub. In most cases, using the %-sub is preferable. Not all %-subs are accessible this way; only the following <variable>s are valid:

    0-9, #, @, !, n, l, and c.

  Unlike %-subs, the v() function is not case-sensitive: v(n) and v(N) are both equivilent to %n (whereas %N is equivilent to [capstr(%n)]).

  v() can also return the value of stack registers. v(0) is equivilent to %0, but v() can return up to 30 registers (v(0) through v(29)). Calling v() with an integer arg that is not between 0 and 29 (inclusive) will return an out-of-range error.

  The final form of this function is equivilent to get(me/<attribute>), but is usually slightly more efficient.

See also: STACK, REGISTERS, SUBSTITUTIONS, get(), r(), ATTRIBUTES
& VADD()
  vadd(<vector1>, <vector2>[, <delimiter>])

  Returns the sum of two vectors. A vector is a list of numbers separated by spaces or <delimiter>.

  > think vadd(1 2 3, 4 5 6)
  5 7 9
  > think vadd(0|0|0, 1|2|3, |)
  1|2|3

See also: VECTOR FUNCTIONS
& VALID()
  valid(<category>, <string>[, <target>])

  The valid() function checks to see if <string> can be used as a valid <category>, and returns 1 if so, 0 if not, and #-1 if an invalid category is used. For some categories, a <target> can be given to make the check more specific.

  The categories are:
   name        Test for a valid object name.
   attrname    Test for a valid attribute name.
   attrvalue   Test if <string> is a valid value for the attribute <target>. Meaningful for standard attributes with @attrib/enum or /limit.
   playername  Test if <target> could @name himself to <string>. <target> defaults to the caller.
   password    Test for a valid password.
   command     Test for a valid command name for @command/add.
   function    Test for a valid function name for @function.
   flag        Test for a valid flag/power name for @flag/add and @power/add
   qreg        Test for a valid name for a q-register.
   colorname   Test for a valid color name for ansi()/colors().
   ansicodes   Test for a valid color code sequence for ansi(<string>, ...).
   channel     Test for a valid channel name. If <target> is given, check to see if channel <target> could be renamed to <string>.
   timezone    Test for a valid timezone; see 'help timezones'
   locktype    Test for a valid locktype for @lock/<string> <target>. <target> defaults to the caller.
   lockkey     Test for a valid lockkey for @lock me=<string>

  Note that, for "playername", valid() returns 0 if the name is valid but currently in use by a player other than <target>.

  For "ansicodes", when not using new-style color names or hex codes, valid() always returns 1, and invalid codes are simply ignored, the same as when used in the ansi() function.

  See 'help valid2' for examples.
See also: colors(), ansi()
& valid2

  > think valid(name,Foobar)
  1
  > think valid(attrname,Foo bar)
  0

  A player can change his own name to a variation of his current name, but other players cannot:
  > think pmatch(Foobar)/%#
  #3/#4
  > think valid(playername, FOOBAR)
  0
  > think valid(playername, FOOBAR, #3)
  1

& VCROSS()
  vcross(<vector1>, <vector2>[, <delimiter>])

  Returns the 3-dimensional vector that is the cross product of its 3-dimensional argument vectors. The cross product is defined as:

   x = Ay * Bz - By * Az
   y = Az * Bx - Bz * Ax
   z = Ax * By - Bx * Ay

  > think vcross(4 5 6, 7 8 9)
  -3 6 -3

See also: VECTOR FUNCTIONS
& VDIM()
  vdim(<vector>[, <delimiter>])

  Returns the dimensionality of a vector.

  > think vdim(1 2 3 4)
  4

See also: VECTOR FUNCTIONS
& VDOT()
  vdot(<vector1>, <vector2>[, <delimiter>])

  Returns the dot product of two vectors. A dot product is the sum of the products of the corresponding elements of the two vectors, e.g. vdot(a b c,d e f) = ad + be + cf. The vectors must be of the same length.

  > think vdot(1 2 3, 2 3 4)
  20

See also: VECTOR FUNCTIONS
& VMIN()
  vmin(<vector1>, <vector2>[, <delimiter>])

  Returns a new vector made out of the minimums of each corresponding pair of numbers from the two vectors. The vectors must be of the same length.

  > think vmin(1 2 3, 4 1 2)
  1 1 2

See also: VECTOR FUNCTIONS
& VMAX()
  vmax(<vector1>, <vector2>[, <delimiter>])

  Returns a new vector made out of the maximums of each corresponding pair of numbers from the two vectors. The vectors must be of the same length.

  > think vmax(1 2 3, 4 1 2)
  4 2 3

See also: VECTOR FUNCTIONS
& VERSION()
& NUMVERSION()
  version()
  numversion()

  version() returns a string which contains various version information for the MUSH you're on. numversion() returns an integer representation of the version/patchlevel which can be used for softcode comparison.

  Example:
    > say version()
    You say "PennMUSH version 1.8.1 patchlevel 4 [12/06/2005]"
    > say numversion()
    You say "1008001004"

    > say version()
    You say, "PennMUSH version 1.8.5 patchlevel 7 [03/16/2015] (rev ebdea0a)"
    > say numversion()
    You say, "1008005007"

See also: @version
& VISIBLE()
  visible(<object>, <victim>[/<attribute>])

  If no attribute name is provided, this function returns 1 if <object> can examine <victim>, or 0, if it cannot. If an attribute name is given, the function returns 1 if <object> can see the attribute <attribute> on <victim>, or 0, if it cannot.

  If <object>, <victim>, or <attribute> is invalid, the function returns 0.

See also: controls(), VISUAL
& VMAG()
  vmag(<vector>[, <delimiter>])

  Returns the magnitude of a vector, using a Euclidean distance metric. That is, for vector a b c d, returns sqrt(a^2+b^2+c^2+d^2).

  > think vmag(3 4)
  5

See also: VECTOR FUNCTIONS
& VMUL()
  vmul(<vector1|number1>, <vector2|number2>[, <delimiter>])

  Returns the result of either multiplying a vector by a number, or the element-wise product of two vectors. The element-wise product of a b c by w x z is aw bx cz

  > think vmul(1 2 3, 2)
  2 4 6
  > think vmul(1 2 3, 2 3 4)
  2 6 12

See also: VECTOR FUNCTIONS
& VSUB()
  vsub(<vector1>, <vector2>[, <delimiter>])

  Returns the difference between two vectors.

  > think vsub(3 4 5, 3 2 1)
  0 2 4

See also: VECTOR FUNCTIONS
& VUNIT()
  vunit(<vector>[, <delimiter>])

  Returns the unit vector (a vector of magnitude 1), which points in the same direction as the given vector.

  > think vunit(2 0 0)
  1 0 0
  > think vmul(vunit(5 6 7), vmag(5 6 7))
  5 6 7

See also: VECTOR FUNCTIONS
& WIDTH()
& HEIGHT()
& SCREENWIDTH
& SCREENHEIGHT
  width(<player|descriptor>[, <default>])
  height(<player|descriptor>[, <default>])

  These two functions return the screen width and height for a connected player. If the player's client is capable of doing so, it will let the mush know what the correct sizes are on connection and when the client is resized.

  The defaults are 78 for width, and 24 for height, the normal minimal values. These can be overridden when calling the function by providing the default to the function. Players can change the value that will be returned when the functions are called on them with the special SCREENWIDTH and SCREENHEIGHT commands, both of which take a number as their sole argument, and set the appropriate field.

  When used on something that's not a visible player, the functions return the default values.

  The intent of these functions is allow softcode that does formatting to be able to produce a display that can make full use of any given screen size.
& WHERE()
  where(<object>)

  This function returns the "true" location of an object. This is the standard location (i.e. where the object is) for things and players, the source room for exits, and #-1 for rooms.

  In other words, the "true" location of an object is where it is linked into the database. For example, an exit appears in the room of its "home", not its "location" (the LOC() function on an exit
  will return the latter). A room's "real" location is always Nothing (the LOC() function will return its drop-to).

See also: room(), loc(), rnum(), locate(), home(), @whereis
& WIPE()
  wipe(<object>[/<attribute pattern>])

  This function is equivalent to @wipe, and attempts to wipe all the attributes on <object> whose names match <attribute pattern>, or "*" if no pattern is given. It returns nothing. Like @wipe, this function will destroy entire attribute trees; to safely remove a single attribute, use attrib_set() instead.

See also: @wipe, attrib_set(), set()
& WORDPOS()
  wordpos(<list>, <number>[, <delimiter>])

  Returns the number of the word within <list> where the <number>th character falls. Characters and words are numbered starting with 1, and <delimiter>s between words are treated as belonging to the word that follows them. If the list is less than <number> characters long, #-1 is returned. <delimiter> defaults to a space.

  Example:
    > say wordpos(foo bar baz, 5)
    You say, "2"

See also: member(), pos()
& WORDS()
  words(<list>[, <delimiter>])

  words() returns the number of elements in <list>. Elements of <list> are separated by <delimiter>, which defaults to a space.

  When the <delimiter> is a space, empty elements are not counted.

  Examples:
    > think words(1 2%b%b3, %b)
    3

    > think words(1|2||3, |)
    4

See also: strlen(), items()
& WRAP()
  wrap(<string>, <width>[, <first line width>[, <line separator>]])

  This function takes <string> and splits it into lines containing no more than <width> characters each. If <first line width> is given, the first line may have a different width. If <line separator> is given, it is inserted between each line; by default the separator is a newline (%r).

  Examples:
    > @desc here=wrap(Wrapped paragraph, 72)
    > @desc here=wrap([space(4)]Indented paragraph, 72)
    > @desc here=iter(wrap(Hanging indent, 72, 76, %r), switch(#@, >1, space(4))%i0, %r, %r)
& XATTR()
& XATTRP()
& REGXATTR()
& REGXATTRP()
  xattr(<object>[/<attribute pattern>], <start>, <count>[, <osep>])
  xattrp(<object>[/<attribute pattern>], <start>, <count>[, <osep>])
  regxattr(<object>[/<regexp>], <start>, <count>[, <osep>])
  regxattrp(<object>[/<regexp>], <start>, <count>[, <osep>])

  xattr() fetches <count> or fewer attribute names from <object> starting at position <start>. It is useful when the number of attributes on an object causes lattr() to exceed the buffer limit. The resulting list is separated by <osep>, which defaults to a space. <start> begins at 1.

  It is equivalent to
    extract(lattr(<object>[/<attribute pattern>]), <start>, <count>, <osep>)

  <attribute pattern> is a wildcard pattern which defaults to "*"; use "**" to get all attributes, including leaf attributes in trees. regxattr() matches attributes against the regular expression <regexp>.

  xattrp() and regxattrp() will include attributes from parents. Do note that parent attributes are listed _after_ child attributes, not sorted alphabetically.

See also: nattr(), lattr(), wildcards
& XOR()
  xor(<boolean1>, <boolean2>[, ... , <booleanN>])

  Takes two or more booleans and returns a 1 if one, and only one, of the inputs is equivalent to true(1).

See also: BOOLEAN VALUES, and(), or(), not(), nor(), lmath()
& XVCON()
& XCON()
  xcon(<object>, <start>, <count>)
  xvcon(<object>, <start>, <count>)

  xcon() fetches <count> or fewer item dbrefs from <object>'s contents starting at position <start>. It is useful when the number of objects in a container causes lcon() to exceed the buffer limit.

  It is equivalent to extract(lcon(<object>), <start>, <count>)

  xvcon() is identical, but follows the restrictions of lvcon().

See also: ncon(), lcon(), lvcon()
& XVEXITS()
& XEXITS()
  xexits(<room>, <start>, <count>)
  xvexits(<room>, <start>, <count>)

  xexits() fetches <count> or fewer exit dbrefs from <room> starting at position <start>. It is useful when the number of exits in a container causes lexits() to exceed the buffer limit.

  It is equivalent to extract(lexits(<room>), <start>, <count>)

  xvexits() is identical, but follows the restrictions of lvexits().

See also: nexits(), lexits(), lvexits()
& XVPLAYERS()
& XPLAYERS()
  xplayers(<object>, <start>, <count>)
  xvplayers(<object>, <start>, <count>)

  xplayers() fetches <count> or fewer player dbrefs from <object>'s contents starting at position <start>. It is useful when the number of players in a container causes lplayers() to exceed the buffer limit. It is equivalent to

    extract(lplayers(<object>), <start>, <count>)

  xvplayers() is identical, but follows the restrictions of lvplayers().

See also: nplayers(), lplayers(), lvplayers(), xthings(), xexits()
& XVTHINGS()
& XTHINGS()
  xthings(<object>, <start>, <count>)
  xvthings(<object>, <start>, <count>)

  xthings() fetches <count> or fewer non-player dbrefs from <object>'s contents starting at position <start>. It is useful when the number of things in a container causes lthings() to exceed the buffer limit. It is equivalent to:

    extract(lthings(<object>), <start>, <count>)

  xvthings() is identical, except it follows the restrictions of lvthings().

See also: nthings(), lthings(), lvthings(), xplayers(), xexits()
& XWHO()
& XWHOID()
& XMWHO()
& XMWHOID()
  xwho([<looker>, ]<start>, <count>)
  xmwho(<start>, <count>)
  xwhoid([<looker>, ]<start>, <count>)
  xmwhoid(<start>, <count>)

  xwho() fetches <count> or fewer player dbrefs from the list of connected players, starting at position <start>. It is useful when the number of players connected causes lwho() or pemits in +who $-commands to exceed buffer limits. If a <looker> is given, only includes players who <looker> can see are online. It is equivalent to:

    extract(lwho([<looker>]), <start>, <count>)

  xmwho() does not include hidden players (like mwho()).

  xwhoid() and xmwhoid() return objids instead of dbrefs.

See also: lwho(), mwho(), nwho(), zwho()
& ZWHO()
& ZMWHO()
  zwho(<object>[, <viewer>])
  zmwho(<object>)

  These functions return the dbrefs of all currently-connected players in locations @chzone'd to <object>. zmwho() does not include hidden players, while zwho() returns all players that the caller can see are online. You must be See_All or pass <object>'s @lock/zone to use these functions.

  See_All players can pass a <viewer> argument to zwho() to get only those players that <viewer> can see is online.

See also: lwho(), nwho(), zone(), zfun(), zemit()
& ZEMIT()
& NSZEMIT()
  zemit(<zone>, <message>)
  nszemit(<zone>, <message>)

  zemit() emits <message> in every room @chzone'd to <zone>, as per @zemit.

  nszemit() works like @nszemit.

See also: @zemit, zone(), zfun(), zwho(), ZONES
& ZFUN()
  zfun(<attribute>[, <arg0>[, <arg1>[, ... , <arg29>]]])

  This function evaluates an attribute on the caller's Zone object. It is essentially identical to

  ufun(zone(me)/<attribute>[, <arg0>[, ... , <arg29>]])

See also: ufun(), get(), zone(), zemit(), zwho(), ZONES
& ZONE()
  zone(<object>[, <new zone>])

  Returns <object>'s zone, or #-1 if it has no zone. You must be able to examine the object; if you can't, zone() returns #-1.

  If a <new zone> is given, zone() attempts to change the zone of <object> to <new zone> first - see help @chzone for details.

See also: @chzone, zfun(), zwho(), zemit() ZONES
& UPTIME()
  UPTIME([<type>])

  This function returns the time, as a number of seconds, that something happend (or will happen). Exactly what is returned depends on the given <type>, which should be one of:

    upsince   - The time the MUSH was started. This is the default.
    reboot    - The time the MUSH was last rebooted.
    save      - The time the MUSH last saved, or -1 if it hasn't.
    nextsave  - The time of the next automatic save.
    dbck      - The time of the next automatic dbck.
    purge     - The time of the next automatic purge.
    warnings  - The time of the next automatic warnings check, or -1 if automated warnings are disabled.

See also: @uptime, secs(), convsecs(), time(), starttime(), restarttime(), restarts(), @dbck, @purge, @warnings, @config, @dump, @shutdown
& SUGGEST()
  SUGGEST(<category>, <word>[, <seperator>[, <limit>]])

  Returns a list of suggested alternatives to <word> from vocabulary words known in the given <category>. <seperator> defaults to space. <limit> controls how many suggestions are returned, and defaults to 20.

 This is the same mechanism used to suggest help entries, function names, etc. when an unknown one is encountered.

 If the dict_file @config option is set, loads that file into the 'words' category.

 Example:
   > think suggest(words, ardvark)
   AARDVARK AARDVARKS AARDVARK'S etc...

See also: @suggest
& CONNLOG()
  CONNLOG(all|[not] logged in|<name>, <spec>...[, <sep>])

  If connection tracking is enabled, returns a list of connections that match the given <spec>. The format of the list elements is '<dbref> <unique-id>', with elements seperated by <sep> (Defaulting to |). <unique-id> is an identifier that can be used to get more information from the connection with connrecord().

  If the first argument is 'all', all connections are returned. If it's 'logged in', all connections that logged in are returned. 'not logged in' shows connections that never logged in. Otherwise, only connections for the given player are returned. If a connection that never logged in is returned, the dbref is #-1 for that record.

  <spec> is one or more of the following:

 + Time-based constraints
  * between, <startsecs>, <endsecs> - connections that were present during the given range.
  * at, <secs> - connections that existed at the given time.
  * before, <secs> - connections that existed before the given time.
  * after, <secs> - connections that existed after the given time.

See CONNLOG2 for more.
& CONNLOG2
+ Source-based constraits
  * ip, <pattern> - connections from IP addresses that match the wildcard <pattern>.
  * hostname, <pattern> - connections from hostnames that match the wildcard <pattern>.

 Only one time-based constraint can be used in a query.

 Times are the number of seconds since the epoch, like what secs() returns.

 This function is Wizard only.

 Example:
 > think connlog(logged in, after, secscalc(now, -15 minutes))
 shows all connections that were present during the last 15 minutes
 > think connlog(all, ip, 127.0.0.1)
 shows all connections ever made from localhost.

See also: connrecord()
& CONNRECORD()
 CONNRECORD(<id>[, <sep>])

  This Wizard-only function returns information about a connection if enhanced logging is enabled.

  <id> is a value returned by connlog(). connrecord() returns the following fields: DBREF NAME IPADDR HOSTNAME CONNECTION-TIME DISCONNECTION-TIME DISCONNECTION-REASON SSL WEBSOCKET. If the optional <sep> argument is given, it is used instead of space to seperate fields.

 If a single connection had multiple logins and logouts, only the last one is used. If a connection was never logged in, the DBREF field is #-1 and the NAME field is -. If the connection is still active, the DISCONNECTION-TIME is -1 and DISCONNECTION-REASON is -.

  Times are in seconds since the epoch, like what secs() returns.

See also: connlog()
& URLENCODE()
  URLENCODE(<string>)

  This function converts its argument to a URL-encoded string where everything but a-z, A-Z, 0-9, -, ., _, and ~ are converted into %NN where NN is a hex code for their character value.

See also: urldecode(), @http
& URLDECODE()
  URLDECODE(<string>)

  This function takes a URL-encoded string and returns it in its decoded form. Unprintable characters are converted to question marks.

See also: urlencode(), @http
& lockkeys
& lock keys

  There are many key types, and it is also possible to form more complex locks by using boolean symbols and grouping. See HELP @LOCK-COMPLEX for examples.

  The types of keys are outlined below. Detailed help for each is available by typing 'help @lock-<key>', replacing <key> with the word on the left.
  
  Simple     - Always true, always false, or locking to a specific object.
  Name       - Check the name of the object attempting to pass the lock.
  Owner      - Lock to objects owned by the owner of an object.
  Carry      - Lock to someone carrying an object, such as a key.
  Indirect   - Use the result of another @lock.
  Attribute  - Check an attribute on the object trying to pass the lock.
  Evaluation - Evaluate an attribute on the object the lock is on.
  Bit        - Check for a flag, type, power, or channel membership.
  Dbreflist  - Check if the dbref of the object trying to pass the lock is in a list set in an attribute.
  Host       - Check for players connecting from a particular host/ip.

  You can negate lock keys, and combine multiple keys, as explained in 'help lockkeys2'.
& lockkeys2
& lock keys2
& @lock-complex
  A lock key can be negated by prefixing the key with an "!". For example:
  
    > @lock North=flag^wizard
    > @lock South=!flag^wizard

  only lets those with the Wizard flag pass through the North exit, while only allowin those who do NOT have the Wizard flag to go South.
  
  You can combine keys, either allowing someone to pass a lock if they pass any of the keys given, or requiring that they pass all of the keys, using the "|" (or) and "&" (and) symbols. For example:
  
    > @lock OOC Room= status:OOC | power^guest
    
  locks the exit "OOC Room" so that only those with their STATUS attribute set to "OOC", or those with the Guest @power, can pass, while
  
    > @lock Men's Room= Sex:Male & +Bathroom Key
    
  only allows those with their @sex set to Male who are carrying a "Bathroom Key" object to pass.
  
  You can group together different sets of keys by enclosing each group in parenthesis "()". For instance,
  
    > @lock Entrance=!type^player | (type^player & !flag^unregistered)
    
  allows non-players to pass, or players who do not have the "unregistered" flag set.  
  
See also: @lock, locktypes, @clock, objid()
& @lock-simple
& @lock-objid
SIMPLE LOCKS

  You can lock an object in several different ways. The simplest lock is one that always succeeds (#true) or always fails (#false), or that matches a specific object by prefixing it with an "=":

   > @lock My Toy = #false
     This lock will always fail.

   > @lock My Toy = =me
     This locks the object "My Toy" to you and you alone. It is recommended that you @lock me = =me in order to prevent anyone else from picking you up. The two = signs are NOT a typo! The first is part of the @lock syntax (as shown at the top of 'help @lock') the second is a lock key that means "only this exact object".
  
  For backwards compatability, OBJID^<object> is an alias for =<object>.

& @lock-owner
& @lock-carry
OWNER LOCK

  An "owner" lock allows you to lock something to anything owned by the same player:
    @lock Box = $My Toy
  This locks "Box" to anything owned by the owner of "My Toy" (since players own themselves, that includes the owner as well).

CARRY LOCK
  You can lock an object to something that has to be carried:
    @lock Door = +Secret Door Key
      This locks the exit "Door" to someone carrying the object "Secret Door Key". Anyone carrying that object will be able to go through the exit.

  You can lock an object to -either- an object or to someone carrying the object with:
    @lock Disneyworld Entrance = Child
      This locks the exit "Disneyworld Entrance" to either the object "Child" -or- to someone carrying the object "Child". (OK, so it's a weird example.)
      
  This is the same as @lock Entrance=+Child|=Child.

& @lock-attribute
ATTRIBUTE LOCKS
  You can lock an object to an attribute on the person trying to pass the lock (as long as the object can "see" that attribute):

    @lock <object>=<attribute>:<value>

  <value> can contain wildcards (*), greater than (>) or less than (<) symbols.

  For example:
    @lock Men's Room = sex:m*
      This would lock the exit "Men's Room" to anyone with a SEX attribute starting with the letter "m".
    @lock A-F = icname:<g
      This would lock the exit "A-F" to anyone with a ICNAME attribute starting with a letter "less than" the letter "g". This assumes that ICNAME is visual or the object with the lock can see it.

& @lock-evaluation
EVALUATION LOCK
  An evaluation lock is set using this format:

    @lock <object>=<attribute>/<value>

  The difference between this and an attribute lock is that the <attribute> is taken from <object> rather than from the person trying to pass the lock. When someone tries, <attribute> is evaluated, and the result is compared to <value>. If it matches, then the person passes the lock.

  The person trying to pass the lock is %# and <object> is %! when the evaluation takes place. The evaluation is done with the powers of <object>. If you try to do something (like [get(%#/<attribute>)]) and <object> doesn't have permission to do that, the person will automatically fail to pass the lock.

  Continued in 'help @lock-eval2'.
& @lock-eval2
& @lock-evaluation2

  Example:
    @lock Thursday Cafe = whichday/Thu
    &whichday Thursday Cafe = first(time())
      This locks the object "Thursday Cafe" (probably an exit) unless today is Thursday.

      Whenever someone tries to pass through the exit, the attribute "whichday" will be evaluated, extracting the first word returned from time() (the day of the week). The result is compared with the value in the lock ("Thu"), and the lock will only be passable when the strings match--Only on Thursdays.

  If you have an evaluation lock that just does [hasflag(%#,FLAGNAME)], you should probably use a bit lock instead.

See also: @lock-bit
& @lock-name
NAME LOCKS
  You can test for objects matching a given name by using the below format

    @lock <object>=name^<pattern>

  It is similar to performing strmatch(%n,<pattern>), though will also match for a player/exit with <pattern> as one of its @aliases.

  For example, to lock "Bob's Tools" to only people with a name beginning with Bob:
    @lock/use Bob's Tools=name^bob*

& @lock-bit
& @lock-flag
& @lock-type
& @lock-power
& @lock-channel
BIT LOCKS
  You can test for set flags, powers, or object types in a lock directly, without using an evaluation lock, with these formats:

    @lock <object>=flag^<flag>
    @lock <object>=power^<power>
    @lock <object>=type^<type>

  These locks act like the object the lock is on does a hasflag(%#, <flag>), or haspower(%#, <power>), hastype(%#, <type>) succeeding only if the flag/power is set, or the object is of the specified type.

  For example,
    @lock/use Admin Commands=flag^wizard|flag^royalty

  You can also test for channel membership with:

    @lock <object>=channel^<channel>

& @lock-dbreflist
& @lock-list
LIST LOCK
  You can test to see if the enactor is a member of a space-separated list of dbrefs or objids on an attribute on the object, with:

    @lock <object>=dbreflist^<attributename>

  For example,
    &allow Commands = #1 #7 #23 #200:841701384
    &deny commands = #200 #1020
    @lock/use commands = !dbreflist^deny & dbreflist^allow 

& @lock-indirect
INDIRECT LOCKS
  An "indirect" lock allows you to lock something to the same thing as another object (very useful in setting channel locks; see help @clock):
    @lock Second Puppet=@First Puppet
      This locks the object "Second Puppet" to whatever the object "First Puppet" is locked to. Normally, the lock type that is checked is the same as the lock on the first. You can specify a different lock type with @object/LOCKNAME. For example:
    @lock Second Puppet = @First Puppet/Use
      Second Puppet's basic lock now checks First Puppet's use lock.

& @lock-host
HOST LOCKS

  You can check to make sure an object is owned by a player connected from a specific host or IP address using the following:
  
    @lock <object>=ip^<ipaddress>
    @lock <object>=hostname^<hostname>
    
  <ipaddress> and <hostname> can contain wildcards. <object> must be able to see the LASTIP attribute (for ip locks) or LASTSITE attribute (for hostname locks) on the enactor's owner.
  
  For example:
    @lock <object>=ip^127.0.0.1
      This locks <object> to players (and the objects of players) currently connected from the computer the MUSH is running on.
      
See also: ipaddr(), hostname(), LASTSITE
& locktypes
& locklist
& lock types
& lock list
  These are the standard lock types supported by PennMUSH. For more detailed information about any lock type, see "help @lock/<lock>".

  @lock/basic           Who can pick up the player/thing, or go through the exit.
  @lock/enter           Who can enter the player/object (aka @elock)
  @lock/teleport        Who can teleport to the room
  @lock/use             Who can use the object (aka @ulock)
  @lock/page            Who can page/@pemit the player
  @lock/zone            Who can control objects on this zone
  @lock/parent          Who can @parent something to this object/room
  @lock/link            Who can @link something to this object/room or who can @link this unlinked exit.
  @lock/open            Who can @open an exit from this room
  @lock/mail            Who can @mail the player
  @lock/user:<name>     User-defined. No built-in function of this lock, but users can test it with elock()

  Continued in 'help locktypes2'.
& lock types2
& locktypes2
  More standard lock types:

  @lock/speech          Who can speak/pose/emit in this room
  @lock/listen          Who can trigger my @ahear/^-pattern actions
  @lock/command         Who can trigger my $-pattern commands
  @lock/leave           Who can leave this object (or room, via exits/@tel)
  @lock/drop            Who can drop this object
  @lock/dropin          Who can drop objects into this location.
  @lock/give            Who can give this object
  @lock/from            Who can give things to this object
  @lock/pay             Who can give pennies to/buy from this object
  @lock/receive         What things can be given to this object
  @lock/follow          Who can follow this object
  @lock/examine         Who can examine this object if it's VISUAL
  @lock/chzone          Who can @chzone to this object if it's a ZMO
  @lock/forward         Who can @forwardlist a message to this object 
  @lock/filter          Controls if the message %0 should be filtered
  @lock/infilter        Controls if the message %0 should be infiltered
  @lock/control         Who can control this object (only if set; non-player)
  @lock/dropto          Who can trigger this container's drop-to.
  @lock/destroy         Who can destroy this object if it's DESTROY_OK
  @lock/interact        Who can send sound (say/pose/emit/etc) to this object
  @lock/take            Who can get things contained in this object
  @lock/mailforward     Who can forward mail to this object via @mailforward
  @lock/chown           Who can @chown this CHOWN_OK object?

See also: @lock, @lset, @clock, FAILURE
& @lock/basic
& @lock/enter
& @lock/leave
& @lock/teleport
  @lock/basic
    For exits, this lock controls who can pass through the exit.
    For players and things, it controls who can "get" the object.
    For rooms, it determines whether the @success or @failure verbs are triggered when someone "look"s at the room. However, even when the lock is failed, the "look" still occurs.
  See also: @success, @failure, goto, get, look
      
  @lock/enter
    For players and things, the Enter lock controls who can "enter" an ENTER_OK object, as well as who can "empty" it. It has no meaning for exits or rooms.
  See also: @enter, @efail, ENTER_OK, enter, empty
    
  @lock/leave
    For players, things and rooms, the Leave lock controls who can leave the object, via "leave", "@teleport" or "goto". It has no meaning for exits.
  See also: @leave, @lfail, leave
      
  @lock/teleport
    For rooms, the Teleport lock controls who can "@teleport" into the room, if it has the JUMP_OK flag set. It has no meaning for players, things or exits.
  See also: JUMP_OK, @teleport

See also: @lock, locktypes, lockkeys
& @lock/follow
& @lock/forward
& @lock/dropto
  @lock/follow
    For players and things, controls who may "follow" the object. Has no meaning for rooms or exits.
  See also: follow, FAILURE
    
  @lock/forward
    For players, things and rooms, controls who can forward sound to an object, via @forwardlist or @debugforwardlist. Meaningless for exits.
  See also: @forwardlist, @debugforwardlist, @lock/mailforward
  
  @lock/dropto
    For rooms, only objects which pass this lock will be sent to the rooms Drop-To. Has no meaning for players, things or exits.
  See also: DROP-TOS, drop, empty

See also: @lock, locktypes, lockkeys
& @lock/use
& @lock/command
& @lock/listen
  @lock/use
    For players, things and rooms, this lock controls who may "use" the object. You must also pass an object's Use lock to trigger $-commands or ^-listens on it (as well as the Command/Listen lock; see below). When an object is used as a Channel Mogrifier, only players who pass the object's Use lock will have their speech on the channel mogrified. Has no meaning for exits.
  See also: @use, @ufail, use, $-commands, ^, MOGRIFY
  
  @lock/command
    For players, things and rooms, you must pass this lock (as well as the Use lock) to trigger $-commands on the object. Meaningless for exits.
  See also: $-commands, FAILURE
    
  @lock/listen
    For players, things and rooms, you must pass this lock (as well as the Use lock) to trigger ^-listen patterns on the object when it's set MONITOR. Meaningless for exits.
  See also: ^
  
See also: @lock, locktypes, lockkeys
& @lock/page
& @lock/speech
& @lock/mail
& @lock/mailforward
& @lock/interact
  @lock/page
    For players, things and rooms, you must pass this lock to page or @pemit to the object, or @remit inside it. Meaningless for exits. 
  See also: FAILURE, @haven
  
  @lock/speech
    Controls who can speak (via say, pose, @*emit or teach) inside an object. Meaningless for exits.
  See also: FAILURE
  
  @lock/mail
    Controls who can send @mail to this object.
  See also: @mail, FAILURE
  
  @lock/mailforward
    Controls who can forward @mail to this object via @mailforward.
  See also: @mail, @mailforward, @lock/forward
  
  @lock/interact
    Controls whose indirect speech you'll hear (from say, pose, channels, @emit, etc). Does not block sound directed specifically at you, such as page, whisper, @pemit, etc; use @lock/page for those. Note that if sound is blocked by the interact lock, the speaker will not be informed.
  
See also: @lock, locktypes, lockkeys
& @lock/drop
& @lock/dropin
& @lock/give
& @lock/from
& @lock/pay
& @lock/receive
& @lock/take
  @lock/drop
    For players and things, controls who can drop the object. Has no meaning for exits. On rooms, has the same meaning as @lock/dropin
  See also: drop, empty

  @lock/dropin
    When set on a player, thing or room, controls who can drop objects into them. Has no meaning for exits.

  @lock/give
    For players and things, controls who may give the object away. Has no meaning for rooms or exits.
  
  @lock/from
    Controls who may give items to this object.
    
  @lock/pay
    Controls who can 'buy' an item from this vendor.
  
  @lock/receive
    Controls what may be given to this object.
  
  @lock/take
    Controls who can take from this container.
  
See also: give, buy, @lock/basic, @lock/enter
& @lock/filter
& @lock/infilter
  @lock/filter
  @lock/infilter
    These are lock versions of @filter and @infilter, respectively. Anyone who fails to pass the lock will have their speech filtered. The sound being made is passed to evaluation locks as %0.
  See also: @filter, @infilter
& @lock/control
& @lock/destroy
& @lock/examine
  @lock/control
    Allows objects which would not normally control something to do so. Does not work for players.
  See also: CONTROL
    
  @lock/destroy
    Limits who can @destroy a DESTROY_OK object.
  See also: @destroy, DESTROY_OK
  
  @lock/examine
    Limits who can examine a VISUAL object.
  See also: examine, VISUAL
& @lock/zone
& @lock/chzone
& @lock/chown
& @lock/parent
& @lock/link
& @lock/open
  @lock/zone
    Objects which pass a SHARED player's @lock/zone control all the objects the shared player owns. If the zone_control_zmp_only @config option is off, anything passing the @lock/zone of other objects will control everything @chzoned to the object.
  See also: @chzone, SHARED, ZONES, ZMR
  
  @lock/chzone
    If set, controls who can @chzone an object to this zone.
  See also: @chzone, ZONES

  @lock/chown
    If set, controls who can change the owner of this CHOWN_OK object via @chown.
  See also: CHOWN_OK, @chown

  @lock/parent
    Controls who can @parent something to this LINK_OK object.
  See also: @parent, LINK_OK
  
  @lock/link
    Controls who can @link this unlinked exit, or who can @link an exit to this LINK_OK room/thing.
  See also: @link, LINK_OK, LINK_ANYWHERE POWER
  
  @lock/open
    Controls who can @open an exit from this OPEN_OK room.
  See also: @open, @dig, OPEN_OK, OPEN_ANYWHERE POWER
& @lock/user
& @lock/user:<name>

  @lock/user:<name>
    User-defined locks have no hardcoded meaning. They allow you to set locks for any purpose, which you can test using the elock() function. <name> can be anything which is a valid attribute name. For example, in a combat system you might use a "wield" @lock on weapons, similar to

      > @lock/user:wield War Hammer=strength:>20
        
      and then test it with elock(War Hammer/wield, %#).
  See also: elock(), valid()
  
See also: @lock, locktypes, lockkeys
& mail
& @mail
  @mail[/<switches>] [<msg-list>[=<target>]]
  @mail[/<switches>] <player-list>=[<subject>/]<message>
 
  @mail invokes the built-in MUSH mailer, which allows players to send and receive mail. Pronoun/function substitution is performed on any messages you may try to send.

  A <msg-list> is one of the following:
        A single msg # (ex: 3)
        A message range (ex: 2-5, -7, 3-)
        A folder number and message number/range (ex: 0:3, 1:2-5, 2:-7)
        A sender (ex: *paul)
        An age of mail in days (ex: ~3 (exactly 3), <2, >1)
           "days" here means 24-hour periods from the current time.
        One of the following: "read", "unread", "cleared", "tagged", "urgent", "folder" (all messages in the current folder), "all" (all messages in all folders).

  Unless a folder is explicitly specified, or all is used, only messages in the current folder will be counted.

  A <player-list> is a space-separated list of recipients, which may be:
        Player names
        Player dbref #'s
        Message #'s, in which case you send to the sender of that message.
        An alias name (see help @malias)

  See also the following topics:    mail-sending   mail-reading   
      mail-folders   mail-forward   mail-other     mail-admin     
      @malias        mail-reviewing @mailquota
& mail-reading
& @mail/read
& @mail/list
& @mail/cstats
  @mail <msg #>
  @mail/read <msg-list>
        This displays messages which match the msg# or msg-list from your current folder.
  
  @mail
  @mail <msg-list, but not a single msg #> 
  @mail/list <msg-list>
        This gives a brief list of all mail in the current folder, with sender name, time sent, and message status.
        The status field is a set of characters (ex: NC-UF+) which mean:
                N = New (unread) message
                C = Cleared message
                U = Urgent message
                F = Forwarded message
                + = Tagged message
        The opposites of these (read messages, etc.) are indicated with a '-' in the status field in that position.

  @mail/cstats
        Shows how many messages you have, in the same format as the automatic mail check when you connect.
& mail-sending
& @mail/send
& @mail/fwd
  @mail[/switch] <player-list>=[<subject>]/<msg>
        This sends the message <msg> to all players in <player-list>.

        If no subject is given, the message subject is the beginning of the message itself. To include a literal / in the subject, double it up (//).

        All function substitutions are valid in <msg> including mail(#) which will allow you to forward mail you have received to other users.

        The following switches are available:
                /send   - same as no switch
                /urgent - mail is marked as "Urgent"
                /silent - no notification to sender that mail was sent
                /nosig  - no mail signature

        If you have an @mailsignature attribute set on yourself, its contents will be evaluated and appended to the message unless the /nosig switch is given.
 
  @mail/fwd <msg-list>=<player-list>
        This sends a copy of all the messages in <msg-list> to all the players in <player-list>. The copy will appear to have been sent by you (not the original sender), and its status will be "Forwarded".

& mail-other
& @mail/clear
& @mail/unclear
& @mail/purge
& @mail/tag
& @mail/untag
& @mail/unread
& @mail/status
  @mail/clear [<msg-list> | all]
  @mail/unclear [<msg-list> | all]
        These commands mark mail in the current folder as cleared or uncleared. Mail marked for clearing is deleted when you disconnect, or if you use @mail/purge. If no msg-list is specified, all mail in your current folder is cleared. If "all" is given instead of a msg-list, all mail in *all* folders is cleared/uncleared.
  
  @mail/purge
        Actually deletes all messages marked for clearing with @mail/clear. This is done automatically when you log out.

  @mail/tag [<msg-list> | all]
  @mail/untag [<msg-list> | all]
        These commands tag or untag mail in the current folder. Tagged mail can be later acted on en masse by using "tagged" as the msg-list for other commands (which does *not* untag them afterward). If no msg-list is specified, all messages in the current folder are tagged/untagged. If "all" is given as the msg-list, all mail in *all* folders is tagged/untagged. (Ex: To clear all mail from Paul and Chani, @mail/tag *paul, @mail/tag *chani, @mail/clear tagged, @mail/untag all).
        
  @mail/unread [<msg-list> | all]
        Mark messages which have already been read as new/unread.
        
  @mail/status [<msg-list> | all]=<status>
        Set the status of the given messages. <status> can be one of tagged, untagged, cleared, uncleared, read, unread, urgent or unurgent. Read marks a new message as read without reading it, urgent/unurgent toggle the urgent flag, and the others are equivilent to @mail/tag, @mail/untag, @mail/clear, @mail/unclear and @mail/unread respectively.
& mail-folders
& @mail/folder
& @mail/unfolder
& @mail/file
  The MUSH mail system allows each player 16 folders, numbered from 0 to 15. Mail can only be in 1 folder at a time. Folder 0 is the "inbox" where new mail is received. Most @mail commands operate on only the current folder.

  @mail/folder
        This commands lists all folders which contain mail, telling how many messages are in each, and what the current folder is.

  @mail/folder <folder#|foldername>
        This command sets your current folder to <folder#>.

  @mail/folder <folder#> = <foldername>
        This command gives <folder#> a name. 

  @mail/unfolder <folder#|foldername>
        This command removes a folder's name

  @mail/file <msg-list>=<folder#>
        This command moves all messages in msg-list from the current folder to a new folder, <folder#>.

See also: @mailfilter
& mail-reviewing
& @mail/review
& @mail/retract
  @mail/review [<player>]
        Reviews the messages you have sent to <player>, or all messages you've sent if no <player> is specified.
 
  @mail/review <player>=<msglist>
        Reads the messages you have sent to <player>.
 
  @mail/retract <player>=<msglist>
        Retracts (deletes) unread messages you have sent to <player>.
& @mailquota
  @mailquota <player>[=<limit>]
  
  This attribute allows wizards to change the maximum number of messages a player can have in their inbox, override the mail_limit @config option for specific people. <limit> should be a number between 1 and 50000, inclusive.

  Example:
    > @alias *Walker=Complaints_Department
    > @mailquota *Complaints_Department=50000
    > @wall Please @mail any and all problems to Complaints_Department.

& @mailfilter
& mailfilter
  The @mailfilter attribute specifies automatic filing of incoming @mail messages into folders. When an @mail message is received, the contents of @mailfilter are evaluated, with the following arguments passed:
     %0     dbref of message sender
     %1     message subject
     %2     message body
     %3     message status flags (a string containing U, F, and/or R, for urgent, forwarded, and/or reply, respectively)

  If @mailfilter evaluates to a folder name or number, the message will be filed into that folder. If @mailfilter evaluates to a null string, the message remains in the incoming folder.

  Example: Filter urgent messages into folder 1
  > @mailfilter me=if(strmatch(%3,*U*),1)

See also: mail-folders
& @mailsignature
& mailsignature
  @mailsignature <object>[=<signature>]
  
  When set, this attribute is evaluated and appended to any @mail messages sent by <object>, unless the @mail/nosig command is used.
  
  Example:
  > @mailsignature me=%r%r-- %n%r%r[u(funny_quote)]
  
See also: @mail, mail-sending
& mail-admin
  
  The @mail command can also take the following switches:
  
    @mail/stats [<player>]    --  Basic mail statistics.
    @mail/dstats [<player>]   --  Also provides read/unread count.
    @mail/fstats [<player>]   --  Does all that, plus gives space usage.
  
    @mail/debug <action>[=<player>]
    @mail/nuke
  
  Only wizards may stats players other than themselves.
  
  The /debug switch does sanity checking on the mail database, and may only be used by a wizard. "@mail/debug sanity" just does the check; the command "@mail/debug clear=<player name or dbref number>" wipes mail for an object. "@mail/debug fix" attempts to repair problems noted in the sanity check.

  The /nuke switch destroys the post office, erasing all @mail everywhere. It may only be used by God.
  
& @malias
  @malias [<alias>]

  The @malias command is used to create, view, and manipulate @mail aliases, or lists. An alias is a shorthand way of specifying a list of players for @mail. Aliases begin with the '+' (plus) prefix, and represent a list of dbrefs; aliases may not include other aliases.

  @malias with no arguments lists aliases available for your use, and is equivalent to @malias/list

  @malias with a single argument (the name of an alias) lists the members of that alias, if you're allowed to see them. Other forms of the same command are @malias/members <alias> or @malias/who <alias>

  Continued in 'help @malias2'.
& @malias2
  @malias[/create] <alias>=<player list>
  @malias/desc <alias>=<description>
  @malias/rename <alias>=<newalias>
  @malias/destroy <alias>

  The first form above creates a new alias for the given list of players.

  @malias/desc sets the alias's description, which is shown when aliases are listed.

  @malias/rename renames an alias.

  @malias/destroy destroys the alias completely.

  Continued in 'help @malias3'.
& @malias3
  @malias/set <alias>=<player list>
  @malias/add <alias>=<player list>
  @malias/remove <alias>=<player list>

  @malias/set resets the list of players on the alias to <player list>.

  @malias/add adds players to the alias. Note that the same player may be on an alias multiple times.

  @malias/remove removes players from the alias. If a player is on the alias more than once, a single remove will remove only one instance of that player.

  Continued in 'help @malias4'.
& @malias4
  @malias/use <alias>=<perm list>
  @malias/see <alias>=<perm list>

  @malias/use controls who may use an alias. Players who may use an alias will see it in their @malias list, and can @mail to the alias.

  @malias/see controls who may list the members of an alias.

  An empty permission list allows any player. The permission list may also be a space-separated list of one or more of "owner", "members" (of the alias), and "admin".

  By default, the owner and alias members may see and use the alias, but only the owner may list the members. Note that admin may always list aliases and their members, regardless of these settings, but are treated like anyone else when trying to @mail with an alias.

  Continued in 'help @malias5'.
& @malias5
  @malias/all
  @malias/stat
  @malias/chown <alias>=<player>
  @malias/nuke

  @malias/all is an admin-only command that lists all aliases in the MUSH.

  @malias/stat is an admin-only command that displays statistics about the number of aliases and members of aliases in use.

  @malias/chown is a wizard-only command that changes the owner of an alias.

  @malias/nuke is a God-only command that destroys all aliases.
& Mail functions
  Mail functions work with @mail.

  folderstats() mail()        maildstats()  mailfrom()    mailfstats()
  maillist()    mailsend()    mailstats()   mailstatus()  mailsubject()
  mailtime()    malias()
  
& FOLDERSTATS()
  folderstats()
  folderstats(<folder #>)
  folderstats(<player>)
  folderstats(<player>, <folder #>)

  folderstats() returns the number of read, unread, and cleared messages in a specific folder, or, if none is given, the player's current folder. Only Wizards may use forms which get other players' mail information.
  
See also: mailstats()
& MAIL()
  mail()
  mail(<player name>)
  mail([<folder #>:]<mail message #>)
  mail(<player>, [<folder #>:]<mail message #>)

  Without arguments, mail() returns the number of messages in all the player's mail folders. With a player name argument, mail() returns the number of read, unread, and cleared messages <player> has in all folders. Only Wizards can use this on other players.

  When given numeric arguments, mail() returns the text of the corresponding message in the current folder. The message number may also be prefaced by the folder number and a colon, to indicate a message in a different folder.

  Example: 
  > think mail(3:2)
  (text of the second message in the player's third folder)
  
See also: maillist(), mailfrom()
& MAILLIST()
  maillist([<player>, ]<message-list>)
  
  maillist() returns a list of all <player>'s @mail messages which match the given <message-list> (the same as @mail/list <message-list>). If no <player> is given, the executor's mail is matched. The <message-list> argument is described in 'help mail'.
  
  Examples:
    > think maillist()
    0:1 0:2 0:3
    > think maillist(all)
    0:1 0:2 0:3 1:1 1:2
    > think maillist(1:)
    1:1 1:2
    
See also: mail(), mailfrom()
& MAILFROM()
& MAILTIME()
& MAILSTATUS()
& MAILSUBJECT()
  mailfrom([<player>, ][<folder #>:]<mail message #>)
  mailtime([<player>, ][<folder #>:]<mail message #>)
  mailstatus([<player>, ][<folder #>:]<mail message #>)
  mailsubject([<player>, ][<folder #>:]<mail message #>)
 
  mailfrom() returns the dbref number of the sender of a mail message.
  mailtime() is similar, but returns the time the mail was sent.
  mailsubject() is similar, but returns the subject of the message.
  mailstatus() returns the mail's status characters (as per @mail/list).

See also: mail(), maillist()
& MAILSTATS()
& MAILDSTATS()
& MAILFSTATS()
  mailstats([<player>])
  maildstats([<player>])
  mailfstats([<player>])

  The mail*stats() functions return data like @mail/*stats does. You either must use this on yourself, or you must be a wizard. The information will be joined together as a space separated list of numbers.

  Example:
  > think mailstats(One)
  <# sent> <# received>
  > think mailfstats(One)
  <# sent> <# sent unread> <# sent cleared> <# sent bytes> <# received>
  <# received unread> <# received cleared> <# received bytes>

See also: folderstats()
& MAILSEND()
  mailsend(<player>,[<subject>/]<message>)

  This function sends a message to a player, just like @mail/send. It returns nothing if successful, or an error message.

& MALIAS()
  malias([<delimiter>])
  malias(<malias name>)
  malias(<malias name>[,<delimiter>])

  With no arguments, malias() returns the list of all malias names which are visible to the player. With two arguments, returns the list of dbrefs that are members of the given malias, delimited by <delimiter>.

  With one argument, the behavior is ambiguous. If the argument matches a malias, returns the list of dbrefs that are memebrs of the malias, space-delimited. If not, it's treated as a no-argument case with a delimiter.
& mail-forward
& @mailforwardlist
  @mailforwardlist <object>[=<space-separated list of dbrefs or objids>]
  @lock/mailforward <object>[=<lock>]
 
  By setting a @mailforwardlist attribute, a player can direct that @mail they receive should be delivered to the specified list of dbrefs of other players. The list may include the player's own dbref, in which case the player will receive a copy of the message, or omit it, in which case the message will be delivered to those listed but the player will not receive a copy.

  To deliver messages to other players this way, you must control them (i.e. you're delivering to yourself or you're a wizard) or pass their @lock/mailforward. An empty @lock/mailforward disallows forwarding to you, and is the default.
& PUEBLO
  Pueblo is a client made by Chaco (a now defunct company). It attempts to mix HTML with MUSH. There are other clients (notably MUSHclient) that also offer Pueblo features. PennMUSH can offer support for some of the enhanced features of Pueblo, enabled via the 'pueblo' @config option.

  PennMUSH will automatically detect a Pueblo client (rather, the client will announce itself and PennMUSH will detect that), and set up that connection for Pueblo use. 

Continued in 'help pueblo2'.
& PUEBLO2
  PennMUSH makes the following enhancements visible to Pueblo users when Pueblo support is enabled:

    * Object/Room names are highlighted
    * Support for VRML graphics
    * Unordered list for contents and transparent exits
    * Contents and exits lists have links (Click an exit to walk through it)
    * Object lists (like the ones found in 'examine'/'inventory') have links
    * Conversion of accented characters into &entity; codes

  While Pueblo brings a number of new features and markups to MUSHes, in many ways it's not well suited. Because it's based on HTML, multiple spaces are compressed, and Pueblo typically defaults to a variable width font. Because of this, supporting Pueblo is not just a matter of enabling the option. The output of any commands which rely on fixed spacing, such as a +who, must be wrapped in <pre> tags to ensure they appear correctly for players using Pueblo. For instance:
  
    > &cmd`who Globals=$+who: @nspemit %#=tagwrap(pre, u(fun`who))

See also: pueblo(), HTML Functions
& HTML
  Hyper Text Markup Language (http://www.w3.org)

  The only HTML implementation supported by the MUSH is the one supported by Pueblo (see 'help pueblo' for more info). To utilize HTML, use one of the MUSH HTML Functions (see 'HTML Functions' for a list).

  HTML tags are stripped when sent to non-HTML capable players.

See also: HTML Functions, PUEBLO, html()
& PUEBLO()
  pueblo(<player|descriptor>)
  
  This function returns 1 if the given player or descriptor is currently Pueblo-enabled, and 0 otherwise. 
  
  If used on a player/descriptor which is not connected, pueblo() returns #-1 NOT CONNECTED. Mortals can only give a <descriptor> for their own connections (but can give any <player> arg), while See_All objects can check any descriptor.
  
  When used with a <player> argument, the most recently active connection is used if the <player> is logged in more than once.
  
See also: terminfo(), html(), PUEBLO
& @VRML_URL
& VRML_URL
& VRML
  @vrml_url <object>[=<url>]

  The VRML_URL attribute provides an object (usually a room) with a VRML world. When someone using a Pueblo-enabled client looks at the object, the VRML World listed in @VRML_URL will be loaded.

  Example:
  > @vrml_url here=http://www.pennmush.org/pennmush.vrml

  To learn about the VRML Format, have a look at the Pueblo Help, which mentions several good sites for learning.

See also: HTML, PUEBLO
& HTML FUNCTIONS
  HTML Functions are used to output HTML tags to HTML capable users. These tags will be stripped by the system for anything non-HTML related. These functions are only available when Pueblo support is enabled (see '@config pueblo').

  html()         tag()          endtag()       tagwrap()

  Examples:
    > say html(a href="http://www.pennmush.org")PennMUSH[html(/a)]
    > say tag(a,href="http://www.pennmush.org")PennMUSH[endtag(a)]
    > say tagwrap(a,href="http://www.pennmush.org",PennMUSH)

  Each of these produces the HTML output:
    <a href="http://www.pennmush.org">PennMUSH</a>

  Mortals are restricted in the tags they may use. Most standard HTML tags are ok; protocol-specific tags like SEND and XCH_CMD can only be sent by Wizards or those with the Send_OOB @power.
& HTML()
  html(<string>)

  This wizard-only function will output <string> as an HTML Tag.

  Example:
    > think html(b)Foo[html(/b)]

  Will output (in HTML):
    <b>Foo</b>

  Non-wizards should see the tag(), endtag(), and tagwrap() functions, which are similar but can be used by mortals.
  
See also: PUEBLO, HTML, HTML Functions
& TAG()
  tag(<name>[, <param1>[, ... , <paramN>]])

  This function outputs the named HTML/Pueblo tag with the given paramaters.

  Example:
   tag(img,src="http://www.pennmush.org/image.jpg",align="left",width="300")

  Will output (in HTML):
    <img src="http://www.pennmush.org/image.jpg" align="left" width="300">

See also: endtag(), tagwrap(), html()
& ENDTAG()
  endtag(<name>)

  Outputs a closing HTML/Pueblo tag for the named tag.

  Example:
   endtag(b)

  Will output (in HTML):
   </b>

See also: tag(), tagwrap(), html()
& TAGWRAP()
Function: tagwrap(<name>[, <parameters>], <string>)

  This function outputs <string>, wrapped in the <name> HTML/Pueblo tag with the specified <paramaters>.

  Example:
    tagwrap(a,href="http://download.pennmush.org",PennMUSH Downloads)]
   
  Will output (in HTML):
    <a href="http://download.pennmush.org">PennMUSH Downloads</a>

  A particularly important use of this function is tagwrap(pre, <string>). Because Pueblo works like an html browser, spaces and tabs are compressed to a single space. If you have code (a +who function, for example) that relies on exact spacing, surround its output with a tagwrap(pre,...) so that Pueblo will render it as "preformatted" text.
  
See also: tag(), endtag(), html()
& WEBSOCKETS
  Websockets are a network protocol used by JavaScript-enabled web browsers to make persistent network connections, similar to the telnet connection you use to connect to PennMUSH. With Websockets enabled in mush.cnf, it is possible to connect from MUSH clients embedded in HTML pages using JavaScript. A Websocket client can natively render HTML, but can also parse Pueblo links into HTML links that send a command to the MUSH when clicked. For safety, we separate plain text from the other kinds of HTML/Pueblo code that we want rendered. In order to render HTML/Pueblo, a player with the Pueblo_Send power uses special functions to embed HTML/Pueblo markup. Players without the PUEBLO_SEND power can not use these markup functions. Any HTML code strings that are not properly marked up will simply show up as unrendered plain text.

  See https://github.com/grapenut/websockclient for an example client.

  The different kinds of markup that can be sent to clients are plain text, HTML tags, Pueblo links, JSON objects, and prompts. Without using any HTML markup functions, output is rendered as normal plain text (including ANSI and xterm256 color).

  See 'help HTML Functions' for functions used to embed HTML markup tags one at a time.
  See 'help wshtml()' for help embedding large segments of raw HTML markup to be sent to Websocket clients.

  Support for Pueblo links depends on the Websocket client, however the example client above supports xch_cmd for command links and xch_hint for tooltip text popups. For clickable command links, embed a link tag with the command to be executed in the "xch_cmd" attribute, e.g. <a xch_cmd="+who">Who is online?</a>.

  You can also send data encapsulated in a JSON object.
  See 'help json()' for information about formatting data into JSON object strings.
  See 'help wsjson()' for help sending formatted JSON object strings to Websocket clients as a JavaScript object.

  See `help @prompt` for information about sending telnet GOAHEAD prompts. Support for prompts depends on the Websocket client. The example client above shows prompts on their own line separating the input and output windows, but requires PROMPT_NEWLINES to be turned off.
  
See also: HTML Functions, json(), pueblo, wshtml(), wsjson()
& WSHTML()
& WSJSON()
  wshtml(<html string>[, <default string>])
  wsjson(<json string>[, <default string>])

  These functions are used to embed HTML and JSON markup into the output for Websocket-enabled clients. They require the Pueblo_Send power.
  
  wshtml() embeds <html string> as HTML markup, to be rendered as HTML by a Websocket client. The <default string> is shown as plain text if the recipient is not Websocket-enabled.

  wsjson() embeds <json string> as a JSON object which can be captured by a Websocket client. The <default string> is shown as plain text if the recipient is not Websocket-enabled. See 'help json()' for information about formatting JSON object strings.

  For example, if one uses:

    @emit [wshtml(<a href="http://pennmush.org">PennMUSH</a>,Go to http://pennmush.org)]

  then any players in the room with a Websocket connection would see (rendered as HTML)

    <a href="http://pennmush.org">PennMUSH</a>

  while non-Websocket connections and listening objects would see

    Go to http://pennmush.org

See also: websockets, pueblo, json(), HTML Functions
& help
This is the index to the MUSH online help files.

  For an explanation of the help system, type:    help newbie
  For a walkthrough of PennMUSH systems, type:    help getting started

  For the list of MUSH commands, type:            help commands
  For the list of MUSH topics, type:              help topics
  For an alphabetical list of all help entries:   help entries 
  For information about PennMUSH:                 help code
  
  For a list of flags:                            help flag list
  For a list of functions:                        help function list 
  For a list of attributes:                       help attribute list
  To see the configuration of this MUSH:          @config

  Use 'help <pattern>' to search for topic names that match the wildcard pattern <pattern>, or 'help/search <pattern>' for a list of topics whose text matches <pattern> (See HELP SEARCHING for details on the format of the pattern).
  
  On many MUSHes, list local commands with:       +help

  If there are any errors in the help text, please notify a wizard in the game, or file an issue at https://github.com/pennmush/pennmush/issues, which is the bug-tracking site for PennMUSH (and its distributed help files) but probably has no relation to this MUSH in particular.
& searching
help/search <pattern>

Displays help entries that match <pattern>

The pattern is one or more 'phrases', where each phrase is one or more words, optionally enclosed with quote marks, and combined with +. A * at the end treats the phrase as a prefix. Phrases can be combined with AND, OR and NOT. The function NEAR(phrase phrase...) matches entries where two or more phrases are near each other. An optional second argument controls how close the matching is. All these operators must appear in upper case. For full details, see https://www.sqlite.org/fts5.html#full_text_query_syntax

Examples:

  help/search cosine OR tangent
  help/search "treated as"
  help/search NEAR(player wizard, 20)

This switch works with help, news, ahelp, and other help like commands.
& newbie
  If you are new to MUSHing, the help files may seem confusing. Most of them are written in a specific style, however, and once you understand it the files are extremely helpful.

  The first line of a help file on a command or function will normally be the syntax of the command. "Syntax" means the way the command needs to be typed in. In the help files, when the syntax of a command is described, square brackets [] mean that that part of the command is optional and doesn't have to be typed in. Also, pointy brackets <> mean that that part of the command needs to be replaced with a specific piece of information.
  
  You should not type the [] or <> brackets when entering a command.
  
  Continued in 'help newbie2' -- type 'help newbie2' without the quotes.
& newbie2
  For example, the syntax of the help command is:
  
  help [<topic>]
  
  What this means is that to get help, you would type first the word "help" and then you could optionally type the name of a more specific topic in order to get help on that topic. Just typing "help" will work too (that's why the <topic> part is optional).
  
  Some common commands that you should look at help for are:
  
    look   say    go    page    pose    get     give    home
  
  Just type help <command> for help. Example: help page
  
  Continued in 'help newbie3'.
& newbie3
  There is help available on every standard MUSH command. If you see a command or someone mentions one to you that you want to know more about, try just typing: help <command name> -- that will most likely bring up the help file on it.
  
  Please note that just because there is help available on a command does not necessarily mean that the command can be used on this MUSH. The siteadmin of the MUSH can choose to turn off some commands. If there's something that you would like available, and it isn't, please ask a wizard why not.
  
  It is also highly recommended that any new player read the MUSH manual, written by Amberyl. It is available from http://download.pennmush.org/Manuals/

See also: Getting Started
& Getting Started
& GS
& Walkthrough
  This helpfile is a quick walkthrough of some of PennMUSH's standard systems. It uses the same syntax as the other helpfiles; if you're not familiar with the syntax of the PennMUSH helpfiles, please read 'help newbie' first, as it's explained there.
  
  For help with getting around, please see 'help gs moving'.
  
  To talk to people in the room with you, see 'help gs talking'.
  
  For a brief guide to the PennMUSH chat system, see 'help gs chat'.
  
  For information on how to send and read mail using PennMUSH's built-in mail system, @mail, please type 'help gs mail'.
& GS MOVING
  To see the room you're in, type 'look'. You'll probably see something similar to this (though some MUSHes customize the appearance of rooms):
  
    Example Room
    This is an example room. It has a rather boring description.
    Contents:
    Bob
    Sports car
    Obvious exits:
    Next Room and Out
    
  The first line is the name of the room you're in, followed by the room's description, a list of other people (and objects) in the room, and finally a list of exits to other rooms.
  
  To move through one of the exits, you can simply type its name (Out), or you can use the "goto" command (goto Out).
 
  Continued in 'help gs moving2'.
& GS MOVING2
  All players on a MUSH have a "home", which is usually the room you started in. You can go back to your home by just typing 'home', or 'goto home'. Some MUSHes may also allow you to change your home to somewhere else; you can do that by typing '@link me=here' when you're in the room.
  
  There may be some objects on the game that you can go inside (wagons or cars, for instance). You can do that by typing 'enter <object>', and can leave again by typing 'leave'. For instance, 'enter sports car'.
  
  It's also sometimes possible to teleport from one room to another, using the '@teleport' command. However, most new players on a game probably won't be able to do that - it's mentioned here only for completeness.
  
See also: goto, home, enter, leave, @teleport, @link
& GS TALKING
  You can talk to others in the room with you (those listed in the 'Contents' of the room) in a number of ways. The easiest is to use the 'say' command. 
  
  For example, when you type:
    say Hello!
  you'll see:
    You say, "Hello!"
  and everyone else in the room will see:
    Lisa says, "Hello!"
  
  You can abbreviate the command to just:
    "Hello!
  if you wish; it works exactly the same.

  Continued in 'help gs talking2'.
& GS TALKING2
  You can also perform actions, using the 'pose' command, or ':' for short.
  For example:
    pose waves!   or
    :waves!
  will both show:
    Lisa waves!
  to everyone in the room (including yourself). If you don't want a space after your name, use 'semipose' (or ';') instead:
    ;'s waving!
  will show:
    Lisa's waving!
    
  If you don't want your name to be added at all, you can use the '@emit' command, or '\' for short:
    @emit Smiling, Lisa waves, "Hello!"
  will show everyone in the room:
    Smiling, Lisa waves, "Hello!"
    
  However, make sure you include your name somewhere, so people know who's talking.
  
See also: GS CHAT, say, pose, semipose, @emit
& GS CHAT
& GS CHANNELS
  PennMUSH has a built-in channel system, which allows you to talk with players who are on the same channels as you, even if you're in different rooms.
  
  Most games have a number of different channels, either for discussing different subjects, or for different groups/factions of players to chat on.
  
  To see a list of channels, type '@channel/list'. This shows the names of all the channels, whether or not you're on the channel, and some other information (the rest is explained in 'help channel-list').
  
  To join a channel, type '@channel/on <channel>'. To leave it again, use '@channel/leave <channel>'. If you want to stop hearing a channel for a while without leaving it totally, use '@channel/gag <channel>'.
  
  Continued in 'help gs chat2'.
& GS CHAT2
  When you've joined a channel, you can chat on it in two ways:
  
    +<channel> <message>
    @chat <channel>=<message>
  
  You don't need to type the entire channel name, just enough letters to make it distinct from other channels. For instance, '+pub Hello'.
  
  When you talk on a channel, everyone who is on the channel will see the channel name in '<>' angle brackets, then your name and the message.
  For example, '+pub Hello' will show everyone
    <Public> Skye says, "Hello"
  If the <message> starts with a ':' or ';' it will be posed or semiposed, respectively. For example, '+pub :waves' shows
    <Public> Skye waves.
    
  Some games customize the appearance of channels a little (for instance, adding color or using '[]' square brackets instead of angle brackets), so it may look a little different.
    
  There's much more you can do with the channel system - see 'help @channel' for the other commands.
See also: GS TALKING, @channel, @chat
& GS MAIL
  PennMUSH has a built-in mail system that lets you send messages to players, even if they aren't online. You can keep mail you receive for as long as you like, and re-read it any time.
  
  To list all the messages you've received, type '@mail'. You'll see something like:

   -------------------------  MAIL (folder  0)  ----------------------------
   [-----]  0:1    One           Welcome!                   Wed Dec 08 09:57
   [-----]  0:2   *Mike          Example Mail               Sat Dec 11 07:55
   -------------------------------------------------------------------------

  The number after the ':' is the message number; to read that message, type '@mail <number>'.

  Continued in 'help gs mail2'.
& GS MAIL2
  To send mail to someone, type:
    @mail <recipients>=[<subject>/]<message>
    
  You can send a message to more than one person at a time, just include the names of all the people you want to send to in <recipients>. The <subject> is optional. For example:
  
    @mail qa'toq anne=Test/Hi! This is a test message!
    
  You can do other, slightly more complex things with the mail system, too, like filing your messages into different folders. See 'help @mail' for more information.
  
See also: @mail
& topics
Help is available on the following topics:

  ACTION LISTS             ANCESTORS                ANONYMOUS ATTRIBUTES
  ATTRIB-OWNERSHIP         ATTRIBUTES               BOOLEAN VALUES
  CHAT                     CLIENTS                  CONTROL
  COPYRIGHT                COSTS                    CREDITS
  DBREFS                   DROP-TO                  ENACTOR
  EVALUATION               EXECUTOR                 EXITS
  FAILURE                  FLAGS                    FUNCTIONS
  GENDER                   GLOBALS                  HERE
  HOMES                    INTERIORS                LINKING
  LISTENING                LISTS                    LOOPING
  MASTER ROOM              MATCHING                 ME

  Continued in 'help topics2'.
& topics2
  MONEY                    MUSHCODE                 NON-STANDARD ATTRIBUTES
  PARENTS                  POWERS                   PUPPETS
  QUEUE                    REGEXPS                  REGISTERS
  SEMAPHORES               SETTING-ATTRIBUTES       SPOOFING
  STACK                    STRINGS                  SUBSTITUTIONS
  SUCCESS                  SWITCHES                 TYPES OF OBJECTS
  USER-DEFINED COMMANDS    VERBS                    WARNINGS
  WILDCARDS                ZONE MASTER ROOMS        ZONE MASTERS
  ZONES

Type 'help <topic name>' for help.
For a list of all topics, see 'help entries'.
& ACTION LISTS
  An "action list" is simply a list of MUSH commands which are run together, one after the other. Each command in the list is separated by a semicolon. Action lists appear in many places: in user-defined commands, triggered in @a-attributes by the MUSH, and even as arguments to other commands, like @switch and @dolist.

  If part of the command (such as the text in an @emit, for example) contains a semi-colon, you may need to enclose that part in curly braces {}. You can also nest action lists inside each other by enclosing each action list in braces {}.

  Substitution will be performed on the contents of action lists before they are executed.

  See 'help action2' for some examples.
See also: @-ATTRIBUTES, VERBS, $-COMMANDS
& ACTION2
  Example 1:
    > @asuccess Gift=@pemit %#={The box pops open; surprise!} ; @name me=New Toy ; @desc me=A shiny new toy, just for %n!
    > take gift
    The box pops open; surprise!
    > look new toy
    New Toy
    A shiny new toy, just for Cyclonus!
            
  Example 2:
    > &TEST me=$test:@emit {Testing; testing; one, two.} ; @dolist 1 2 3={think Test %i0, success.}
    > test
    Testing; testing; one, two.
    Test 1, success.
    Test 2, success.
    Test 3, success.

See also: ATTRIBUTES, SUBSTITUTION, @asuccess, @dolist
& ANCESTORS
  ANCESTORS

  Objects can inherit attributes and locks from other objects through the use of parents. An object's parent, its parent's parent, its parent's parent's parent, etc. constitute the object's "parent chain" and lookups work the way up the chain until an inheritance occurs.

  Ancestors are "virtual parents" that are assumed to be last on every parent chain. There is one ancestor for each object type (room, exit, thing, player), and @config lists the dbref of each ancestor object (@config ancestor_room, etc). Under normal circumstances, if an attribute/lock can't be retrieved from an object or any of its explicit parents, the attribute will be looked for on the appropriate ancestor. The ORPHAN flag may be set on an object to cause lookups on that object to ignore ancestors (like the pre-ancestor behavior).

  Ancestors may themselves have parent chains, but these are (obviously) not virtually terminated by ancestors.

  Note that the choice of which ancestor to look up is based on the type of the *child* object, as is the check of the ORPHAN flag. Also note that ancestors are *not* checked for $-commands or ^-commands; you should use the master room for global commands, instead.

See also: PARENTS, ORPHAN
& ANONYMOUS ATTRIBUTES
& LAMBDA
& #LAMBDA
& #APPLY
  In many cases where a function expects a object/attribute pair that refers to an attribute to evaluate, you can use the form

  #lambda/<code>

  instead, and the code will be treated as an attribute's body. The code will normally be parsed twice, so special characters should be escaped where needed.

  If the #lambda just calls one other function, the form

  #apply[<number of arguments>]/<function name>

  can be used instead. If the argument count is left out, it defaults to 1.

  These anonymous attributes should be used for short and simple pieces of code. Anything long or complicated should go in an actual attribute, for readability and maintainability.

  See 'HELP ANONYMOUS2' for examples.
& ANONYMOUS2
& LAMBDA2
& #LAMBDA2
  A typical usage of anonymous attributes would be to convert a list of dbrefs to names, as so:

  > say map(#lambda/name(\%0), #3 #12 #23)
  You say, "Joe Robert Sally"
  
  The following version uses #apply instead:

  > say map(#apply/name, #3 #12 #23)

  Because the code is parsed twice, you can actually build parts of it in place, which is very convenient. Consider this implementation of a lattrval function, which is like lattr() but it only returns non-empty attributes:

  > &lattrval me=filter(#lambda/hasattrval([decompose(before(%0, /))], \%0), lattr(%0))
  
  The first time '#lambda/hasattrval([decompose(before(%0, /))], \%0)' is parsed in a call like 'u(lattrval, #1234)', it is turned into '#lambda/hasattrval(#1234, %0)', thus avoiding the need for a setq() or the like to store the top-level %0 for use in a real attribute called by filter(). However, this can lead to problems with evaluating un-trusted code. Use decompose() where neccessary.

  See 'HELP ANONYMOUS3' for more examples.
& ANONYMOUS3
& LAMBDA3
& #LAMBDA3
  You can also use lit() to avoid having the code evaluated twice, if needed. For example, this code, which returns all unlinked exits in a room:

  &lunlinked me=filter(lit(#lambda/strmatch(loc(%0), #-1)), lexits(%0))

  This approach is useful both for security in making it harder to evaluate a string that shouldn't be, and for making the code look nicer by not having to escape percent signs, brackets, and other special characters. However, it also makes it harder to build the code string on the fly. Use what's most appropriate.
  
  Finally, a multiple argument example of #apply, which requires less escaping than #lambda for cases where you're just calling another function:

  > think mix(#apply2/ansi, r g b, foo bar baz)

  See 'HELP ANONYMOUS4' for a list of functions that support anonymous attributes.
& ANONYMOUS4
& LAMBDA4
& #LAMBDA4
& LAMBDA FUNCTIONS
  The following functions support anonymous attributes:
  
  filter()    filterbool()   fold()      foreach()   map()      mapsql()
  mix()       munge()        namelist()  sortby()    sortkey()  speak()
  step()

& ATTRIB-OWNERSHIP
  ATTRIBUTE OWNERSHIP
  
  The latest person to set an attribute on an object is the owner of that attribute. If you lock an attribute, using the @atrlock command, only the person who owns the attribute will be able to alter the attribute. This allows you to create standard commands on objects and then @chown them to others without letting them alter them.

  Attribute ownership is NOT changed when the object itself is @chown'ed. To change attribute ownership, you must use the @atrchown command.

  You must control an object in order to set attributes on it.

See also: @atrlock, @atrchown, ATTRIBUTES
& ATTRIBUTES
& ATTRIBUTES LIST
& ATTRIBUTE LIST
  Attributes with (*) after them are special, cannot be set by players, and may only be visible to wizards or admin. For those attributes, there is no @-command, so you can just type 'help <attribute name>' for help. For all other attributes, type 'help @<attribute name>' for help.

Standard Attributes: (see @list/attribs for the complete list)
  AAHEAR        ACLONE        ACONNECT      ADESCRIBE     ADISCONNECT
  ADROP         AEFAIL        AENTER        AFAILURE      AHEAR
  ALEAVE        ALFAIL        AMHEAR        AMOVE         APAYMENT
  ASUCCESS      AWAY          CHARGES       COST          DESCRIBE
  DROP          EALIAS        EFAIL         ENTER         FAILURE
  FORWARDLIST   HAVEN         IDESCRIBE     IDLE          LALIAS
  LAST (*)      LASTIP (*)    LASTLOGOUT(*) LASTSITE (*)  LEAVE
  LFAIL         LISTEN        MOVE          ODESCRIBE     ODROP
  OEFAIL        OENTER        OFAILURE      OLEAVE        OLFAIL
  OMOVE         OPAYMENT      OSUCCESS      OXENTER       OXLEAVE
  OXMOVE        PAYMENT       QUEUE (*)     RQUOTA (*)    RUNOUT
  SEX           STARTUP       SUCCESS       TFPREFIX

  Continued in 'help attributes2'.
& ATTRIBUTES2
  An attribute is part of the code on an object that makes it unique. An attribute can contain any sort of text -- from a single word, to a long paragraph, to a piece of MUSHcode. Some attributes are standard in PennMUSH. That means that their effects are pre-set.

  Standard attributes can be set using one of the following commands:
    @<attribute name> <object>=<content>
    @set <object>=<attribute name>:<content>
    &<attribute name> <object>=<content>

  It is also possible to have non-standard attributes, which can be named anything you like. Please see 'help NON-STANDARD ATTRIBUTES' for more information on those.

  Continued in 'help attributes3'.
& ATTRIBUTES3
  Any attribute name can be shortened, but a shorter forms run the risk of conflicting with other attribute names. This could result in you setting an unwanted attribute.

  For example:
    @adesc me=think %n looks at you.
  will set your ADESCRIBE attribute just as
    @adescribe me=think %n looks at you.
  would.

  To see the attributes that are set on you or on any of the objects you own, you should use the "examine" command. See 'help examine'.
  
  Continued in 'help attributes4'.
& ATTRIBUTES4
  Attributes can be owned by someone other than the object they are set on. This allows the person to change the content of just that attribute while not the rest of the object. Attributes can also be locked, which prevents them from being changed by anyone.

  In addition to the standard attributes with pre-set effects, there are some special attributes that date from the days before you could set non-standard attributes with any name you wanted. These are the attributes VA-VZ, WA-WZ, XA-XZ. These attributes have no pre-set effects, and were just to allow players to store any text or MUSHcode that they wished in those attributes. Now that non-standard attributes are available, it is highly recommended that you instead use them, since you can use longer and descriptive names for attributes, which makes it much easier to examine and work on objects.

See also: ATTRIB-OWNERSHIP, @set, examine, @atrchown, @atrlock, hasattr(), get(), v(), NON-STANDARD ATTRIBUTES, SETTING-ATTRIBUTES, ATTRIBUTE TREES
& BOOLEAN VALUES

  A boolean variable, for those of you not familiar with programming, is a variable that is either true or false. Normally, a value of 1 is considered "true" and a value of 0 is considered "false". Many MUSH functions return either 1 if they are true or 0 if false. For example, the hasflag() function tests to see if an object has a certain flag set on it. If hasflag(<object>,<flag name>) is true (the object has the flag), it will return 1. If it is false, it will return 0.

  Other functions expect to operate on boolean values. What they consider "true" or "false", however, depends on the setting of the "tiny_booleans" config option (@config tiny will show this).

  Continued in 'help boolean2'.
& BOOLEAN2
  If tiny_booleans is...
  no                       FALSE: null string, 0, any negative db
                           TRUE:  everything else
  yes                      TRUE:  numbers other than 0, strings beginning with numbers other than 0
                           FALSE: everything else 
  
  Or, put another way:
  Value                 tiny_booleans=no        tiny_booleans=yes  Gotcha
  0                     FALSE                   FALSE
  non-zero number       TRUE                    TRUE 
  #<non-negative>       TRUE                    FALSE               *
  #<negative>           FALSE                   FALSE                

  null string           FALSE                   FALSE
  0<non-numbers..>      TRUE                    FALSE               *
  <non-numbers...>      TRUE                    FALSE               *

  Continued in 'help boolean3'.
& BOOLEAN3

  Examples (assuming tiny_booleans is "no"):     
    not(foo) = 0  
    not(<null string>) = 1
    not(-66) = 0
    not(0) = 1
    not(#-1) = 1
    not(#12) = 0
  And so on...
  (note: These rules only apply when a function expects a Boolean value, not for strings that expect other values.)

See also: BOOLEAN FUNCTIONS, not(), t()
& CLIENTS
  Clients are special software programs that you can use to connect to MUSHes. They are usually much nicer to use than raw telnet and give you many additional features, such as larger text buffers (so you can type more), backscroll, history of previous commands, macros, and so on.

  Here is a list of common clients and the web sites where they can be found.  Please note that the below sites are subject to change. The below are listed solely for your information and possible benefit. The developers of PennMUSH have nothing to do with the clients. Except for Potato, which is made by Mike. Not that this is a shameless plug. Noooo. Carry on.

  OPERATING
  SYSTEM          CLIENT      WEB SITE
  -----------------------------------------------------------------------
  UNIX            Tinyfugue   http://tinyfugue.sourceforge.net
                  Potato      http://www.potatomushclient.com
  WINDOWS         MUSHClient  http://www.mushclient.com
                  SimpleMU    http://simplemu.onlineroleplay.com
                  MuckClient  http://www.xcalibur.co.uk/MuckClient/
                  Potato      http://www.potatomushclient.com
  MAC OS X        Savitar     http://www.heynow.com/Savitar/
                  Atlantis    http://www.riverdark.net/atlantis/
                  Potato      http://www.potatomushclient.com
                  Unix clients will also run on OS X.
& CONTROL
  Controlling an object basically means that you have the power to change the object's characteristics such as flags and attributes. It may also mean that you have the ability to destroy it.

  These checks are performed, from top to bottom, to see if object O controls object V:
   1. If O has the Guest power, O does not control V
   2. If O and V are the same object, O controls V
   3. If V is God, O does not control V
   4. If O is a Wizard, O controls V
   5. If V is a Wizard, O does not control V
   6. If V is Royalty and O is not, O does not control V
   7. If O is MISTRUST, O does not control V
   8. If O and V are owned by the same player, and either:
       a. V is not set TRUST, or
       b. O is set TRUST
      then O controls V
   9. If V is a player, or set TRUST, O does not control V
  10. If the zone_control_zmp_only @config option is set to 'No', V is on a Zone, and O passes the Zone's @lock/zone, O controls V
  11. If V is owned by a SHARED player, and O passes the owner's @lock/zone, O controls V
  12. If V has an @lock/control, and O passes the lock, O controls V
  13. O does not control V

See also: controls(), TRUST, MISTRUST, ZONES, SHARED PLAYERS
& COSTS
  Some things on the MUSH cost pennies. The default costs are shown below:
  
          @dig: 10 pennies
          @create: 10 pennies (or more)
          @search: 100 pennies *
          @link: 1 penny (if you didn't already own it, +1 to the previous owner)
          @open: 1 penny (2 pennies if linked at the same time)
  
  Type '@config/list costs' to get the costs for the MUSH you are on.

See also: MONEY, money(), score
& CREDITS
  Maintainer: Raevnos [SW]
  Developers: Greg Millam [GM], Mike Griffiths [MG], Intrevis, Tim Krajcar/Rince [TK]
  Past Porters: Nick Gammon [NJG] (win32), Dan Williams [DW] (MacOS), Sylvia (OS/2)
  Former developers: Rhyanna [RLM], Trivian [TN], Halatir [LdW], Talek [TAP], Javelin, Ervin Hearn III [EEH]
 
  The original TinyMUSH 1.0 code was written by Lawrence Foard, and was based upon James Aspnes' TinyMUD server. Since then, the code has been modified by the programmers of MicroMUSE (then MicroMUSH), and Joseph Traub (Moonchilde of PernMUSH). From January 1992 to January 1995, Lydia Leong (Amberyl of PernMUSH / Polgara of Belgariad) maintained the code currently known as PennMUSH 1.50. From January 1995 until July 2006, Alan Schwartz (Paul of DuneMUSH / Javelin elsewhere) maintained this code, along with a development team. From July 2006 on, Raevnos has been the maintainer.

  Big thanks to the developers of TinyMUSH 2.0, 2.2 [2.2], 3.0 [3], MUX2, and Rhost [Rhost] servers, as well as to the players of Belgariad MUSH, DuneMUSH, and M*U*S*H, and everyone else using this server!

See also: help code, help license
& DATABASE
& DBREFS
& DBREF NUMBER
& DBREF #
  You will find the term "dbref" or "dbref number" used frequently in these help files and in MUSHcode. It is an abbreviation of "database reference number".
  
  The database is the part of MUSH that stores all the information about this particular MUSH. Players, things, rooms, and exits are all objects in the database. Each object in the database has a unique dbref number that is set when the object is created. You can use the dbref number to refer to an object that is not in your current location, and it is especially important for global code.

  Using DBREFs is also faster than using names, even if the object is in your location. This is because whenever you try to do something with an object (such as look at it, take it, etc.), the MUSH first has to locate the object. Since the dbref is unique, it can immediately find the object rather than checking through all the contents of your area to see if one matches the name.

  Continued in 'help dbref2'.
& DBREF2
  
  If you own or control an object, you will see its dbref number listed right after its name when you look at it (unless you are set MYOPIC).

  Example:
    > look me
    Cyclonus(#3PWenAMc)
    A very short desc.

  The dbref number is indicated by the number/pound sign (#). Cyclonus's dbref is #3. The letters following the dbref are the abbreviations of the flags set on the object. NOTE: the abbreviation of the OPAQUE flag is 'O' (o), which looks like '0' (zero) on some clients. Make sure you have the right number before using it in your code!

See also: MYOPIC, OPAQUE, MUSHCODE, MATCHING, OBJIDS
& OBJIDS
& OBJECT IDS

  When an object is destroyed, its dbref number will eventually be recycled and given to a newly created object. This can cause problems in code, particularly in database code which stores members of a group, as code which was meant to refer to the old object ends up referring to the new one by mistake.
  
  To avoid this problem, you can use the "object id", or objid, instead of the dbref. An object id consists of the object's dbref, a colon, and then the object's creation time. Objids can be used anywhere dbrefs can and, because the creation time is different each time the dbref is recycled, the objid is totally unique to each object.
  
  The objid() function returns the object id of an object, and the %: substitution evaluates to the objid of the enactor. 
  
See also: objid(), @lock-objid, DBREFS
& DROP-TOS
& DROPTOS

  When you use the @link command on a room, it sets another room or object as the DROP-TO location. By default, any non-STICKY object that someone drops in the room will automatically be transported to the drop-to location, rather than staying in the room. Any STICKY object dropped in the room will go to its home.

  If the room is set STICKY, objects will stay in the room until the last player leaves or disconnects, at which point they will be transported as described above.

  Drop-tos work on things and players alike.

  If the room has a @lock/dropto set on it, only objects that pass the lock will be transported (either immediately or when the last player leaves if the room is STICKY). This can be used to prevent the dropto from acting on, say, objects containing connected players.

See also: @link, STICKY, LINK_OK, @lock
& %#
& %n
& %k
& %~
& %:
& ENACTOR
  The enactor is the object which causes something to happen. This is an important concept in MUSH, because the way many commands work will depend on who enters the command (ie, who the enactor is). Note that while the enactor is the object which -caused- code/a command to run, it is not necessarily the object which is running the code (that's the executor). Any type of object can be an enactor.

  There are eight %-substitutions that involve the enactor:
    %# = the enactor's dbref
    %n = the enactor's name
    %~ = the enactor's accented name
    %k = the enactor's name, colored by their @moniker (if any)
    %: = the enactor's unique identifier, like objid(%#)
    %a, %o, %p, %s = pronoun substitutions, based on the enactor's @sex. See 'help gender' for more information.

  If, for example, you have an @osuccess on an object that includes the %n subtitution, whenever someone picks up the object, that %n will evaluate to the name of the enactor (the person who typed 'get <object>' in this case).
  
See also: EXECUTOR, CALLER, SUBSTITUTIONS, DBREF
& %!
& EXECUTOR
  The executor of a command is the object actually carrying out the command or running the code. This differs from the enactor, because the enactor is the object that sets off the command. In some cases, the enactor and the executor will be the same. The substitution %! evaluates to the dbref of the executor of the code.

  For example:
    > @emit %n (%#) is the enactor and %! is the executor!
    Cyclonus (#6) is the enactor and #6 is the executor!
    > @create Box
    Created: Object #10
    > &EMIT box=$emit: @emit %n (%#) is the enactor and %! is the executor!
    > emit
    Cyclonus (#6) is the enactor and #10 is the executor!

  In the first case, Cyclonus directly entered the command and was therefore both the enactor and the executor. In the second, Cyclonus set off the command on the box, so Cyclonus was still the enactor, but the box was the object that was actually doing the @emit, and was thus the executor.

See also: ENACTOR, CALLER, SUBSTITUTIONS
& %@
& CALLER
  The caller is the object which causes an attribute to be evaluated (for instance, by using ufun() or a similar function). The substitution %@ evaluates to the caller's dbref. It's particularly useful for functions with side-effects, to check that the object evaluating the function has permission.
  
  Example:
    > &cmd_test Foo=$test: @emit ufun(Bar/fun_test)
    > &fun_test Bar=%n(%#) typed 'test', and [name(%@)](%@) ufun()'d this!
    > test
    Mike(#5) typed 'test', and Foo(#6) ufun()'d this!
    
    > &wizfun Foo=if(hasflag(%@, Wizard), ufun(wizfun2), #-1 Sorry)
    
See also: ENACTOR, EXECUTOR
& EVALUATION ORDER
  Whenever some text is entered by an object, the MUSH attempts to match it against a valid game command in the following order of possible commands:

    Socket commands (*): QUIT, SCREENWIDTH, etc
    Single-token commands: ", :, ;, +, \, #
    MUX-style channel aliases, if enabled (see 'help muxcomm')
    Exits in the room
    &attribute setting
    Regular game commands: get, inventory, @emit, etc
    @attribute setting
    Enter aliases
    Leave aliases
    User-defined commands on nearby objects. All such $-commands are matched and executed.
    If there are no user-defined commands nearby:
      If the zone of the player's location is a zone master room,
        Zone master room exits
        Zone master room user-defined commands
      Else
        User-defined commands on the zone of the player's location

  (*) Socket commands are only matched when the command is entered by a player directly from their client.
    
  Continued in 'help evaluation2'.
& EVALUATION2
    If still nothing is matched:
      User-defined commands on the player's personal zone
    If nothing, including zone commands, has been matched:
      Global exits
      Global user-defined commands: all $-commands in the Master Room are matched. Local commands are always checked first and ALWAYS negate global commands.
    If still nothing has matched, run huh_command to show a Huh? message

  Because local $-commands overrule global $-commands, you can easily prevent a global $-command from working in a specific room by setting a copy of the global $-command in that room. Alternatively, if a global $-command is oddly not working in a room, you should check for copies of the command word in the room (using @scan). Wizards who want to ensure a global $-command always takes precedence over a local one should use @command/add and @hook/override, to make the command run as a regular game command instead of a softcoded global.
  
See also: @command, @hook, $-commands, huh_command
& FAILURE
  FAILURE  

  A "failure" usually occurs when you try to do something that is governed by an @lock and you don't pass the lock. If you try to take a player or thing, or pass through an exit, and you don't pass its Basic @lock, you will set off their @failure/@ofailure/@afailure attributes. A few failures have special attributes, while others use <locktype>_LOCK`FAILURE, <locktype>_LOCK`OFAILURE and <locktype>_LOCK`AFAILURE attributes.

  See 'help failure2' for a list of failure verbs and when they're triggered.

  See 'help @lock' and 'help locktypes' for more information on lock types.

See also: verbs, @lock, @failure, @efail, @lfail
& failure2
  The following failures are defined in PennMUSH:
  
  Failure to...                                 Lock     Attribute
  --------------------------------------------- -------- --------------------
  "get" a player/thing, pass through an exit,   Basic    @failure
    or "look" in a room
  run an $-command on an object                 Command* COMMAND_LOCK`FAILURE
  use zwho()                                    Zone     ZONE_LOCK`FAILURE
  leave your current location                   Leave    @lfail
  "take" from an object                         Take     TAKE_LOCK`FAILURE
  "drop" a thing, or drop something in a room   Drop     DROP_LOCK`FAILURE
   enter an object                              Enter    @efail
  "follow" an object                            Follow   FOLLOW_LOCK`FAILURE
  "give" an object away                         Give     GIVE_LOCK`FAILURE
  "give" money to or "buy" from an object       Pay      PAY_LOCK`FAILURE
  "@chzone" something to a zone                 Chzone   CHZONE_LOCK`FAILURE
  "use" an object                               Use      @ufail
  speak via say/pose/@*emit/teach in a room     Speech   SPEECH_LOCK`FAILURE
  "page" or "@pemit" to an object               Page     PAGE_LOCK`FAILURE**
  "@mail" a player                              Mail     MAIL_LOCK`FAILURE
  
  * The Use lock can also prevent you from running an $-command, but it will still trigger COMMAND_LOCK`FAILURE.
  ** @haven or @away will also be shown on failure to "page", if set
  
& GENDER
& SEX
  Gender on a MUSH is entirely up to you. You can set yourself (or any of your objects) to be male, female, neuter, or plural. If whatever is in the SEX attribute is not recognizable, the MUSH will assume the object is neuter. Setting a gender attribute will enable pronoun substitution by the MUSH. The SEX attribute is visual to anyone who wants to see it.
  
  The obj(), subj(), poss() and aposs() functions return different pronouns for an object based on its @sex, and the %o, %s, %p and %a substitutions return the same pronouns for the enactor.

See also: @sex, SUBSTITUTION
& GLOBALS
& GLOBAL COMMANDS
  A command is "global" if it can be used anywhere in the world of the MUSH. The standard/built-in MUSH commands are all global, so this term is usually used to refer to user-defined commands on objects in the Master Room of the MUSH. Global commands very greatly from MUSH to MUSH, but you can usually find MUSH-specific help on them by typing "+help".

See also: MASTER ROOM, USER-DEFINED COMMANDS, EVALUATION ORDER
& HERE
  The word 'here' refers to the room you are in. For example, to rename the room you're in (if you control it), you could use:

    > @name here=<new name>
    
See also: MATCHING
& HOMES
& HOME
  Every thing or player has a home, which is usually the room where it was created. You can reset your home or the home of any object you own with the @link command: @link [me | <object>]=<location>. You must also control <location>, unless that location (room or thing) is set ABODE or LINK_OK.

  When a player types 'home', she is sent back to the home room. When a thing with the STICKY flag set on it is dropped, it also goes to its home location. Note that if the FIXED flag is set on a player, she cannot use the 'home' command.

  You can create an exit that sends players home by doing:
    > @link <exit name>=home
  You can set the drop-to in a room to home by doing:
    > @link <room dbref or "here">=home
        
  The home of an exit is its source (the room it's located in). You can change the home/source of an exit by @teleporting it to another room.

  The home of a room is its drop-to.

See also: DROP-TOS, @link, STICKY, LINK_OK, FIXED, EXITS, home(), loc()
& INTERIORS
  Here's a quick description of how to make things that can be entered:
        
  @create Car
  @desc Car=A shiny red car.
  @idesc car=You are sitting inside a luxurious sportscar.
  @set Car=enter_ok
  @oxleave car=climbs out of the car.   { The 'ox' messages are shown to 
  @oxenter car=climbs into the car.     { those OUTSIDE the object.
  @oenter car=joins you inside the car. { The 'o' messages are shown to 
  @oleave car=gets out of the car.      { those INSIDE the object
  @enter car=You get into the car.      { The plain messages are shown to 
  @leave car=You get out of the car.    { the one entering or leaving 
       
  Continued in 'help interiors2'.
& INTERIORS2
  Now, if you want people inside to be able to hear and communicate with the outside, you also need to do the following.
   
  @set car=audible  (lets people outside hear what's being said in the car.
  @listen car=*     (lets people inside hear what's being said outside.
  @prefix car=From inside the car,
  @inprefix car=From outside,
  @filter car=* has arrived.,* has left.,joins you inside the car., gets out of the car.
  @infilter car=* has arrived.,* has left.,* climbs out of the car., * climbs into the car.

  (The filters will keep people on the outside from seeing the 'o' messages and people on the inside from seeing the 'ox' messages which is a good thing.)

See also: enter, leave, @prefix, @filter, AUDIBLE, @listen
& LAST & LASTLOGOUT
& LAST
& LASTLOGOUT
  LAST and LASTLOGOUT

  These attributes show the last times you connected and disconnected from the MUSH.
  
See also: LASTSITE
& LASTSITE
& LASTIP
  LASTSITE and LASTIP

  The LASTSITE attribute gives the name of the site you last connected from. The LASTIP attribute gives the IP address you last connected from. Mortals cannot set them.
  
See also: LAST
& LINKING

  You can link to a room if you control it, or if it is set LINK_OK or ABODE. Being able to link means you can set the homes of objects or yourself to that room if it is set ABODE, and can set the destination of exits to that room if it is LINK_OK.

See also: LINK_OK, ABODE, @link
& LISTENING
  
  There are two basic ways to trigger action on the MUSH. The basic way is to type in commands such as 'look' or '@emit'. These commands are not seen or heard by other players, although the results of the commands may be.

  The other way is to "listen" for something said/emitted in your hearing. There are two ways to listen for something in a room. The easiest way is to use a combination of @listen and @ahear/@aahear/@amhear.

  For example:
    > @listen Welcome Mat=* has arrived.
    > @ahear Welcome Mat="Welcome, %n!
    Breaker has arrived.
    Welcome Mat says, "Welcome, Breaker!"

  To trigger an object's @listen, you must pass its @lock/listen.

  Continued in 'help listening2'.
& ^
& ^-LISTENS
& LISTENING2
  If you need an object to "listen" for more than one pattern, you can also use ^-patterns. These work similar to user-defined commands, using ^ instead of $. An object must be set MONITOR to have ^-patterns activated.

  Syntax:  &<attribute> <object> = ^<pattern>:<action list>

  For example:
    > @set Welcome Mat = MONITOR
    > &greet Welcome Mat=^* has arrived.:"Welcome, %n!
    > &goodbye Welcome Mat=^* has left.:POSE says as %n leaves, "Bye!"
    Grimlock has arrived.
    Welcome Mat says, "Welcome, Grimlock!"
    Grimlock has left.
    Welcome Mat says as Grimlock leaves, "Bye!"

  Such attributes can also be @triggered as if the ^<pattern>: did not exist.
  
  In order to trigger an object's ^-listen patterns, you must pass BOTH its @lock/use and its @lock/listen.

  Continued in 'help listening3'.
& LISTENING3
  By default, ^-patterns work like @ahear. To have them work like @amhear, set the AMHEAR attribute flag on the attribute; to have them work like @aahear, set the AAHEAR attribute flag on the attribute (Note that the triggering object is whatever happens to be %#, so, for example, when you @set an object MONITOR, you are %# with regard to the "Object is now listening" message, and this message can be picked up with an ^-pattern.)

  Additionally, unlike $-commands, ^-patterns are NOT inherited via @parent, unless the LISTEN_PARENT flag is set on the listener. @listen is never inherited.

  Listen patterns are checked after the object's normal @listen attribute.

See also: @listen, @ahear, @amhear, @aahear, MONITOR, LISTEN_PARENT, USER-DEFINED COMMANDS, INTERIORS
& LISTS
  The word "list" is used in the help files to refer to a string that is a series of smaller strings separated by one or more spaces. A list can also have its elements separated by some other kind of character -- the separating character is called the "delimiter". For example, the following are all lists:

    #6 #10 #14 #12
    Rumble|Krystal|Bobatron|Rodimus Prime   ('|' is the delimiter here)
    foo bar whee blarg 
    -eek- .boing. yawp #5 7
  
  Lots of MUSHCode depends on lists and manipulating them. Normally, a
  list is made up of similar items (so the fourth list in the example
  is NOT a typical one).

See also: STRINGS, List Functions, ACTION LISTS
& LOOPING
  Looping in an object can have its good parts and its bad parts. The good part is when you activate part of a program multiple times to exhaustively perform an operation. This can be done like this:

    &PART1 object=<action list> ; @trigger me/PART2
    &PART2 object= @select <test for being done>=<false>,@trigger me/PART1

  Looping can be a problem when it goes on without stopping. The @ps command can be used to see if you are looping. Beware! A looping machine that isn't @halt'd will drain your pennies while you are away from the mush!
  
  The @retry and @include commands, and %= substitution, can also be useful for building code which needs to loop.

See also: @ps, HALT, COSTS, @trigger, @retry, SUBSTITUTIONS3
& MASTER ROOM
  
  The Master Room enables global commands and exits. Exits in the Master Room may be used from any location on the MUSH. All objects left in the Master Room are checked for user-defined $-commands. Those $-commands are considered global, meaning that they can be used anywhere on the MUSH. Normally, only wizards will have access to the Master Room; if you have a global command that you would like to see enabled for the MUSH, speak to a wizard.
  
See also: EVALUATION, GLOBAL COMMANDS
& ME
  The word 'me' refers to yourself. Some things to do when starting out: 
  1) give yourself a description:       @desc me=<description>
  2) check your desc.:                  look me
  3) lock yourself:                     @lock me==me
  4) set your gender:                   @sex me=<male|female|neuter|plural>

See also: NEWBIE, @lock, @describe, @sex, MATCHING
& MONEY
  The MUSH has a built-in money system, which gives a starting amount of money to new players and hands out a daily allowance thereafter. MUSH money (the default name is "pennies", but this may be different depending on the particular MUSH) is spent on some MUSH commands that are computationally expensive or alter the database. In addition, every time you "queue" a command, it costs you a certain amount of money -- this prevents looping from getting out of control, since when all your money is spent, you can't queue any more commands.

  The money system can also be used on player-created objects by setting @cost/@payment/@opayment/@apayment attributes and using the "give" command to give pennies, or by setting @pricelist/@buy/@obuy/@abuy attributes and buying items with the "buy" command. The Pay @lock on an object controls who can give it pennies.
  
  The "score" command tells you how many pennies you have.

See also: COSTS, give, @cost, @payment, @lock, buy, @buy, score, money()
& MONIKERS

  Monikers are ansi templates which allow objects to have colored names. They can be set via the @moniker command, and can always be viewed via the moniker() function and %k substitution. Monikers may also be used automatically by MUSH commands, depending on how the "monikers" @config option is set.
  
  By default, anyone can use the @moniker command to set a moniker for themselves or their objects. However, where monikers are displayed - and for what types of objects - is controlled via the "monikers" @config option.

  Continued in 'help monikers2'.
& MONIKERS2

  The "monikers" @config option should be a list of one or more of these:

  chat - In @chat messages
            say - Non-channel speech (say, pose, page, @wall, etc)
       movement - Movement messages (Joe has arrived., exit @osucc/@odrop, etc)
           look - "look" - contents/exit lists, when looking at an object, etc
        unparse - In "examine", and other places which show Name(#123flags)
            who - In WHO, DOING and SESSION
         system - All other messages generated by the MUSH with player names.
  announcements - Connection messages and "GAME: *" announcements.
     everywhere - All of the above.
  
  You can also limit the types of objects which monikers are used for with 'players', 'things', 'rooms', and/or 'exits'. Use 'alltypes' for all.

  Objects with the MONIKER flag set will always be monikered (though still only in the places specified), even if their type is excluded from the "monikers" option; if no types are included, only objects set MONIKER will be monikered.

  Setting the option empty disables all automatic displaying of monikers, and they will only be available via softcode (moniker() and %k).
  
  You can use !<value> to remove something, so 'everywhere !who' shows monikers everywhere except in WHO, '!everywhere !alltypes' will disable them entirely, etc.
  
See also: @moniker, moniker(), MONIKER
& MUSHCODE
& SOFTCODE

  MUSHcode is the programming language available within the MUSH itself with which you can create user-defined commands and macros. It is sometimes called "softcode" to distinguish it from "hardcode", which is the language that the source code for the MUSH server is written in. (Incidentally, hardcode is written in the C programming language.)
  
  At its most basic, writing MUSHcode is just stringing together a series of commands that you would otherwise just type in one at a time. You can store MUSHcode in attributes on any type of object you own or control (including yourself!). The series of commands can be triggered by using a user-defined command or by using @trigger.
  
  Continued in 'help mushcode2'.
& MUSHCODE2

  If you would like to learn more about MUSHcoding and how to create $-commands for yourself, the following help files may be useful. You may also find it useful to download a copy of Amberyl's MUSH manual and follow the examples described there. However, the manual is quite old now, and some parts may no longer be relevant or entirely accurate. The manual is available for download at http://download.pennmush.org/Manuals/

  Related Help Topics (in no particular order)
  -------------------
  ATTRIBUTES    SUBSTITUTION    NON-STANDARD ATTRIBUTES 
  ENACTOR       EXECUTOR        USER-DEFINED COMMANDS
  DBREFS        EVALUATION      TYPES OF OBJECTS
  WILDCARDS     STRINGS         LISTS           
  ACTION LISTS

& NON-STANDARD ATTRIBUTES
  While there are many standard attributes in MUSH, objects can also have an enormous number of attributes, with any name you wish to use. In the past, you were limited to attributes named VA-VZ, WA-WZ, XA-XZ; these are still available as standard attributes. However, it is strongly recommended that you use non-standard attributes and meaningful names in order to make maintaining your MUSHCode easier.

  To set a non-standard attribute, you can use these formats:
      &<attribute name> <obj>=<value>  OR
      @_<attribute_name> <obj>=<value> OR
      @set <obj>=<attribute_name>:<value>

  You can get the value of attributes using the functions v(), get(), and xget(). You can evaluate attributes using u(), eval(), and get_eval(). All attributes can be used in attribute locks and can be 'owned' independent of object ownership.
  
See also: ATTRIBUTES, ATTRIB-OWNERSHIP, Attribute Functions, ATTRIBUTE TREES, ATTRIBUTE FLAGS
& PARENT
& PARENTS
& OBJECT PARENTS
  
  Objects may have "parent" objects, from which they can inherit attributes. Once an object is given a parent, it may use the attributes on the parent just as if the attributes were on the object itself, including checking for $-commands. Use the @parent command to change the parent of an object.

  Objects may have multiple levels of parents - thus, if #100 is the parent of #101, which is the parent of #102, object #102 checks itself, #101, and #100 for attributes. Attributes are checked on the object itself first, followed by its parent, followed by that parent's parent, and so on. There is a (configurable) maximum length of the parent chain for an object; the default is 10.

  After the parent chain is exhausted, the type-specific ancestor is also checked in similar fashion. See 'help ANCESTORS' for more about ancestors.

  Continued in 'help parents2'.
& PARENTS2
 
  Note that the only properties inherited are attributes and locks. In particular, flags and exits are NOT inherited from the parent object. Also, commands which walk the attribute list (such as "examine", the LATTR() function, the HASATTR() function, @set, and @edit) only affect attributes that are on the object itself, although there are variants which also check parents (examine/parent, lattrp(), hasattrp(), etc).
  
  There are some limitations to the use of @parent. The most important is that ^-pattern checking is not done on the parent of an object, unless the object is set LISTEN_PARENT. For the purposes of automated game checks, the following attributes are not inherited:
    CHARGES, EALIAS, LALIAS, LAST, LASTSITE, LISTEN, QUEUE, RQUOTA, SEMAPHORE, and STARTUP.
    
  Continued in 'help parents3'.
& PARENTS3
  If a child and its parent both have the same attribute set, the attribute on the child will always be used first. However, a child can use the pfun() function to get the value of an attribute from its parent, even when it has an attribute with the same name.

  For example:
    > &TEST Bar=$test:@emit I'm the parent ([name(me)])
    > &TEST Foo=$check:@emit I'm the child ([name(me)])
    > @parent Foo=Bar
    > test
    Huh?  (Type "help" for help.)
    > check
    I'm the child (Foo)

  Continued in 'help parents4'.
& PARENTS4
  If a parent has the same $-command name in a different attribute, however, BOTH the parent and child commands will execute:

  (continued from previous example)
    > &CHECK Bar=$check:@emit No, I'm the parent! ([name(me)])

    > check
    I'm the child (Foo)
    No, I'm the parent! (Foo)
 
  The attributes inherited from the parent are treated just like its own attributes by the child. Thus, when a $-command or @trigger is executed, "me", for example, refers to the child, not the parent, and the $-command's associated actions are performed by the child.

  @parent is most useful when several objects use common attributes. 

  Continued in 'help parents5'.
& PARENTS5
 
  While ancestors are checked for attributes at the end of the parent chain, they are NOT checked for $-commands or ^-listens.
  
  If you are "mass-marketing" your objects, you can create blank copies, and @parent those copies to a template object. You can then customize necessary attributes on the copy. When a buyer @chowns his copy, the parent does not change, so unless you're putting data into the parent that you want to make impossible to read, it's safe to allow the purchasers of your object to @chown their copy.

  Locks can also be inherited, but are flagged no-inherit by default. Use @lset to change that on a per-lock basis.

See also: @parent, $-COMMANDS, ATTRIBUTES, ANCESTORS, ORPHAN, pfun()
& PUPPETS
  A thing is turned into a puppet by setting the PUPPET flag on it. A puppet object is an extension of its owner and relays everything it sees and hears to its owner, except if it is in the same room as the owner (a puppet with the VERBOSE flag will relay even if it's in the same room). Things relayed by the puppet will be prefixed by the name of the puppet.

  Puppets are useful for keeping track of what is going on in two rooms at once, as extensions of a player (such as a pet, for example), or for testing code.

  You can control your puppets using the @force command. It is important to remember the DBREF numbers of your puppets so you can control them even if they are not in the same room with you. You can also have your puppets follow you by using the 'follow' command.

  See 'help puppets2' for examples.
& PUPPETS2
  An example of a puppet:

  > @create Punch
  Created: Object #18.
  > drop Punch
  Dropped.
  > @set punch=puppet
  Punch is now listening.
  Punch - PUPPET set.
  > @force punch=go north
  Punch has left.
  Punch> The Finishing Place
  Punch> 
  Punch> Obvious exits:
  Punch> Door <S>  
  > @force #18=:waves hello
  Punch> Punch waves hello
  > #18 say Hello.
  Punch> You say, "Hello."
  
  To have an object relay things it hears to players other than its owner, use @forwardlist.

See also: PUPPET, @force, DBREF
& QUEUE
  QUEUE

  The queue is the waiting line for action lists to be executed by the MUSH. Each time you enter an action list, it goes into the queue and stays there until its turn comes up, at which time the MUSH processes the commands and you see the results. The MUSH can execute several commands every second, so normally you see results right away.

  However, if there are too many action lists in the queue, there may be a slight delay, called lag. The more common cause of lag, however, is network delays between you and the MUSH. Action lists that were queued by another command (like @switch, @force, @wait, etc.) also have a small delay before they run.
  
Continued in 'help queue2'.
& QUEUE2
  There are actually several different queues in PennMUSH. Commands which are queued as a direct result of something done by a player go onto the Player queue (also called the Priority queue). Commands which are queued by other types of objects go on the lower priority Object Queue. This gives actions caused directly by a player a higher priority, to make the MUSH seem more responsive. Commands on the Object queue get moved to the Player queue after a 1 second delay.
  
  There is also a Wait queue, where commands queued via the @wait command go, and a Semaphore queue, where semaphore @waits go. These commands are moved to the Player or Object queue at the appropriate time, either when the @wait time elapses, or when the semaphore is @notified.
  
  You can see which commands are currently queued with the @ps command, and with the getpids(), lpids() and pidinfo() functions. Queued commands can be cancelled with @halt and/or @drain.

Continued in 'help queue3'.
& QUEUE3
  There are several @config options which affect queueing. The option 'player_queue_limit' controls how many action lists can be queued by one object at any given time. Wizards and objects with the Queue @power can queue more commands (equal to the player_queue_limit plus the current number of objects in the database, including garbage).
  
  Normally each object has its own queue count, but if the 'owner_queues' option is enabled, objects share a queue count with their owner.
  
  'queue_chunk' and 'active_queue_chunk' control how quickly commands are executed from the queue.
  
  It costs a certain number of pennies to queue an action list; the exact amount is set in the 'queue_cost' @config option. These pennies are returned after the action list is run. Sometimes, you'll lose a penny when queueing a command; the chance of this happening is controlled by the 'queue_loss' option.
  
See also: @ps, LOOPING, ACTION LISTS
& QUOTAS
  The Quota system controls how many objects a player may own. It is only used of the 'use_quota' @config option is set to Yes.
  
  Each object created normally costs one quota (though this can be altered with the 'quota_cost' @config option), and every player starts with a fixed amount of quota, controlled with the 'starting_quota' @config option. Whenever you create an object of any type, your remaining quota, stored in the RQUOTA attribute, is decreased by the quota_cost.
  
  Wizards can give specific players (for example, builder characters) unlimited quota by giving them the No_Quota @power.
  
  You can view your current quota with the @quota command. Wizards can adjust a specific player's quota qith the @squota command, and God can see or alter all players' quotas with @allquota.
  
See also: @quota, quota(), Quotas Power, No_Quota Power
& REGEXP
& REGEXPS
  (This help text is largely from TinyMUSH 2.2.4, with permission)

  The majority of matching in MUSH is done with wildcard ("globbing") patterns. There is a second type of matching, using regular expressions, that is available in certain circumstances.

  For attributes that are $-commands or ^-listen-patterns, setting that attribute "regexp" (with '@set <object>/<attribute>=regexp') causes patterns to be matched using regular expressions rather than globbing. In addition, the function regmatch() performs regular expression matching.
 
  In a regular expression match, the substring of the string which matched the regexp pattern is %0; %1 through %9 are the substrings of the string which matched parenthesized expressions within the regexp pattern.
 
  Continued in 'help regexps2'.
& REGEXPS2
  Regular expressions are extremely useful when you want to enforce a data type. For example, if you have a command where you want a player to enter a string and a number ('+setnum <player>=<number>', for example), you might do it like this:
 
    > &DO_NUM Command Object=$^\+setnum (.+)=([0-9]+)$: @va me=Data: %1 = %2
    > @set Command Object/DO_NUM=regexp
 
  Then, '+setnum cookies=30' would set VA to "Data: cookies = 30". This eliminates your having to check to see if the player entered a number, since the regular expression matches only numbers. Furthermore, the '+' guarantees that there needs to be at least one character there, so a player can't enter '+setnum cookies=' or '+setnum =10' or similarly malformed input.
 
  The '+' sign in the command has to be escaped out, or it is taken as a regexp token. Furthermore, the pattern-match has to be anchored with ^ and $, or something like 'try +setnum cookies=30 now' would also match.
  
  However, keep in mind that players who attempt to use the command and give invalid input (such as "+setnum cookies=thirty") will receive the normal, non-descriptive Huh? message. Using a broader match and validating the input in softcode, so you can give more descriptive error messages, may be desirable.
 
  Regular expression syntax is explained in 'help regexp syntax'.
& REGEXP SYNTAX
  PennMUSH uses PCRE for its regular expression engine. PCRE is an open source library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. The text below is excerpted from its man page. PCRE was written by Philip Hazel <ph10@cam.ac.uk>, and is Copyright (c) 1997-1999 University of Cambridge, England. You can find it at ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/

  (Note that in PennMUSH, if the regular expression is in an eval'd context (like an argument to regmatch), you'll have to do a lot of escaping to make things work right. One way to escape an argument like %0 is: regeditall(%0,\\W,\\$0) or similar).

  Regular expression matching in PennMUSH can be used on user-defined command or listen patterns. In this usage, regular expressions are matched case-insensitively unless the attribute has the CASE flag set. Regular expressions can also be matched in MUSHcode using regmatch(), regrab(), regedit, etc. function families, which usually come in case-sensitive and case-insensitive versions.
  
  Continued in 'help regexp syntax2'.
& regexp syntax2
  A regular expression is a pattern that is matched against a subject string from left to right. Most characters stand for themselves in a pattern, and match the corresponding characters in the subject. 

  There are two different sets of meta-characters: those that are recognized anywhere in the pattern except within square brackets, and those that are recognized in square brackets.  Outside square brackets, the meta-characters are as follows:

       \      general escape character with several uses
       ^      assert start of subject
       $      assert end of subject
       .      match any character except newline
       [      start character class definition
       |      start of alternative branch ("or")
       (      start subpattern
       )      end subpattern
       ?      0 or 1 quantifier (after a unit to quantify) or, minimal match (after a quantifier) or, extends the meaning of ( after a ( 
       *      0 or more quantifier
       +      1 or more quantifier

  Continued in '"help regexp syntax3'.
& regexp syntax3
  Part of a pattern that is in square brackets is called a "character class". It matches any character listed in the class. In a character class, the only metacharacters are:

       \      general escape character
       ^      negate the class, if the first character in the class
       -      indicates character range (e.g. A-Z, 0-4)
   [:NAME:]   A symbol for a group of characters that can vary according to the language the mush is using. See 'help regexp classes' for more information.
       ]      terminates the character class

  A backslash will escape most metacharacters, and can turn some normal characters into generic character types:

       \d     any decimal digit
       \D     any character that is not a decimal digit
       \s     any whitespace character
       \S     any character that is not a whitespace character
       \w     any "word" character (letter, digit, or underscore)
       \W     any "non-word" character
 
  Continued in '"help regexp syntax4'.
& regexp syntax4
  A backlash can also be used for two useful assertions -- conditions that must be met at a particular point in a match:

       \b     word boundary
       \B     not a word boundary

  A word boundary is a position in the subject string where the current character and the previous character do not both match \w or \W (i.e. one matches \w and  the  other  matches \W), or the start
  or end of the string if the first or last character matches \w, respectively.

  Continued in '"help regexp syntax5'.
& regexp syntax5
  Quantifiers specify repetition of characters. Four are available:
       *    match 0 or more of whatever came before
       +    match 1 or more of whatever came before
       ?    match 0 or 1 of whatever came before
	 {m,n}  match between 'm' and 'n' of whatever came before. if 'm' is omitted, it matches between 0 and 'n'. if 'n' is omitted, matches at least 'm'. Note the MUSH parser often requires escaping the braces and the comma.

  Quantifiers are usually greedy -- they match as much as possible. Adding a ? after a quantifier causes it to match as little as possible instead. 

  Continued in '"help regexp syntax6'.
& regexp syntax6
  Outside a character class, a backslash followed by a digit greater than 0 (and possibly further digits) is a back reference to a capturing subpattern earlier (i.e. to its left) in the pattern, provided there have been that many previous capturing left parentheses. A back reference matches whatever actually matched the capturing subpattern in the current subject string, rather than anything matching the subpattern itself. So the pattern

    (sens|respons)e and \1ibility

  matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". 

  You can give names to subpatterns and refer to them that way instead of using numbers.

   (?P<NAME>subexpr) (Note: Literal <>'s) is a named capture, and (?P=NAME) refers back to it. The above pattern might be written:
  
   (?P<word>sens|respons)e and (?P=word)ibility
   
  In a $-command, the value of the named pattern can be accessed via the r(<name>, args). Softcode functions which work with regexps allow you to access the named subpatterns via $<NAME> (the <> are literal here).

  Continued in '"help regexp syntax7'.
& regexp syntax7
  An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. There are two kinds: those that look ahead of the current position in the subject string, and those that look behind it.

  An assertion subpattern is matched in the normal way, except that it does not cause the current matching position to be changed. Lookahead assertions start with (?= for positive assertions and (?! for negative assertions. For example, Lookbehind assertions start with (?<= for positive assertions and (?<! for negative assertions.

  Assertion subpatterns are not capturing subpatterns, and may not be repeated, because it makes no sense to assert the same thing several times. If an assertion contains capturing subpatterns within it, these are always counted for the purposes of numbering the capturing subpatterns in the whole pattern.

  Continued in '"help regexp syntax8'.
& regexp syntax8
  PCRE's engine can also do conditional subpattern matching, embedded comments in regexps, and a bunch of other things. See a regexp book for details.
& REGEXP CLASSES
  In a character class, you can use a number of additional keywords that match certain types of characters. The keywords are enclosed in [: and :], within the character class, so the whole thing looks like [[:NAME:]].

  These keywords can be mixed with other things in the character class, like [ab[:digit:]], which will match 'a, 'b', or a digit. [:^NAME:] reverses the meaning of NAME - it expands to everything but characters that would match [:NAME:].

  Some recognized NAMEs:
   digit, for numbers. [[:digit:]] is the same as \d. [[:^digit:]] is the same as \D.
   alpha, for letters. 
   alnum, for numbers and letters.
   lower, for lower-case letters. 
   upper, for upper-case letters.
   word, for word characters. [[:word:]] is the same as \w. [[:^word:]] is the same as \W.
   space, for whitespace characters. [[:space:]] is the same as \s. [[:^space:]] is the same as \S.

  Continued in 'help regexp classes2'.
& REGEXP CLASSES2
  These keywords (Or the corresponding \codes) should be used instead of explicit ranges where possible to improve portability. For example, [A-Za-z] and [[:alpha:]] are not the same thing in languages with accented characters. 

  Examples:
    > say regmatch(foo_bar, lit(^[[:word:]]+$))
    You say "1"
    > say regmatch(foo bar, lit(^[[:word:]]+$))
    You say "0"  

  Other, less useful, character class keywords include ascii, cntrl, graph, print, punct, and xdigit.
& REGEXP EXAMPLES
  The regexp pattern '.' is equivalent to the wildcard '?'; it matches one and only one of an arbitrary character.
 
  The regexp pattern '.*' is equivalent to the wildcard '*'; it matches zero or more arbitrary characters. To match one or more arbitrary characters, the regexp pattern is '.+'.
 
  To match a string of numbers, use:       [0-9]+    or \d+
  To match a string of letters only, use:  [A-Za-z]+ or \w+
 
  See 'help regexp syntax' for a more detailed explanation.
& REGISTERS
  A register is essentially a little reserved piece of computer memory that can hold some variable information that you want to pass on to another command. There are thirty registers on the MUSH available via the %0-%9 substitutions and v(0)-v(9) and r(0,args) to r(29,args). There are also many setq registers available via %q- substitution (%q0 - %q9, %qA - %qZ and arbitrary names), or the r() function.

  The basic registers are filled with information that matches the wildcard pattern of the command trigger. (Before you say "Huh?", here's an example.)

    > &COMMAND me=$command *=*:@emit %0 is in register 0 and %1 is in register 1.
    > command whee=blert foo
    whee is in register 0 and blert foo is in register 1.

  Continued in 'help registers2'.
& REGISTERS2
  As you can see from the above example, the command trigger had two wildcards separated by a "=" sign. When the user types in the command with some words taking the place of the wildcards, the first register (register 0) is filled with whatever part of the command replaces the first wildcard (in this case, "whee") and the second register is filled with whatever replaces the second ("blert foo").

  They can also be filled with information that is passed by an @trigger command:

    > &SOMECODE me=@emit %0 is in register 0 and %1 is in register 1.
    > @trigger me/somecode=whee,foo bar
  whee is in register 0 and foo bar is in register 1.

  Please see 'help setq()' for more information about the setq registers.

See also: SUBSTITUTIONS, @trigger, USER-DEFINED COMMANDS, setq(), v(), r(), registers(), listq(), letq(), unsetq(), strmatch()
& RQUOTA
  RQUOTA

  This attribute tracks remaining building quota if it is implemented. It is settable in-game only by a wizard, and is only visible to wizards.

See also: @quota, @squota
& SEMAPHORES
  The most complicated thing about semaphores is their name. Before you try to use semaphores, you should first be familiar with the "@wait" command. If you are, then you know that normally, you type:

    @wait <number of seconds>=<action> 

  and the action takes place after that number of seconds has passed. With a semaphore, you instead type:

    @wait <object>=<action>
    @wait <object>/<number of seconds before timeout>=<action>

  and the action takes place after the object has been "notified" that its time for it to happen. You can also set a timeout -- if the object hasn't been notified by the time that number of seconds has passed, the action will take place. Any object (player, thing, exit, room) that you control or that is set LINK_OK can be used to wait actions on.

  Continued in 'help semaphores2'.
& SEMAPHORES2

  An object is notified using the "@notify" command. When you type "@wait <object>=<action>", you are adding one to the SEMAPHORE attribute on the object. When you type "@notify <object>", you are decreasing the SEMAPHORE attribute on the object by one. Whenever the attribute decreases, one of the actions waiting on the object takes place. The actions occur in the order they were added.

  You can make the semaphore attribute of an object negative by @notify-ing it more times than things have been @wait-ed on it. If you do so, anything @wait-ed on the object will add one to the SEMAPHORE attribute and the action will take place immediately. You can also make all the actions waiting on an object take place right away by using "@notify/all", or wipe all the commands out and clear the SEMAPHORE attribute by using "@drain". Please note that all SEMAPHORE attributes are cleared out whenever the MUSH is restarted.
 
  Semaphores can be used to make sure that events occur in the right order, or to make sure that two players can't use the same object at the same time.

  Continued in 'help semaphores3'.
& SEMAPHORES3

  It's important to remember that the actions will be carried out NOT by the object that they are being @waited on, but by whichever object entered the @wait.

  Examples:
    > @wait semaphore=:tests.
    > @notify semaphore
    Wizard tests.
  
    > @wait timer/30=:waits 30 seconds.
    [ 30 seconds passes. ]
    Wizard waits 30 seconds.
 
  Continued in 'help semaphores4'.
& SEMAPHORES4
  Semaphores can be used to enforce mutual exclusion - to prevent the same object from being used simultaneously by two players. The basic strategy is to ensure that the object always has a SEMAPHORE of -1, to enclose commands in an @wait, and to conclude the set of commands with an @notify me:

    > &doit obj=$doit: @wait me={&doer me = %n; @trigger me/report}
    > &report obj=say [v(doer)] did it!; @notify me
    > @startup obj=@drain me; @notify me
    > @notify obj
    > ex obj/SEMAPHORE
    SEMAPHORE [#1ic+]: -1
    > doit
    obj says, "Talek did it!
    > ex obj/SEMAPHORE
    SEMAPHORE [#1ic+]: -1

  If a second player types doit as well, the second player's command is put on the semaphore queue and not run until the @notify me at the end of the REPORT attribute. Note the STARTUP attribute - because semaphores are cleared when the MUSH starts up, you must insure that the object gets @notify'd once when it starts up.
  
  Continued in 'help semaphores5'.
& SEMAPHORES5
  Normally, semaphores use the SEMAPHORE attribute. However, other attributes can be used, as long as they follow a few simple rules: If the attribute is already set, it has to have the same owner (God) and flags as the SEMAPHORE attribute would (typically no_inherit, no_clone, and locked - see 'help @set' and '@atrlock'), and have a numeric or empty value. If it's not set, it can't be one of the built in attributes (See @list attribs) unless, naturally, it is SEMAPHORE.

  See the help on @wait, @notify and @drain for details, but, briefly, you can use named semaphores with <object>/<attribute> where you would normally just use <object> in those commands. This means you can't have an untimed semaphore on an attribute with a numeric name.

  See 'help semaphores6' for an example.

See also: @wait, @drain, @notify
& SEMAPHORES6
  An example:
 
  > @wait me/semtest=think blah
  > ex me/semtest 
  SEMTEST [#1ic+]: 1
  > @ps
  ...
  Semaphore Queue:
  [#8/SEMTEST]Raevnos(#8P):think blah
  ...
  > @notify me/semtest
  Notified.
  blah

  This allows you to use one object to control many different things -- for example, fights in a turn-based combat sytem.
& SETTING-ATTRIBUTES
& SETTING ATTRIBUTES  
  Standard attributes are set using @<attrib> <obj>=<value>
  Nonstandard attributes are set using &<attrib> <obj>=<value>
  Attributes may also be set using @set <obj>=<attrib>:<value> or the attrib_set() or set() functions.
  
  Attributes are cleared using @<attrib> <obj> or &<attrib> <obj>, attrib_set(), or with @wipe or wipe().
  
  Note that if the empty_attrs configuration option is set (@config empty_attrs to check), there is a difference between clearing an attribute and setting an attribute to a null value:
    @va me       <--- wipes out my VA attribute
    @va me=      <--- sets my VA attribute to be empty
  
  Empty attributes retain their flags and atrlock status. Wiped attributes are gone forever.
  
See also: ATTRIBUTES, NON-STANDARD ATTRIBUTES, @set, @wipe, attrib_set(), set(), wipe(), ATTRIBUTE FLAGS
& SPOOFING
  Spoofing is the act of making other characters think that a person said or did something that they did not. This is very easy to accomplish, and has some good effects, which is why it is allowed. However, abusing it is very twinkish and will most likely get you in hot water with your wizards. Note that if you are being spoofed and want to know who is doing it, you can set yourself NOSPOOF and you will be notified who is making the @emits.
  
  Most @*emit commands have a wizard-only @ns*emit version, which does not show nospoof information. These are useful for writing global commands.
  
  Some @*emit commands also take a /spoof switch, which causes nospoof information to show that sound originated from the enactor (%#) instead of the executor (%!). This switch allows staff to write global $-commands for speech which show more helpful nospoof tags.

See also: @emit, @pemit, @remit, @oemit, NOSPOOF, PARANOID
& STACK
  For those unfamiliar with the term stack, it refers to a programming data structure that follows a LIFO (Last-In-First-Out) principle. The stack in MUSH holds the REGISTERS. The first ten registers can be accessed via the %0-%9 %-substitutions and v(0)-v(29), while all 30 registers can be accessed via the r() function (r(0, args) up to v(29,args)).
  
  When using regexp $-commands with named subpatterns, the named arguments can be accessed via r(<name>, args).
  
See also: REGISTERS, r(), v()
& STRINGS
  A string is simply a bunch of characters. A word is a string that begins and ends with the space character. A sentence is a string made up of smaller substrings that are words. Please note that a "word" or "sentence" in this technical sense does not have to make sense in English (or in any other language, for that matter). As far as mush functions and commands are concerned, this is a perfectly good sentence:

        Foozle 09blert bar baz foo.

See also: string functions
& %
& %b
& %t
& %%
& SUBSTITUTIONS
  The % symbol is used in MUSH commands to indicate a substitution -- some other character(s) or words are substituted for whatever follows the % symbol. Some common substitutions are:

     %b = a single space (just like [space(1)])
     %r = a blank line
     %t = A tab. Note that this may not look right on some screens.
     %# = dbref of the ENACTOR (object that set off the command)
     %n = the ENACTOR's name
     %N = the ENACTOR's name, first letter capitalized
     %~ = the ENACTOR's accented name, like accname(%#)
     %: = the ENACTOR's unique identifier, like objid(%#)
     %k = the ENACTOR's name, colored by @moniker, like moniker(%#)
     %% = a literal %
     
  Case makes a difference in all substitutions; capitalizing the first letter after the % will capitalize the first letter of the resulting substitution.

  Continued in 'help substitutions2'.
& SUBSTITUTIONS2
& %2
& %v
& %w
& %x
  If the ENACTOR's gender is set, you can use these substitutions to get the
  right pronoun for him/her:
     %s = subjective pronoun: he, she, it, they. Same as subj(%#)
     %o = objective pronoun: him, her, it, them. Same as obj(%#)
     %p = possessive pronoun: his, her, its, their. Same as poss(%#).
     %a = absolute possessive: his, hers, its, theirs. Same as aposs(%#).

    Case makes a difference: %S will return He, She, It, They.

  Some attributes can be retrieved via substitutions:
     %va-%vz = the contents of the object's VA-VZ attributes, respectively
     %wa-%wz, %xa-%xz = as above, for WA-WZ and XA-XZ
  These are the equivilent of get(me/<attribute>).

  Continued in 'help substitutions3'.
& SUBSTITUTIONS3
& %3
& %L
& %c
& %u
& %?
& %=
& %+
  Other substitutions:
    %0-%9   = the contents of the REGISTERS 0-9, respectively
    %@ = the caller's dbref number. Initially same as %#, changes when something like ufun() is called.
    %! = the dbref number of the object the command is on (the EXECUTOR)
    %L = the dbref of the ENACTOR's location
    %c = text of the last command, _before_ evaluation
    %u = text of the last command, after evaluation, available to locks/hooks
    %? = The current function invocation and depth counts
    %= = The dbref/attribute currently being evaluated
    %+ = The number of arguments passed to the current ufun.
    %qN = the equivalent of r(N), a register set by a setq() function.
    %q<N> = the equivilent of r(N) for a named register
    %iN = equivilent of itext(N), the list element for iter()/@dolist.
    %$N = equivilent of stext(N), the <string> in switch()/@switch.
 
  See 'help substitutions4' for examples.
See also: EVALUATION, ENACTOR, EXECUTOR, DBREFS, REGISTERS, v()
& SUBSTITUTIONS4
& %4
  Example: 

  > @sex me=male
  > @drop box=%n just dropped %p box.
  > drop box
  Cyclonus just dropped his box.
 
  Let's say that Cyclonus's dbref number is #10 and the box's dbref number is #11. The dbref of the room Cyclonus is standing in is #13. When Cyclonus dropped the box above, these were the values of the following %-subs:
  
  %n = Cyclonus
  %# = #10
  %@ = #10
  %! = #11
  %L = #13

& SUCCESS
  A "success" normally occurs when you attempt to do something that is restricted by an @lock and you pass the @lock. (Note that if no lock is set, you automatically pass it.) For example, the "basic" lock restricts who can pick up a player/thing or who can go through an exit. Whenever you successfully do either of these things, you will set off the basic success messages on the object whose lock you have just successfully passed.

  Many other actions can also be locked - see @lock and locktypes for more information. Many of these actions have standard attributes that you can set messages in for when someone succeeds.

See also: FAILURE, @lock, VERBS, ATTRIBUTES, @success, @asuccess, @osuccess
& SWITCHES

  Commands can have "switches" which modify the behavior of the command. Switches are attached after the end of a command. For example, most people are familiar with the command

    @lock me==me

  The "enter" switch to @lock allows you to lock who can enter:

    @lock/enter me==me

  A command may have multiple switches:

    @pemit/noeval/silent me=Hi!

  Help on the switches available for a command is available in the help file for that command.
  (If you are looking for information on @switch, see 'help @switch'.)
& TYPES OF OBJECTS
& TYPES
& OBJECTS
  Everything on a MUSH is an object in the MUSH database. There are four main types of objects: players, things (once called 'objects'), rooms and exits. You can see the type of an object when you 'examine' it, or with the type() function.
  
  There is also a 'garbage' type, used for objects which have been created and then @destroyed. Garbage objects cannot be used in any way, and their dbrefs will be recycled (with a new objid) when something new is created.
  
  For more information on any of the types, see 'help <type>'.
  
  The @stats command lists how many objects of each type currently exits in the database.

See also: type(), hastype()
& PLAYERS
  Players can be created at the login screen (or with @pcreate) and connected to. They can also receive @mail, and have a number of attributes set on them by the MUSH automatically, including LAST, LASTSITE, etc. They can have multiple @aliases, and are checked for $-commands and ^-listens.
  
  @linking a player sets their home.

See also: TYPES OF OBJECTS, type(), hastype(), @pcreate
& ROOMS
  Rooms are outermost-containers: they cannot be moved. They are created with @dig. Rooms can contain exits. They are checked for $-commands and ^-listens. Rooms do not have aliases.
  
  @linking a room creates a drop-to. Rooms have no location; loc() on a room returns its drop-to (as does home()).
  
See also: TYPES OF OBJECTS, type(), hastype(), @dig, DROP-TOS
& THINGS
  Things are created with @create. They can move around the MUSH, be entered and carried. They are checked for $-commands and ^-listens. Things do not have aliases.
  
  @linking a thing sets its home.
  
See also: TYPES OF OBJECTS, type(), hastype(), @create
& EXITS
  Exits are created with @open. They link rooms together, and can be used by players and things to move from one room to another with the GOTO command. Exits cannot move (though they can be @teleported to another room). They can have multiple aliases in their @alias. They are NOT checked for $-commands or ^-listens. Exits can have variable destinations; see 'help @destination' for more information.
  
  You can change the destination of an exit with the @link command. home() returns the source room of an exit, and loc() returns its destination.
  
  Setting an exit CLOUDY and/or TRANSPARENT causes its destination's description and/or contents to be shown after the exit's description when looked at.
  
  Sound is propagated through exits which are set AUDIBLE, as long as their source room (home) is also set AUDIBLE.
  
See also: TYPES OF OBJECTS, type(), hastype(), @open, @link, @destination, AUDIBLE
& GARBAGE
  Garbage objects previously existed as one of the four main types (player, thing, exit or room) but were destroyed with @destroy/@nuke. They exist only as placeholders in the database; you can do nothing with them. The dbrefs of garbage objects will be reused when new objects are created (but with a different creation time/object id).
  
  The total number of garbage objects, and the next garbage object to be recycled, is shown in @stats. You can use lsearch(all,type,garbage) to get a list of all garbage dbrefs.
  
See also: @destroy, @stats
& $-COMMANDS
& MACROS
& USER-DEFINED COMMANDS
  User-defined commands can be created by setting $-commands on players, things, and rooms. Exits cannot have $-commands. To set a $-command:

    &<attribute> <object>=$<command pattern>:<action list>
  
  Whenever someone in the same room as the object types the command name, the action list is carried out by the object, as long as:

  - the person typing the command passes the object's @lock/use and @lock/command
  - the object is not set NO_COMMAND or HALT

  Such attributes can also be @triggered as if the $<command name>: did not exist.

  It is recommended that <command pattern> not begin with "@", as many of PennMUSH's built-in commands start with "@". Conventionally, global $-commands are often named with the "+" prefix, and local $-commands commonly have a "+" or "." prefix.
  
  Continued in 'help user-defined2'.
& $-COMMANDS2
& MACROS2
& USER-DEFINED2
  Any number of wildcards, * and ?, may be in present in <command pattern>. A * matches any number of characters (including none), and ? matches exactly one character. When the action list is executed, the values on the stack in %0-%9 and v(10)-v(29) are the portions of what the user types that match the first 30 *'s or ?'s. You can also match a regular expression rather than wildcards by setting the REGEXP attribute flag on <attribute>; see 'help regexps' for details. When using named regexp captures, the named arguments can be accessed via r(<name>, args).

  For example, to make a 'wave' command, you could do the following:
    > &DO_WAVE me=$wave *: pose waves to %0.
  You could then type:
    > wave Guest
    Rhyanna waves to Guest.

  If a command would match, but the enactor can't pass the lock, the object may define generic failure behavior by setting the COMMAND_LOCK`FAILURE, COMMAND_LOCK`OFAILURE, and/or COMMAND_LOCK`AFAILURE attributes. These are triggered on all objects with matching commands and failing locks, but only if no command successfully matched, and take the place of the usual "Huh?" message.

  *BE SURE TO @LOCK/USE ME==ME IF YOU SET $-COMMANDS ON YOURSELF!*

See also: GLOBAL COMMANDS, EVALUATION ORDER, STACK, SUBSTITUTIONS, @lock
& VERBS
  Verb attributes are ones which are shown (or triggered) when you use a particular command, or perform a certain action. There are normally three: the 'verb' attribute (shown to the enactor), the 'overb' attribute (shown to others in the enactor's location), and the 'averb' attribute (an action list which is triggered). One example is @use, @ouse, and @ause, which are shown/triggered when the 'use' command is run on an object.
  
  Some verbs which involve movement have a fourth attribute, 'oxverb', shown in the enactor's old location (for example, @oxmove), while some verbs have less (for example, @oname/@aname are shown when an object's name changes, but there is no @name attribute).
  
  You can create your own verbs for softcoded commands/actions with the @verb command.
  
  Continued in 'help verbs2'.
& VERBS2
& NONAME
& NOSPACE
  Normally, the enactor's name and a space are prepended to the 'overb' and 'oxverb' attributes automatically. The NOSPACE attribute flag prevents a space being placed between the name and attribute value, and the NONAME attribute flag stops the name being added at all.
  
  Example:
    > @ouse Foo=has used Foo!
    > use Foo
    Sketch has used Foo!
    
    > @ouse Foo='s used Foo!
    > @set Foo/ouse=nospace
    > use Foo
    Sketch's used Foo!
    
    > @ouse Foo=Foo has been used by %n!
    > @set Foo/ouse=noname
    > use Foo
    Foo has been used by Sketch!
  
See also: @verb, attribute flags
& WARNINGS

  If the MUSH is configured to do so, players may receive regular warnings about potential building problems on objects that they own. The interval is set in the 'warn_interval' @config option; if set to 0, automatic warnings are disabled. You can also check warnings, either for a specific object or all objects you own, with @wcheck. 

  For more information, see the following help topics:
    @warnings        @wcheck         NO_WARN         WARNINGS LIST
    
& WARNINGS LIST
  The building warning system supports the following types of warnings:

  exit-unlinked         Warn on unlinked exits
  exit-oneway           Warn on exits with no return exit
  exit-multiple         Warn on multiple exits from A to B
  exit-msgs             Warn on missing succ/osucc/odrop/fail
  exit-desc             Warn on missing description
  room-desc             Warn on missing description
  thing-msgs            Warn on missing succ/osucc/odrop/fail
  thing-desc            Warn on missing description
  my-desc               Warn on missing player description
  lock-checks           Warn on @lock problems

  Continued in 'help warnings list2'.
& WARNINGS LIST2
  These warnings combine the functionality of multiple warnings above:

  serious      exit-unlinked, thing-desc, room-desc, my-desc, lock-checks
  normal       serious, exit-oneway, exit-multiple, exit-msgs
  extra        normal, thing-msgs
  all          all of the above

  The warning "none" indicates no warnings.
  You can exclude warnings from a larger list by using !<warning> after the larger list. For example: @warnings me=all !exit-oneway
& WILDCARDS
& *
& ?
& **
  PennMUSH has two standard wildcards, which can be used in $-commands, as well as a number of softcode functions: an asterisk (*) matches zero or more of any characters, and a question mark (?) matches exactly one character. The most common use of wildcards is to allow people to pass arguments to $-commands. For example, let's say you want to have a 'wave' command which allows you to wave to a specific person:
  
    > &cmd.wave me=$wave *: pose waves.
  
  The "*" wildcard will match anything, allowing you to type "wave foo", "wave bar", etc. You can use the %0-%9 substitutions to get the values which matched the first ten wildcards in the command:
  
    > &cmd.wave me=$wave *: pose waves to %0.
    > wave to Muse
    Mike waves to Muse.
    
  A backslash (\) can be used to escape * and ? if you want to match a literal asterisk or question mark.
  
  The "**" wildcard is also available for matching attribute names. See HELP ATTRIBUTE TREES2 for more information.
  
  It's also possible to use regular expressions, rather than wildcards, for matching strings. Regexps allow a lot more control over what is matched, but are therefore somewhat more complex. See 'help regexp' for details.
  
See also: USER-DEFINED COMMANDS, REGEXP, STACK, REGISTERS
& ZONE MASTER ROOMS
& ZMRs
  
  Zone Master Rooms are a subset of zones. If a room is used as a zone, it is called a Zone Master Room (ZMR). ZMRs are like local "master" rooms; exits in the ZMR are global to that zone, and $-commands on objects in the ZMR are global to that zone ($-commands on the ZMR itself, like $-commands on the master room, are ignored). If a ZMR is a player's personal zone, objects in the ZMR are checked for commands that the player can use anywhere (but exits are not checked unless the player is in a zoned room).

  Zone Master Rooms are useful either if you need global exits for the zone, or if the zone has a lot of $-commands which need to be restricted to different groups, as they can go on separate use-locked objects.

See also: ZONES, MASTER ROOM, EVALUATION
& ZONE MASTERS
& ZMPs
& SHARED PLAYERS
  SHARED PLAYERS
 
  Shared players are player objects which are used to mediate shared control of objects. A shared player is an object of type PLAYER which has the SHARED flag set. They are created like ordinary players, and can connect, build, etc. The only difference is that objects owned by a shared player are controlled by anything that passes the @lock/zone of the shared player.
  
  Anyone who passes the @lock/zone of the shared player can @chown objects to it. This, however, does not refund the original creator's money or quota, as does normal.

  Shared players used to be known as Zone Masters. The term was changed to emphasize the fact that they are not related to Zone Master Objects, which are used to allow area-specific $-commands.

  Continued in HELP SHARED PLAYERS2
& SHARED PLAYERS2
  Some suggested uses of shared players:
  
  1. If you are working on a building project with several people, it may be useful to create a shared player and @lock/zone it to all of you. That way, all of the players working on the project will be able to modify the building, as long as the shared player owns all the objects being built.
    
  2. If local wizards are desired, a shared player may be created and zone locked to the local wizards. Players building within that zone should be @chowning to the shared player, or logged in as it while creating objects. The local wizard will then be able to control anything within that domain as long as the object in question is owned by the shared player.
       
See also: SHARED, @lock, ZMO
& ZONES
& ZONE OBJECTS
& ZONE MASTER OBJECTS
& ZONE MASTER THINGS
& ZMOs
& ZMTs
  Zones are areas of the MUSH that can have the same user-defined commands without having to @parent every object in the zone or make the commands MUSH-wide globals.

  The default zone is NOTHING. Any building done by a player defaults to belonging to the same zone that the player belongs to. Every zone is defined by a Zone Master Object (ZMO). The ZMO is an ordinary MUSH object owned by some player. A wizard may change the zone of an object or player to a ZMO.
  
  If the ZMO is a room, it is called a "Zone Master Room." Most of the statements about ZMOs also apply to zone master rooms; for details, see 'help Zone Master Rooms'.
  
  See 'help zones2' for more.
& ZONES2
  $-commands on a ZMO are treated as global within that zone. The game attempts to match $-commands for the ZMO of the player's location, as well as $-commands for the player's own zone.

  If you want restricted global commands defined over only a small area, you can define that area to be part of a zone, and place the desired $-commands upon the ZMO. If you want players to be able to use special commands for a culture they belong to, the $-commands should go on the ZMO, and the players @chzoned to it so they can use the commands anywhere.

See also: @chzone, SHARED PLAYERS
& MATCHING
  Matching is the process the MUSH uses to determine which object you mean when you try to do something with an object. Different commands and functions do matching in different ways, but most will allow you to specify an object as:
    * its dbref (#7) or objid (#7:123456789)
    * the string "me" (yourself)
    * the string "here" (the room you're in)
    * a '*' followed by a playername (*javelin)
    * its full name (Box of chocolates)
    * part of any word in its name, if nothing else shares that part (Box)

  Using the object's name only works if the object is near you.

  You can usually qualify an object with an adjective (English matching) to help the MUSH determine which object you mean Adjectives include:
    * my <obj> - an object you're carrying
    * this <obj> - an object in your location (also: this here <obj>)
    * toward <exit> - an exit in your location
    * 1st, 2nd, etc. <obj> - one of a set of objects with the same names. Objects are ordered in the order in which they're listed in your inventory, room contents, and exit list (in that order). If there aren't enough objects, this will fail.	You can use an adjective with an ordinal (my 1st <obj>, this 2nd <obj>, etc)

  In commands that take a list of space-separated names (like page), you'll need to enclose names with spaces in "double quotes". The same is true on the login screen. For example:
    page "Leeroy Jenkins"=Stop doing that.
& &HELP
This is the AHELP index.
& RESTRICT

  Commands, functions and attributes can have their permission levels controlled in the mush config files, or by wizards from the game via @command, @function and @attribute.
 
  In the config file, the syntax is:
    restrict_command <command-name> <restriction> [" <error message>]
    restrict_function <function-name> <restriction>
    restrict_attribute <attribute-name> <restriction>

  From the game:
    @command/restrict <command-name>=<restriction> [" <error message>]
    @function/restrict <function-name>=<restriction>
    @attribute/access <attribute-name>=<restriction>
 
  For commands, if <error message> is given, that message is sent to the player who runs it instead of a generic, unhelpful error message.

  Continued in 'help restrict2'.
& RESTRICT2

  For commands, <restriction> should be an @lock-style boolexp (though, for backwards compatability, the restrictions below can be used, and will be converted into an @lock automatically). For functions, <restriction> should be any combination of the phrases below. For attributes, <restriction> is a list of attribute flags, or "none" to create a standard attribute with no restrictions (see 'help attribute flags').

    god        Command or function is usable only by God.
    wizard     Usable only by wizards.
    admin      Usable only by Wiz/Roy.
    nogagged   Usable only by non-GAGGED objects.
    nofixed    Usable only by non-FIXED objects.
    noguest    Usable only by non-guest @powered objects.
    nobody     Nothing can use it. Same as the /disable switch to @command or @function.
    logname    When used, log cmd/fun name, and who is using it
    logargs    When used, log cmd/fun name and args, and who is using it
              
  Functions only:             
    noparse    Function arguments are not evaluated. Only applies to @functions.
    localize   %q-registers are saved/restored when evaluating, as if the @function were wrapped in localize().
    userfn     Function can only be called from within an @function.
    nosidefx   Don't allow side-effects for this function. See also the function_side_effects @config option.
    deprecated This function should no longer be used. Warns the executor's owner whenever someone uses the function.

  Commands only:
     noplayer   Cannot be used by players.
  Commands can also give any flag, power or type, to restrict to objects with one of those flags or powers, or of one of those types.

  Continued in 'help restrict3'.
& RESTRICT3
  In cases where there are a function and command that do the same thing (like pemit() and @pemit), the command's restrictions are also checked when the function is called, so to use pemit() you must also be able to use @pemit. However, a function's restrictions are not checked when a command is called, to allow disabling side-effect functions.

  Some functions (like name()) have non-side-effect and side-effect versions depending on how many arguments they're called with. The side-effect version can be disabled while keeping the safe non-side-effect form with the 'nosidefx' restriction. This can also be used to disable pure side-effect functions.
 
  Examples:
  Only allow admin to use ansi():
    > @function/restrict ansi=admin
    
  Don't let anyone set SUSPECT or GAGGED use @emit, and log the name of anyone who uses it.
    > @command/restrict @emit=logname
    > @command/restrict @emit=!flag^suspect&!flag^gagged

See also: @command, @function, @attribute, @lock
& DESCRIPTOR
& PORT
  A descriptor (also called a port or socket descriptor) is a unique (though reusable) number assigned to each connection to the MUSH. The descriptor for each connection is shown on the Wizard WHO in the 'Des' column.
  
  Several commands and functions take a descriptor as an argument, or return the descriptor(s) associated with a player's connection.
  
See also: WHO, ports(), lports(), player(), @boot, CONNECTION FUNCTIONS
& UNICODE

At the moment, PennMUSH has very minimal support for Unicode. Almost all text is treated internally as being in the Latin-1 character set. Clients that support telnet character set negotiation can send and receive UTF-8, but only characters in the Basic Latin and Latin-1 Supplement blocks are accepted (Others are replaced with question marks).

A few functions support Unicode-aware text transformations:

    stripaccents()

When the MUSH is compiled with the ICU library (See @config compile), additional functions support Unicode-aware text transformations:

    lcstr2()     ucstr2()

When using these functions, do not assume that they return the same number of characters as their argument.
& 1.7.4p20
Version 1.7.4 patchlevel 20		       September 19, 2002

Fixes:
  * Help semaphores4 typo fixed by Mike Griffiths.
  * Help cleanup. [TAP]
  * See_All players now see hidden connected mail senders. Suggested
    by Philip Mak.
  * spellnum could introduce spurious spaces. Reported by Intrevis@M*U*S*H.
  * table() sometimes produced spurious blank rows. Reported by
    Nymeria@M*U*S*H. This is the first attempt at a fix.
  * switch() help improved. [SW]
  * enter <exit> no longer returns Permission denied, but 
    "I can't see that here", as you can only enter things. 
    Suggested by Philip Mak.
  * A one-time, one-pointer memory leak in plyrlist.c fixed
    by Vadiv@M*U*S*H.
  * Unbalanced or empty double-quotes gave weird results in page 
    and whisper. Reported by Vadiv@M*U*S*H. [SW]
  * @chan/decomp no longer shows names of channels that the enactor
    can't see. Reported by Nat@SW:ANT.
  * The lock() and elock() functions now operate properly with
    user:whatever locks. Reported by Mike Griffiths.
  * pmatch() will locate hidden players if they're visible to you
    because they're nearby. Suggested by Julian@M*U*S*H.
  * regedit and other functions that used $-substitutions for subpatterns
    could produce weird results in some cases. Reported by Bellemore@M*U*S*H


& 1.7.4p19
Version 1.7.4 patchlevel 19		       June 14, 2002

Minor changes:
  * Wizards can now unset the WIZARD flag on any thing, whether they
    own it or not. Suggested by Cerekk@bDv.
  * Circular zoning is no longer allowed. Fixes part of a bug reported
    by Philip Mak. [SW]
Fixes:
  * Win32 portability fixes. [EEH]
  * grep for 'grep' rather than 'egrep' in restart because in grep 2.5.1,
    egrep is a shell script that exec's grep instead of a link.
    Fix by Vadiv@M*U*S*H.
  * The messages for a possessive get used the object's new location
    instead of its old one. Fixed by Apollo@Restoration.
  * Attempts by unlinked exits to @link an exit could crash. 
  * %1 in @areceive was being set to the recipient rather than the giver.
    Fixed. Report by jubjup@trekmush.org
  * @uptime fix for Linux 2.4 kernel. [SW]
  * The @@() function no longer complains about commas. Report by
    Trispis@M*U*S*H. [TAP]
  * @search flags=<flaglist> is now smarter about toggles with the same
    letter and different types. Report by Philip Mak.
  * English-style matching now ignores the type of object being matched.
    This fixes a bug with, e.g., @link my 1st object=me reported by
    Oriens@Alexandria.
  * bound() now listed in the math functions list. Report by Dandy@M*U*S*H.
  * Help fix for member() by Cerekk@bDV TrekMUSH
  * The server can now transparently read mush.cnf (and included) files
    that have Dos- or Mac-style line-endings. Suggested by Paleran.
  * Crash bug in @search fixed. Reported by Philip Mak.

& 1.7.4p18
Version 1.7.4 patchlevel 18		       May 6, 2002

Minor Changes:
  * The Mersenne Twister RNG has been backported from 1.7.5 into
    this patchlevel, as it is not susceptible to some bugs that could
    cause the RNG to hang the server. Report by Bellemore@M*U*S*H.
  * Improved detection of info_slave errors. Based on patch by CU5.
  * Rooms and exits can now be @forced. Suggested by Philip Mak.
  * Deleting files from the hlp/nws/etc. directories is now sufficient
    to cause game/txt/Makefile to rebuild the txt files. Patch by
    Philip Mak.
  * A see_all player may now use @chan/decompile on any channel.
    Previously, the ROYALTY flag was required. Suggested by Oriens@Alexandria.
Fixes:
  * The QUEUE and semaphore attributes aren't listed in @decompile
    anymore. Suggested by Oriens@Alexandria. [SW]
  * Several compiler warnings fixed. [SW]
  * The LASTSITE and LASTIP attributes are now set locked and wizard by default,
    to go along with the other connection-tracking attributes. [SW]
  * Help on-vacation updated. Report by Nymeria@M*U*S*H.
  * Help for following() function added. Report by Ashen-Shugar@Rhost.
  * The last line of the access.cnf file sometimes wouldn't get read 
    properly. [SW]
  * lnum improperly cached its return values without consideration for
    changes in separator, so subsequent lnums with different separators
    broke. Reported by Rhysem and Ambrosia@M*U*S*H. [TAP]
  * Failing to speak on a channel you can't see no longer reveals the
    full channel name. Reported by Vadiv@M*U*S*H.
  * Passing a negative argument to the space() function now returns
    an error string instead of 8192 blanks. Patch by Myrddin.
  * Improved messages for following/unfollowing an ambiguous object.
    Reported by Philip Mak.


& 1.7.4p17
Version 1.7.4 patchlevel 17		       April 14, 2002

Minor Changes:
  * The on-vacation flag, if in use, is no longer automatically cleared
    on connect. Instead, the player is warned on connect (and at each
    dump) that their flag is set. Suggested by Nymeria@M*U*S*H.
Fixes:
  * Improved help for edit(). Suggested by Trispis@M*U*S*H [SW]
  * List functions with null elements and a null output seperator could
    trip end-of-buffer checks and stop in the middle of a list. [SW]
  * valid() was inconsistent in how it handled attribute names with lower-case
    letters compared to what everything else does. Reported by Philip Mak. [SW]
  * @open could cause crashes in some unusual contexts. Reported
    by Dandy@M*U*S*H.
  * Improved sort()'s autodetection of list types. [SW]
  * Fixed a problem with sorting dbrefs larger than the highest one in the 
    db. [SW]
  * Mac portability fixes. [DW]
  * Help for @open clarified. Suggested by fil@M*U*S*H.
  * Help for kill clarified. Suggested by Philip Mak.
  * Channel titles can no longer contain newlines or beeps. 
    Report by Nome@M*U*S*H.
  * soundex behaved badly with extended characters. [SW]
  * inc() and dec() now behave like the help says, regardless of whether
    tiny_math is set or not. Their behavior on null strings and strings
    that do not end in a digit depend on the null_eq_zero setting.
    Reported by Wayne@PDX.
  * The panic db file descriptor was never closed after reading a
    panic dump. [SW]
  * DOES removed from help attribute list. Suggested Philip Mak.
  * Under no circumstances should connection to a null-named player
    be allowed. Suggested by Wayne@PDX.
  * 'with' no longer allows use of $commands on remote objects you
    don't control. Report by Nammyung@M*U*S*H.

& 1.7.4p16
Version 1.7.4 patchlevel 16		       March 11, 2002

Minor changes:
  * After using 'register' at the connect screen, the player is
    no longer disconnected. Suggested by Philip Mak.
  * 'help mail functions'. Suggested by Trispis@M*U*S*H.
  * Messages associated with drop, give, and get are now more
    verbose and provide more information about who did what to whom.
    Suggested by Philip Mak.
  * Attrib locks did case-sensitive comparison of values, which is not
    what you probably want. No longer. Reported by Philip Mak. [SW]
  * QUEUE and sempahore attributes are now removed (not just emptied)
    when drained or notified to 0. [TAP]
Fixes:
  * Improvements in handling ansi in string functions. [SW]
  * @clone/preserve didn't preserve when cloning exits. Reported by
    Bellemore@M*U*S*H. [SW]
  * A significant bug in the manual notification of timed semaphores has 
    been corrected. [SW]
  * Revian@M*U*S*H pointed out that user-defined commands starting with
    "@" that match the names of standard attributes don't behave as
    you might expect. This is now documented in help user-defined commands.
  * Security checks for attribute setting used the owner of the setting 
    object, not the setting object itself. Report by Howie@New Frontier.
  * help set() improved based on report by Tareldin@M*U*S*H.
  * folderstats() did not behave as promised in the help. Now it
    does. Report by Trispis@M*U*S*H.
  * Typo in src/log.c fixed by Nathan Schuette.
  * Improved help for DEBUG. [SW]
  * Aliased 'help ^' to 'help listening2'. Suggested by Philip Mak.
  * MacOS portability fixes. [DW]
  * The sigusr1 handler would reinstall itself as the sighup handler
    on systems that don't provide persistent signals. 
    Fixed by Bellemore@M*U*S*H.
  * &a=b me now properly clears the attribute A=B. Reported by 
    Trispis@M*U*S*H. In addition, now @tel #1234= produces an error,
    as it should. [SW]
  * mail functions can now be called by an object on anything it controls
    (typically, its owner). Suggested by Trispis@M*U*S*H.
  * The givee is now correctly passed in %1 to @give/@ogive/@agive,
    and documented. Reported by Philip Mak.
  * Added hints for Irix 6.x by Vexon@M*U*S*H.
  * i18n fix for function invocation limit message.
  * Clarification in help @alias by Philip Mak.
  * @set obj=!puppet repeatedly no longer repeats the "not listening"
    message. Reported by Philip Mak.


& 1.7.4p15
Version 1.7.4 patchlevel 15		       February 8, 2002

Minor Changes:
  * @dolist and iter(), where multiple tokens are replaced (## and #@),
    now do both replacements at once. This is more efficient in several
    ways and fixes a problem where if the second token gets into the
    string from a replacement of the first, it gets replaced. (iter(a#@,
    ##) should return a#@, not a1). [SW]
  * setunion no longer eats empty list elements. [SW]
  * The help text for items() is now more descriptive of how it works
    and differs from words(). Suggested by Zen@SW1.
  * When you attempt to @chzone an object to a ZMO without a zone-lock,
    a default zone-lock of "owner of the ZMO" is now set, and the
    attempt succeeds. Suggested by Linda Antonsson.
  * In the French message translation files, the word 'drapeau' and
    'flag' were used interchangeably. I've standardized on 'flag'.
    Report by Vexon@M*U*S*H.
Fixes:
  * Message typo fixed by Bellemore@M*U*S*H.
  * No more ansified names in logged shutdown messages. Report by
    Bellemore@M*U*S*H.
  * Messages when destroying players now take into account the 
    destroy_possessions and really_safe settings. Suggested by Wayne@PDX.
  * The parser no longer strips any first layer of braces in, e.g.
    @switch action clauses, but only when the first character in the
    clause is a brace. This prevents @sw 1=1, @wait me={@emit 1; @emit 2}
    from being misparsed and running @emit 2 immediately. Reported by
    Azratax@Azmush. [TAP]

& 1.7.4p14
Version 1.7.4 patchlevel 14		       January 4, 2002

Minor Changes:
  * The global function invocation limit is now 5 times the per-evaluation
    function invocation limit, to provide some flexibility in cases
    where you run a small number of functions that cause a larger
    number of other functions to be evaluated (e.g., using tel()
    to move players into rooms with function-laden descriptions). [TAP]
Fixes:
  * Mortals are now restricted in which html tags they can generate
    when pueblo support is enabled. Suggested by BladedThoth.
  * @sitelock/name !<name> was improperly case-sensitive in its
    matching. Reported by Linda Antonsson.
  * Better invocation count checking and aborting on reaching limit.
    Reported by Ashen-Shugar. [TAP]
  * Beep characters are ignored when matching object listen patterns.
    Suggested by Wayne@PDX.
  * The end-of-dump marker is checked when reading the chat database.
    Suggested by Bellemore@M*U*S*H. [SW]
  * @lock obj=attrib:value locks were broken. Reported by Linda
    Antonsson.
  * Minor help fixes.

& 1.7.4p13
Version 1.7.4 patchlevel 13		       November 30, 2001

Minor changes:
  * options.h.dist mentions Darwin as well as MacOS X. [DW]
  * PCRE updated to 3.7. [SW]
  * When CHAN_NAME_LEN is increased beyond 30, the @chan/list header
    line is misaligned, and other strange things can happen to
    @chan/list. Reported by Bladed Thoth
Fixes:
  * Crash bug in chat channels reported by BladedThoth.

& 1.7.4p12
Version 1.7.4 patchlevel 12		       November 9, 2001

Minor changes:
  * @dol/delim is now @dol/delimit, for Mux compatibility. [SW]
  * /preserve switch for @chownall works like @chown's /preserve switch.
    This changes the default behavior of @chownall, which used to
    preserve everything, to work like @chown and strip privileged bits.
    Suggested by Taladan@M*U*S*H.
Fixes:
  * Warnings in index-files.pl are no longer shown. Report by Noltar@Korongil
  * Additional support for ansi in channel names. Ansi is now stripped
    when sorting channels and when matching names for @chan/decomp and
    @chan/what.  Reported by Oriens@Alexandria.
  * Help @decompile clarifies the /flags switch. Suggested by Oriens@Alexandria
  * Source is indented before diffs are produced.
  * Typo in help zmr correct by Oriens@Alexandria.
  * Players disconnecting without QUIT continued to use CPU until fully
    disconnected. Fixed. Report by Protagonist@M*U*S*H. [SW]


& 1.7.4p11
Version 1.7.4 patchlevel 11		       October 15, 2001

Minor Changes:
  * In places like switch() that can match <number, the numbers
    are now treated as floating point, so they need not be only integers.
    However, they must be pure numbers; "<3km" will not work.
  * Tests for channel name matches now disregard ansi. Suggested by Wayne@PDX.
Fixes:
  * MacOS linting. [DW]
  * next() could reveal unfindable players. Reported by Jeffrey@TheHotel. [TAP]
  * making diffs or a dist now insures that switches.h, etc. are rebuilt
    for the Mac/Win32 crowd. Reported by many people.
  * Some warnings discovered with compiling with gcc 3.0.1 fixed. [SW]
  * Potential crash-or-worse bugs that could be caused by malformed
    save messages fixed. [SW]
  * @mail to players with names starting with numbers works correctly now.
    Report from Mike Wesson. [SW]
  * Fewer logged warnings from failed convtime()s. [SW]
  * Help for page now mentions /blind. Reported by Oriens@Alexandria.
  * Attempting to set an invalid priv on a channel now produces a
    better message. Reported by Oriens@Alexandria.
  * Improved message when a Wizard overrides a chan join lock by Wayne@PDX.
  * Another way to end up inside yourself fixed. Report by Ashen-Shugar. [TAP]
  * Help default/edefault syntax clarified by Delina@ST:VAAE
  * Help math functions clarifies 'number'. Suggested by Delina@ST:VAAE
  * Information on the patches.h header added to the FAQ file. Suggested 
    by Kahmy. [SW]
  * Potential crash in @set fixed. Report by Michael Loftis [SW]
  * The Unfindable flag is checked on all levels of containers, not just
    the immediate location. Suggested by Oriens. [SW]
  * NT_TCP fix by Bellemore.
  * secure() now escapes ^, as the help says it does. Report by Gabriel Matlin.
  * link_anywhere now lets you actually @link anywhere, instead of just
    letting variable exits link anywhere. Report by Viila@M*U*S*H.
  * help home now returns help homes, not help home(). Suggested by 
    Gary Williams

& 1.7.4p10
Version 1.7.4 patchlevel 10		       September 7, 2001

Fixes:
  * @clone changes in p9 introduced a crash bug. Fixed.
  * Typo in mushcnf.dst fixed by Noltar@Korongil.

& 1.7.4p9
Version 1.7.4 patchlevel 9		       September 4, 2001

Minor changes:
  * @clone can optionally specify a new name for the clone.
    Patch by Bellemore@M*U*S*H, inspired by mux.
  * die() can take a third argument which, if true, will cause it to
    return the list of individual die rolls rather than the sum.
  * NT_TCP option moved to options.h.dist, and @config/list compile now
    reports whether it's on or not. Suggested by Glonk@GlonkMUSH
  * QUIET flag affects the "Teleported." message as well.
    Suggested by Glonk@GlonkMUSH.
  * pos() and strmatch() strip ansi and html markup before matching. [SW]
  * Slight optimizations for many of the functions that strip markup. [SW] 
  * chat_strip_quote setting now applies to @*wall and say. Suggested by
    Glonk@GlonkMUSH. [SW]
  * @malias/who is now the same as @malias/members. Suggested by
    Oriens@Alexandria.
  * Small code change in do_chat_by_name so that find_channel_partial_on
    can behave as documented. Suggested by Michael Loftis
Fixes:
  * p8 broke regeditall when the replacer was null. Fixed.
    Reported by Nymeria@M*U*S*H.
  * Some unused variables removed, and pcre.h included in parse.c.
    Reported by Sidney@M*U*S*H.
  * index-files.pl produced an uninitialized value warning if a help file
    had only a single entry (or admin entry). Warning removed.
    Reported by Nymeria@M*U*S*H.
  * Fixed to help lstats() to mention stats() as alias. Reported by
    Glonk@GlonkMUSH.
  * Help edit() fix by Sash@SW:Uprising.
  * Improved failure message for @password. Suggested by Mike Wesson. [SW]
  * alphamin()/alphamax() were stripping markup from what they returned. [SW]
  * PARANOID flag is now only visible to owners. Reported by 
    Bellemore@M*U*S*H.
  * Improved error message when trying to rejoin a channel. [SW]
  * In Win32 NT_TCP mode, ident lookups are now done and the LASTIP
    attribute doesn't get corrupted. Patch by Bellemore@M*U*S*H.
  * @chan/describe now works along with @chan/desc. Suggested by 
    Trispis@M*U*S*H
  * 'teach'ing a motion to a follower didn't work right. Reported by
    Cheetah and Viila@M*U*S*H.
  * Security bug in follow fixed. Reported by Walker@M*U*S*H.
  * The &ecirc; and &euml; entities were not correctly returned in
    Pueblo mode. Fixed by [NG].
  * Help for trig functions improved. [SW]
  * Pueblo references no longer give Chaco's (defunct) website.
    By Noltar@Korongil.

& 1.7.4p8
Version 1.7.4 patchlevel 8		       July 22, 2001

Minor changes:
  * restart is a bit more precise in the "Mush already active" message.
    Suggested by Lucas Layman.
  * When a player's creation is refused because creation/registration
    is globally turned off, show them register.txt instead of down.txt.
    Patch by Bellemore.
  * The NOSPOOF flag is now visible only to the player themself. [SW]
  * regedit can now use backreferences in the replacer. [SW]
Fixes:
  * ident lookups were broken on win32. Reported by Bellemore. [SW] 
  * ident query timeouts could get doubled mistakenly. [SW]
  * Typo in mushcnf.dst fixed by Noltar@Korongil.
  * Fix to help puppets2 by TurtleKnee@M*U*S*H.
  * Help pcreate() added. Report by Rince@M*U*S*H.
  * @pcreate messages capitalized by Oriens@Alexandria.
  * create() used 10 as the default cost, instead of the configured
    default. Report by 8bitMUSH.
  * Inactivity timeouts longer than 1 day didn't work. Fixed and
    efficiency of the check improved. Reported by Bellemore@M*U*S*H.
  * Null @aliases are no longer allowed. [SW]
  * Cleanup to ident for situations when the remote host isn't running
    an ident server. [SW]

& 1.7.4p7
Version 1.7.4 patchlevel 7		       July 02, 2001

Major changes:
  * %r can now evaluate to one character or two, based on a new config 
    option, newline_one_char, which defaults to being yes. This allows
    %r to be used as a list delimiter. However, this may
    break softcode which expects strlen(%r) to be 2, but it's probably
    smarter to fix the softcode than turn off this option. [sw]
  * If a command and a standard attribute have the same name, the
    command takes precedence. So if you have an @attribute named
    "PEMIT", @pemit me=foo will do the command, not set the attribute. [SW]
Minor changes:
  * When someone attempts to create too many attributes on an object,
    the log indicates who and which object. Suggested by Frob@Battlestar
    Galactica:TSC.
  * Buncha tprintfs replaced with notify_formats. [SW] 
  * New local_connect() and local_disconnect() hooks in local.dst.
    Suggested by Rince@M*U*S*H.
  * lookup_player now deals with player names prefixed with "*",
    so a bunch of commands like @newpassword will now treat those
    arguments. Suggested by Glonk@GlonkMUSH.
  * Make is more verbose about alerting you to changes in the 
    src/*.dst files.
  * The message for undestroying someone else's object more closely matches
    the destroy message. Suggested by Noltar@Korongil.
  * Server output that used to be tagged with "PRE" for Pueblo is now
    tagged with "SAMP", because the original Pueblo client did not correctly
    handle "<BR>\n" in PRE, and the newer clients that are supporting
    the pueblo protocol, like MUSHclient, do handle it correctly, causing
    an incompatibility problem. Our workaround is to avoid PRE. 
    Reported by [NJG].
  * The WHO list output is tagged <img xch_cmd=html> for Pueblo to get
    appropriate newline handling. [NJG]
  * help @mail mentions help @malias. Suggested by Trispis@M*U*S*H.
  * Matching code now treats players you can't see like disconnected players
    when matching *player. Reported by Walker@M*U*S*H.
  * @newpassword now confirms whose password was changed. Suggested by
    Xyrxwyrth@M*U*S*H.
  * @chan/who and cwho() now include objects on the channel. Suggested by
    Glonk@GlonkMUSH.
  * q-register lookup is slightly faster. [SW]
  * Floating-point numbers in exponential format (6.02e23) are always
    accepted, not just when tiny_math is set. [SW]
  * isint() and isnum() ignore the null_eq_zero option, since they already
    ignore tiny_math. [SW]
  * time() and convsecs() take an optional timezone argument that,
    if 'UTC', makes them act the same way as utctime() and convutcsecs(). 
    From MUX2. [SW]
Fixes:
  * Additional range checking to avoid some bugs reported by Alierak. [SW]
  * Fix to buglet in @name error with PLAYER_NAME_SPACES reported by
    Luke@M*U*S*H.
  * Typo in @name error message fixed by Luke@M*U*S*H.
  * One could @pcreate players past the hard db limit. Reported by Z@Korongil.
  * Typos in config_h.SH and options.h.dist fixed by Oriens@Alexandria.
  * Under some conditions, you could double-join a channel.
    Reported by Xyrxwyrth@M*U*S*H, investigated by Steven@Champions.
  * Error message for @chan/desc improved. Reported by Oriens@Alexandria.
  * Typo in alias.cnf fixed by rodregis@M*U*S*H.
  * @mvattr sometimes failed to remove the old attrib, when it was a 
    standard attrib that could be abbreviated (@mvattr a/desc=b).
    Fixed by Walker@M*U*S*H.
  * Some english-matching (like 'get 1st foo') would fail. Reported by
    Mystery8.
  * Typo in help @verb reported by Greck.
  * MacOS tweaks. [DW]
  * Better detection of numbers that are too big. [SW]
  * Wizards could crash the server by entering objects in their own
    inventory. Reported by Howie@New Frontiers.

& 1.7.4p6
Version 1.7.4 patchlevel 6		       June 11, 2001

Minor changes:
  * English-style matching has been added to some more commands, 
    to help with the stricter ambiguity checking (@teleport my 3rd foo=box, 
    etc.). [SW]
  * @pemit/list no longer does its useless ## substitution. [SW] 
  * capstr() and art() skip leading ansi and html. [SW]
  * table(), alphamin(), alphamax(), comp(), lcstr(), ucstr(), strinsert(), 
    and delete() are all ansi and html aware. Mixing html and ansi in their 
    arguments is probably a bad idea, though. [SW]
  * reverse() and scramble() are ansi-aware, and still will break html, but 
    in a different way than before. [SW]
  * foreach() strips ansi and html from the string before doing its things. [SW]
  * Complete Norwegian translation by Kenneth Aalberg.
Fixes:
  * Bug in growing hash tables fixed. [SW] 
  * Typo in copyright fixed. Reported by Cheetah@M*U*S*H.
  * Unused variable removed from fun_ansi. Reported by Sidney@M*U*S*H.
  * Mac portability stuff. [DW]
  * Wizards could @chown garbage objects. [SW]
  * Wizards could give to garbage objects. [SW]
  * Wizards could read God's @mail. [SW]
  * Eliminated some compiler warnings. [SW]
  * mid() was quite broken with ansi. right() was less broken. 
    Both hopefully fixed for good. [SW]
  * Fixed a problem with the attribute used with foreach() evaluating from 
    the perspective of the wrong object. [SW]
  * before(), after(), and wrap() are now classified as string functions
    in the help. [TAP]
  * help wildcards now mentions ?. Suggested by cmintrnt@M*U*S*H.
  * help fixes by Jeff Ferrell.
  * Problems with wrap() when the text included %r%r (or started with %r)
    reported by Noltar@Korongil.
  * If you somehow managed to load a corrupt db with a parent loop,
    lparent could infinite-loop. Reported by Ashen-Shugar. [TAP]


& 1.7.4p5
Version 1.7.4 patchlevel 5		       May 25, 2001

Fixes:
  * Fix to uninitialized variable that could cause ansi to bleed
    on some systems. Patch by Luke@M*U*S*H
  * Prototypes for ansi_align and ansi_save added to externs.h. [DW]
  * FreeBSD hints file updated to get rid of a compiler warning. [SW]
  * Setting hate_dest to no will not disable @recycle [SW]
  * switchinc.c updated. [DW]


& 1.7.4p4
Version 1.7.4 patchlevel 4		       May 13, 2001

Minor changes:
  * Internally, the /folder switch is now /folders, which prefix-matches
    to /folder and also lets @mail/folders work as syntactic sugar.
  * fun_ansi has been rewritten to use less buffer space by consolidating
    ansi codes. New codes for turning off ansi attributes (like hilite)
    also added.  Patch by Luke@M*U*S*H.
  * /silent switch to give suppresses default messages when giving
    money to players. Suggested by 8BitMUSH.
  * Old port concentrator code removed. [SW]
  * On linux, @uptime reads /proc files instead of running 'uptime' [SW]
  * Code that uses strdup and then adds a MEM_CHECK record for "string"
    now use a wrapper function that does it automatically. [SW]
Fixes:
  * Paging a page-locked player didn't give the appropriate messages.
    Reported by Steven@Champions.
  * left, right, and mid are now ansi-aware. Patch by Luke@M*U*S*H.
  * Help fixes to lexits(), name() (Noltar@Korongil), 1.7.4p3 (Z@Korongil).
  * win32/cmds.h updated with prototypes for dismiss and desert by
    Noltar@Korongil. And hdrs/externs.h, too, by [SW].
  * Memory leak with using alphabetic q-registers in queued commands fixed.
    Report by Jayvin@Dynamix [SW]
  * Added hints/openbsd.sh to distribution.
  * Mac portability linting. [DW]
  * Several memory leaks in @malias code fixed. [SW]

& 1.7.4p3
Version 1.7.4 patchlevel 3		       April 23, 2001

Commands:
  * unfollow with no args now stops you from following everyone.
    dismiss command stops people from following you.
    desert command stops people from following you or leading you.
    Idea by Oriens@Alexandria. Names suggested by Noltar@Korongil
Minor changes:
  * MONITOR announcements of disconnects distinguish hidden disconnects.
    Suggested by Oriens@Alexandria.
  * The Uptime field of INFO shows first start time, not last reboot time.
    Suggested by Trispis@M*U*S*H.
Fixes:
  * Exact matches are now preferred over partial matches, and no longer
    result in ambiguity. Report by Steven Viscido.
  * Message mentioning INHERIT changed to TRUST by Xyrxwyrth@M*U*S*H.
  * Distributed register.txt file is now more descriptive. 
    Suggested by Xyrxwyrth@M*U*S*H.
  * The ctime(), mtime(), restarttime(), and starttime() functions now 
    return 2-digit days (01 vs. 1). Reported by Z@Korongil.
  * @malias output uses the alias token more consistently. Suggested by
    Kyieren@M*U*S*H.
  * hints/solaris_2.sh modified a bit.
  * Mac portability fixes
  * Options.h clarification suggested by rodregis@M*U*S*H.
  * Cosmetic bug in @halt fixed. Report by Trispis@M*U*S*H.
  * Fixed a fencepost error in regedit*() that could generate garbage text.
    Reported by Vadiv@M*U*S*H


& 1.7.4p2
Version 1.7.4 patchlevel 2		       March 23, 2001

Major changes:
  * The object matching routines have been modified. Some things you may
    notice:
    * Ambiguous cases are more often reported as such (rather than you
      getting one of the ambiguous matches arbitrarily).
    * locate() now returns #-2 as promised. Reported by Jeff Ferrell.
    * A few functions that used accept player names now require
      the use of *playername to match the player (e.g. mail(), hidden()).
      (This is generally more consistent).
Minor changes:
  * @tr of a nonexistent attribute now reports that. Report by Z@Korongil.
  * TEL_OK is an alias for JUMP_OK. Suggested by Kyieren@M*U*S*H.
  * Added 'help i18n' (aka help translation). Suggested by Kyieren@M*U*S*H.
  * When you use 'teach' and, as a result, run the command you are teaching,
    it is treated as if the command were run by a player from the socket --
    that is, attribute sets are not evaluated. Suggested by Xyrxwyrth@M*U*S*H.
  * See_All players can see all channels and their members, too.
    Suggested by Oriens@Alexandria.
  * When trying to join yourself to a channel, we only check channels
    you're not on; when trying to leave a channel, we only check channels
    that you are on. This is handy for disambiguating similar prefixes.
    Suggested by Oriens@Alexandria.
  * When you're following a leader and the leader moves, you're told that
    that you're following them before you attempt to move. Suggested by
    Oriens@Alexandria.
  * @stats/table is no longer restricted.
Fixes:
  * @grep/iprint produced highlighted strings matching the case you
    gave, not the case actually found. Reported by Reagan@NF
  * @search/lsearch by powers could sometimes get you the equivalent
    flag-bit instead of power-bit. Reported by Reagan@NF
  * Configure fix.
  * hpux-gcc hint file now included.
  * Nested ansi() broke again in p1. Fixed now. Reported by Intrevis@M*U*S*H
  * Added Configure check for <netdb.h> to help Cygwin builds.
    Reported by Xyrxwyrth@M*U*S*H.
  * Help fix or two.
  * Grammatical correction by Rince@M*U*S*H in @boot/me error message.
  * Cosmetics of @mail with folders > 9 improved. Reported by Bellemore@M*U*S*H
  * One could be disconnected at the connect screen under some conditions
    for no good reason. Reported by Oriens@Alexandria. [SW]
  * Compile error when ROYALTY_FLAG not defined patched by Noltar@Korongil.
  * Fixed infinite loop reported by Xyrxwyrth@M*U*S*H. [SW]
  * It's no longer posible to connect to a GOING player.

& 1.7.4p1
Version 1.7.4 patchlevel 1		       March 17, 2001

Minor changes:
  * Speedup for repeat() function. [TAP]
  * Hint for openbsd, which appears to have a broken IPv6 configuration. [SW]
  * Some OS-dependent defines have been removed.
  * ansi() now only adds a maximum of 7 codes to the string. [TAP]
Fixes:
  * The restrict_command for rob has been removed from restrict.cnf
    Reported by Kyieren@M*U*S*H.
  * Help fixes by Kyieren, rodregis, and Luke @ M*U*S*H, Datron@SW2, 
    and Noltar@Korongil.
  * stripansi() didn't correctly handle multiple ansi codes in
    sequence. Reported by CU5@WCX.
  * Linting for warnings in pcre. [SW]
  * Configure now sends mailing list subscription stuff to the new 
    list address.
  * Updated examples in access.README to use dbrefs.
  * Updated a reference to the rob command in 'give' errors. Noted by
    rodregis@M*U*S*H.
  * median was broken. Reported by Parax@SandsMUSH.
  * Fixes to update.pl's handling of CHAT_TOKEN_ALIAS and the like.
    Noted by rodregis@M*U*S*H

& 1.7.4p0
Version 1.7.4 patchlevel 0                     March 7, 2001

Major Changes:
  * This is now the stable minor version. PennMUSH 1.7.2 is no longer
    supported except to help people transition to this version.
Commands:
  * The practically useless 'rob' command has been removed.
Minor Changes:
  * A virtually complete French translation joins the Swedish and
    Hungarian ones! Congratulations to Jean-Michael Amblat and
    Guillaime Lupin.
  * The index-files.pl script handles long help topic titles better when
    creating the index of help entries. [SW]
  * Config options that can be set with @config/set are now documented in
    mush help. [SW]
  * A @config/set of a dbref option now checks dbref for validity. [SW]
  * An ansi_normal code is added at the end of each channel title.
  * You can clear attributes that have invalid names. [SW]
  * stripansi() removes HTML markup as well as ANSI. [SW]
  * @poll and @doing cannot have ANSI or HTML markup. [SW]
  * soundex() and soundslike() strip ANSI and HTML. [SW]
  * The maximum length of attribute names has been limited to 1024 
    characters. [SW]
  * Nesting ansi() functions now works better. Patch by Luke@M*U*S*H.
  * help credits explains [initials] used herein. Suggested by Kyieren@M*U*S*H
Fixes:
  * Help fixes by Nymeria, Balerion, Trispis, Vexon (all@M*U*S*H),
    Jeff Ferrell, and [SW,LdW]
  * The two-argument forms of regmatch() and regmatchi() were backwards
    when it came to case-sensitivity. [SW]
  * @search on zone class did parent instead. Fix by Luke@M*U*S*H.
  * Use of @mail after @mail/nuke could cause a crash.
    Reported by Brazil. [SW]
  * make update handles the include directive correctly. [SW]
  * The admin WHO output looks better when locations reach 5-digit
    dbrefs now.
  * regedit() and regeditall() were case-insenstive. Fixed. [SW]
  * The code for log() was changed some time back to allow an optional
    base argument, but the help and function table were never updated. [SW]
  * owner() could be used to determine if any attribute existed on any
    object. [SW]
  * atrlock() has been cleaned up, fixing many bugs. [SW]
  * Some list functions that evaluate attributes could be used to determine
    if the attribute existed even if the object doing the function couldn't
    normally see the attribute. Fixed, and their error messages are now
    consistant with the other list functions (In other words, no errors, just
    a null string) [SW]
  * Idle timeout is now checked every minute rather than at dbck intervals. 
    Based on a report by Noltar@Korongil.
  * Cleanup of signed/unsigned casts and signal handlers. [SW,DW]
  * forbidden_name now does a case-insensitive comparison.
    Reported by Kyieren@M*U*S*H.
  * Blank lines at the start of help files are now correctly ignored
    on Win32 and Mac systems as well as Unix. Report by Nymeria@M*U*S*H.
  * functions() didn't show @functions. [SW]
  * Nuked players weren't getting removed from @maliases. [SW]
  * Database corruption caused by reading a db with over-long attribute
    names or with attributes starting with quotes fixed. [SW]
  * Crash bug in @attribute/rename fixed. [SW]
  * Potential memory leak in help_command fixed. [SW]
  * Warnings removed. Reported by [NJG]
  * Windows NT native IO (NT_TCP) stuff should work again. Reported by
    Bellemore@M*U*S*H. [NJG]
  * @forwardlist now requires that you control the target, be pemit_all,
    or pass the target's @lock/forward. Report by Vadiv@M*U*S*H.
  * unparse_flags didn't handle exit toggles. Report by Draci@Chaotic.
  * Casting and cleanup to enable compiling with lcc [SW]
  * A potential problem with regexps with heavy backtracking fixed. [SW]
  * Memory leaks with @clock fixed. [SW]
  * Typo in spellnum() "fourty" fixed. Reported by Kyieren@M*U*S*H.
  * @malias/set didn't work. Reported by Kyieren@M*U*S*H.
  * Win32 portability fixes. [NJG]
  * MacOS portability fixes [DW]
& 1.7.5p12
Version 1.7.5 patchlevel 12                     November 3, 2002

Fixes:
   * Another bug in wrap() fixed. Reported by Rhysem. [SW]
   * Bug in @wall fixed. [SW]
   * Variable renaming to avoid C99 keyword 'conj'. [SW]
   * Win32 project files for MSVC++ updated by Mark.
   * Several portability fixes for MS VS.NET's compiler by BladedThoth.
   * flip() and reverse() didn't mix well. Better now.
     Reported by Julian. [SW]
   * Compiling with CHAT_SYSTEM undefined works again. Report by
     BladedThoth.
   * bxor() was actually doing a bor(). Reported by Sketch@M*U*S*H. [SW]


& 1.7.5p11
Version 1.7.5 patchlevel 11                     October 31, 2002

Config:
   * New mush.cnf option only_ascii_in_names (defaults to yes) prohibits
     the use of extended characters in names. Games that are running
     in non-English locales will probably want to set this to no instead. 
     Suggested by Philip Mak. [SW]
Commands:
   * Added @hook/before and @hook/after [SW,3]
Locks:
   * You can now use power^<power> and channel^<channel> in locks
     to test if the enactor has a given power or is on a given channel.
     Patch by Vadiv@M*U*S*H.
   * @lock/dropto, if set on a room, can prevent objects from being
     affected by the room's drop-to. Inspired by Oriens@Alexandria.
Functions:
   * The sha1() function computes the SHA-1 cryptographic hash of a string.
   * A new nosidefx function restriction to allow disabling the side-effect
     version of a function while still enabling the informational version.
     For things like name() and parent(). [SW]
   * @function's report includes more function restrictions in the flags
     field. [SW]
Minor changes:
   * Modularization of code for itemizing lists by Vadiv@M*U*S*H.
   * If there's no connect.html and you're on an html connection,
     connect.txt is now better formatted when sent to you. Same for 
     other cached text files. Suggested by BladedThoth@M*U*S*H.
   * CRYPT_SYSTEM 1 now behaves like CRYPT_SYSTEM 3 (replacing
     system-crypt passwords with SHS passwords). Suggested by Vadiv@M*U*S*H.
   * flag_table is no longer referenced anywhere except when it is used
     to seed the ptab_flag at startup. A stub "flag_add" function has
     been added to make life easier for hardcoders. Suggested by
     Gepht.
Fixes:
   * sig.c was broken on systems without sigprocmask. Reported by
     Arithon@Oracle
   * Bug with paging disconnected players and @away fixed.
     Reported by Vadiv@M*U*S*H.
   * Bashisms that crept into utils/mkcmds.sh has been replaced by
     more portable alternatives based on Configure's results. 
     Reported by Jason Newquist.
   * Trigonometric functions were broken for non-radian degree types.
     Fixed up.
   * @decomp <room>/<attrib> didn't properly use 'here' as the name
     of the object in its output. Reported by Oriens@Alexandria.
   * Wizards can now modify any lock on anything but God. Reported by
     Brian Favela.
   * ex/mortal and ex now produce identical output when a mortal 
     examines an object owned by someone else. Reported by Philip Mak.
   * We do a little better about trying to close html and ansi tags
     in all conditions. Bugs reported by BladedThoth @ M*U*S*H.
   * whisper/@pemit to a puppet should be relayed to the owner, even if the 
     owner is in the same room. Discovered thanks to MUSH sound test
     suite designed by Trispis@M*U*S*H.
   * The --longest switch in game/txt/Makefile was broken. Report by
     Nymeria@M*U*S*H
   * Help fixes by Noltar@Korongil and Intrevis@M*U*S*H
   * The M_READ extmail bit is now renamed M_MSGREAD, as M_READ conflicts
     with an included define on Solaris. Report by Jason Newquist.
   * Setting flags using single characters was not well documented, and
     didn't respect the character case. Reported by Intrevis@M*U*S*H.
   * @chown by a Wizard attempted to debit the Wizard's money, rather than
     that of the new owner of the object, which violated expected conservation
     of money. Reported by Peter Bengtson.
   * Several bugs in wrap()'s output fixed. Reported by Balerion@M*U*S*H. [SW]


& 1.7.5p10
Version 1.7.5 patchlevel 10                     September 19, 2002

Major Changes:
   * Commands can now be restricted by generic flags or powers.
     Several mush.cnf options (restricted_building, free_objects,
     hate_dest, player_locate, cemit_power) are now restrict.cnf
     restrictions instead. By Vadiv@M*U*S*H.
Functions:
   * When a set function (setdiff, etc.) is called with 4 arguments,
     if the last one isn't a valid sorting category, it's treated as
     the output separator.  Inspired by Mux [SW]
   * checkpass(), a wizard function that checks a string against a player's
     password. Requested by Writh@M*U*S*H.
   * regedit() and variants can now accept multiple regexps and
     replacements, in order, like edit(). By Walker@M*U*S*H.
   * comp() can take a third argument to specify the type of 
     comparison to make. Suggested by Philip Mak.
   * The trigonometric functions now take an optional argument to
     control how the angles they work with are measured to allow them
     to accept angles in degrees as well as the default radians. [SW,MUX2,Rhost]
   * Added ctu() for converting between angle measurements. [SW,MUX2,Rhost]
   * Added atan2(). [SW]
   * dist2d() and dist3d() can take floating-point numbers. [SW]
   * Other small cleanups in the math functions. [SW]
Mail:
   * The MAIL_SUBJECTS option has been removed. @mail now includes
     subjects mandatorily. Suggested by Vadiv@M*U*S*H.
Minor Changes:
   * When a player @clones an object owned by another player, the
     clone is now owned by the @cloning player, instead of the original
     owner. Fixes a quota transfer issue reported by Sparta and
     Philip Mak.
   * The flag table is no longer walked with a linear search. Instead,
     ptab_firstentry and ptab_nextentry are used. Flags no longer need
     to be added in a particular order or groups in flags.c, and flags
     added through hardcode should work better. Patch by Vadiv@M*U*S*H
   * Error message for wrong number of arguments to a function
     now tells you how many arguments it thinks you gave.
     Suggested by Philip Mak.
   * GAGGED players may now perform mail reading and maintenance.
   * Internal reorganization of signal code. [SW]
   * Attempts to speak on a channel that you can't speak on or see
     now fail and command parsing continues. Suggested by Vadiv@M*U*S*H.
   * The amount of CPU time spent running a queue entry can be limited.
     This helps reduce the impact of some types of denial-of-service attacks.
     New mush.cnf directive queue_entry_cpu_time. This currently
     works only on Unix systems with setitimer. [SW]
   * Internal rewrite of page/whisper code by Vadiv@M*U*S*H.
   * Flag set/reset messages now include the name of the target object.
     Suggested by Kyieren@M*U*S*H.
   * game/txt/Makefile now includes options to limit the number of
     news/etc topic aliases that are included in the 'entries' indices
     generated by index-files.pl. Suggested by Nymeria@M*U*S*H.
   * Minor inconsistencies in @sweep output punctuation reported by
     Cmintrnt@M*U*S*H have been fixed.
   * Added hints/cygwin.sh, tested with cygwin 1.3.12. Added additional
     cygwin build information to README.
   * The whisper-pose message is now Player senses: <pose>, with no
     quotation marks added. This matches all other pose-type messages
     in the server. Suggested by Philip Mak.
   * Only escape codes described in the help are allowed in timefmt() [SW]
Fixes:
   * Archaic help reference to FORCE_WHITE removed. Noted by Oriens@Alexandria.
   * Help fixes by Cerekk@bDv TrekMUSH, Julian@M*U*S*H, Letters@M*U*S*H,
     and Philip Mak.
   * The wildcard matcher could lag the MUSH under unusual conditions.
     It's now smarter. Discovered by Sketch@M*U*S*H.
   * Fixes from 1.7.4p20
   * Fix a bug with setdiff() not using the output separator correctly. [SW]
   * convsecs() could attempt to use values larger than 2^31, which could
     crash Windows. Reported by Bellemore@M*U*S*H.
   * @config didn't correctly show default flags for objects.
     Reported by Vadiv@M*U*S*H.
   * The strcasecoll function was poorly coded, and is now fixed.
   * Created players who hadn't yet logged in didn't have LASTIP set
     properly. Reported by Philip Mak.

& 1.7.5p9
Version 1.7.5 patchlevel 9                     July 16, 2002

Minor Changes:
   * /noeval switch added to @wall/@rwall/@wizwall and variants.
     Suggested by Philip Mak.
Fixes:
   * Added a missing space in the @function report for softcoded
     @functions. [SW]
   * MUX-style @function foo=obj/attr works right. [SW]
   * Cleaned up some multiple includes of the same header files. [SW]
   * Lots of cleanup of old _() macros and similar by Vadiv@M*U*S*H.
   * Added help for @stats/table. Suggested by Intrevis@M*U*S*H.
   * Fixes to csrimalloc #ifdefs that broke in last patchlevel. [SW]
   * A typo that could crash @function on certain operating systems
     has been fixed. Report by Jeff Heinen.
   * Improved switch() help. [SW]
   * Changes in the way switchinc.c is generated, to reduce the number
     of patches that attempt to patch it due to indentation changes. [SW]

& 1.7.5p8
Version 1.7.5 patchlevel 8                     June 26, 2002

Minor Changes:
  * Added @nspemit and nspemit(). Wizard-only versions of @pemit and
    pemit() that don't print nospoof information. Suggested by many people,
    most recently Mike Griffiths and Nymeria@M*U*S*H. [SW]
  * Help updates. [SW]
  * Force the pipes to compression program for database reads and saves to be
    block-buffered. [SW]
  * @function name=obj/attrib now works, as well as
    @function name=obj,attrib [TAP]
  * The AF_PREFIXMATCH flag is no longer shown on attributes it's set
    on when you examine them.
Fixes:
  * A bunch of internal code cleanup, especially around casts. [SW]
  * The disconnected room check is skipped on GOING rooms. Suggested
    by Philip Mak.
  * The dbck check for nameless rooms was only checking disconnected
    rooms; now it checks all rooms.
  * hasflag() did not work with single-character flag abbreviations.
    Report by Mystery8.
  * The variable named 'template' in src/strutil.c has been renamed
    to avoid clashes with the C++ reserved word. Suggested by Mac@M*U*S*H.
  * Improvement to help @filter. Suggested by Philip Mak. [SW]
  * Files in the patches directory ending in ~ are ignored
    when patches.h is rebuilt. [SW]
  * Removed a // comment from strutil.c, as we're still
    just following the c89 standard, not c99. Report by
    Vadiv@M*U*S*H. [SW]
  * make indent now indents the .dst files before the .c ones.
    Fixes some spurious warnings from later makes. Suggested by
    Vadiv@M*U*S*H. [SW]
  * Code cleanup, mostly tprintf() and unneeded header file
    checking elimination. [SW]
  * Since a Windows header #defines OPAQUE, which conflicts with a
    #define for the mush flag of the same name, rename
    our #define rather than #undefining the Windows one. [SW]
  * Fixes from 1.7.4p19


& 1.7.5p7
Version 1.7.5 patchlevel 7                     May 14, 2002

Utilities:
  * 'make globalinstall' will install executables, scripts, and
    a game/ directory structure in a global location (/usr/libexec/pennmush
    by default). Facilitates rpm builds. By Vadiv@M*U*S*H.
  * The utils/ln-dir.sh script can be used to clone a globalinstall'd
    pennmush for an individual MUSH/user. In combination, these two
    are a replacement for 'make customize', especially for mud hosters.
    By Vadiv@M*U*S*H.
  * You can now configure options.h settings from the command line
    using: make DEFINE="OPTION OPTION=value" UNDEFINE="OPTION" update
    This will mostly be useful for autoinstallers and packaging scripts.
    Suggested by Vadiv@M*U*S*H.
Minor Changes:
  * The default gcc compile flags now include some extra warnings.
  * The prefix-table code now only aliases down to unique prefixes.
    This prevents @w from calling @wipe (reported by Philip Mak),
    and means that you'll need to use alias.cnf to get some of those
    short aliases. [SW]
  * Attribute lookups only do prefix-matching on attributes with the
    AF_PREFIXMATCH flag. Most standard atr_tab.h attributes have this
    flag, but newly added @attributes won't. Solves a problem with
    inadvertant prefix-matching of @attribs reported by Sam Knowlton.
Fixes:
  * Fixes from 1.7.4p18
  * @decomp/skipdefaults skips @lsets of default lock flags.
    Suggested by Oriens@Alexandria. [SW]
  * Typo in src/bsd.c corrected. Reported by Nymeria@M*U*S*H.
  * Missing prototype in src/help.c. Reported by Nymeria@M*U*S*H.
  * A bunch of linting.
  * Win32 portability fixes. [EEH]
  * Updated MSVC++ project files for win32. [EEH]
  * @newpassword = foo would change the password of an arbitrary player.
    This is now corrected. Report by Oriens@Alexandria.

& 1.7.5p6
Version 1.7.5 patchlevel 6                     April 22, 2002

Config:
  * New attribute_alias config directive, and some default attribute
    aliases added to alias.cnf. Based on a report from Hilikiradi.
Functions:
  * textfile() returns help/news/etc. entries. Suggested by Trispis@M*U*S*H.
Minor changes:
  * New @warnings type lock-checks that reports problems with @locks. [SW]
  * exit-unlinked checks do some sanity checks on variable exits. [SW]
  * Improved error-checking in evaluation of @locks. [SW]
  * No more hdrs/warnings.h file. [SW]
  * New @nameaccent attribute to add accent marks to object
    names in speech and things like look. Idea from Elendor. [SW]
  * accent() understands a few more things. [SW]
  * The accented characters->html entities table and other
    lookup tables are now in a seperate file, src/tables.c,
    which can be regenerated if needed by utils/gentables.c [SW]
  * Improvements in caching of cached text files. [SW]
Fixes:
  * Buglet in ansi display of high-bit characters fixed. Report by
    Trispis@M*U*S*H. [SW]
  * Improved @clock2 help by Linda Antonsson.
  * Fixes from 1.7.4p17
  * A truly perverse database could cause an infinite loop on load. [TAP]
  * Win32 portability fixes. [NJG, EEH]
  * The notify code assumed that integers could be directly stored in
    pointers. This isn't always true. [SW]
  * Removed some un-used code. [SW]
  * Fixed some compiler warnings and general code cleanup. [SW]
  * Changed signal handlers to always use the ANSI/ISO C form (Returning
    void, basically) [SW]
  * A null string no longer prefix-matches anything. Report by Prot Diryn
    and Cheetah@M*U*S*H.
  * @sitelock/remove could remove entries it shouldn't if you remove the first
    one after the '@sitelock will add sites...' line. Reported by
    Ambrosia@M*U*S*H. [SW]
  * The last line of the access.cnf file sometimes wouldn't get read
    properly. [SW]


& 1.7.5p5
Version 1.7.5 patchlevel 5                     March 11, 2002

Commands:
  * @notify and @drain now accept a new switch /any. [TAP]
  * Added @remit/list. Suggested by Tareldin@M*U*S*H [SW]
Minor changes:
  * We now use the Mersenne Twister pseudo-random number generator,
    which is better that that available in most C libraries.
    Moreover, we seed with /dev/urandom, if it's available. [SW]
  * The 'T' type character (for THING) is now shown when one-character
    flag lists are displayed. This is more consistent with other types,
    and makes it harder to confuse #23O (#23, opaque) with #230
    (#230, no flags). Suggested by Rince@M*U*S*H.
  * @lock/use on a parent used to apply to attempts to use $commands on
    a child. This is no longer necessary, given inheritable locks,
    so the behavior has been changed. Parents' locks are no longer checked
    when deciding if a $command inherited from the parent should be run
    via a child.
  * New 'call_limit' config option can limit the number of recursive
    parser calls to control process stack size and avoid crashes
    on systems with limited stack. Defaults to unlimited, however, because
    setting this value too small breaks mushcode. Report by Bellemore
    and BladedThoth @ M*U*S*H.
Fixes:
  * Code cleanup - some stuff from 1.7.4 got left in that isn't
    used in 1.7.5 any more. [SW]
  * Fixes from 1.7.4p16, notably an important fix for timed semaphores.
  * Cygwin portability fixes. [NJG]
  * Updated MSVC++ project files. [EEH]


& 1.7.5p4
Version 1.7.5 patchlevel 4                     February 15, 2002

Major changes:
  * The mush recognizes telnet-aware connections. This is
    neccessary for properly sending them some 8-bit characters. [SW]
  * Much more support for handling accented characters in the ISO 8859-1
    character set. See help for accent(), stripaccents(), and NOACCENTS.
    Inspired by Elendor. [SW]
  * Things that do first-unique-prefix matching (command, attribute and flag
    names) now use a more space-efficient data structure than before.
    This adds two new files, src/ptab.c and hdrs/ptab.h [SW]
Commands:
  * @sitelock/remove removes a sitelock entry. [SW]
Functions:
  * ord() and chr() functions for converting characters to/from numerical
    values that represent them. [SW]
Minor changes:
  * The useless FORCE_WHITE flag is really, truely, gone. [SW]
  * Use the new arglens argument to functions in more places. [SW]
  * capstr() and before() fixes reimplemented using arglens. [SW]
  * We now use the Mersenne Twister PRNG algorithm. [SW]
Fixes:
  * setunion() no longer eats empty list elements. [SW]
  * Setting an inherited lock on a child could change the parent's lock.
    Reported by Riverwolf. [SW]
  * Help fixes. [SW, Nymeria]
  * Players waiting at the connect screen weren't being disconnected
    by the idle_timeout.
  * Detection of cygwin in Configure may be improved.
  * Fixes from 1.7.4p15.

& 1.7.5p3
Version 1.7.5 patchlevel 3                     January 24, 2002

Fixes:
  * before() was broken in 1.7.5p2. Reported by Sam Knowlton.
  * capstr() was broken in 1.7.5p2.
  * Win32 portability fixes by Noltar@Korongil.

& 1.7.5p2
Version 1.7.5 patchlevel 2                     January 23, 2002

Major changes:
  * Implementations for softcode functions get the lengths of their arguments
    passed to them, and this is taken advantage of in a number of places. [SW]
Minor changes:
  * It's harder to get a partial dbref because of end-of-buffer truncation. [SW]
  * Code cleanup. In particular, safe_str() and friends are no longer
    macros for a safe_copy_str() or the like, because hardly anything
    used a different buffer length than BUFFER_LEN, and those places
    can be handled other ways. [SW]
Fixes:
  * Win32 portability fixes by Noltar@Korongil and Eric Koske.
  * When you have two hidden connections, one idle over the inactivity limit,
    and the other not, @hide/off on the active connection unhides both,
    but you also see the Inactivity re-hide message from the other
    connection. Reported by Trispis.
  * iname() function actually added to function table so it works.
    Reported by K. Shirow.
  * @lock obj=attrib:value locks didn't work properly. Reported by
    Linda Antonsson.
  * Fixes from 1.7.4p14.

& 1.7.5p1
Version 1.7.5 patchlevel 1                     December 3, 2001

Minor Changes:
  * PCRE updated to 3.7. [SW]
  * player_name_len is now runtime configurable. Suggested by
    Linda Antonsson. [SW]
  * Any object of any type may be a ZMO, and any object of any type
    may be zoned to a ZMO of any type. However, searching for
    $commands has not changed, so $commands on a ZMO are only
    searched when the ZMO is not a room, and $commands on objects
    within the ZMO are only searched when the ZMO is a room. [TAP]
  * @chzoneall nows directly calls @chzone, and @chzone now tells
    you when it's not changing a zone. [TAP]
  * The term "Zone Master" (player) has been replaced by "Shared
    Player" in the help. [TAP]
  * Many obsolete db formats are no longer readable. hdrs/oldattrib.h
    and src/convdb.c are no more. [SW]
  * Code cleanup. [SW]
Fixes:
  * Help file for mix updated. Report by Cmintrnt@M*U*S*H
  * Updated win32 config.h file and other fixes by Noltar@Korongil
  * WHO wasn't showing unconnected players. Report by Noltar@Korongil. [SW]
  * Help fixes. [SW]

& 1.7.5p0
Version 1.7.5 patchlevel 0                     November 14, 2001

Major Changes:
  * This is now the development minor version. This first release includes
    relatively few changes, to make converting to it easier.
  * Internal changes to the lock system. This requires a new minimal.db,
    which is now distributed. [SW]
  * Locale-based string collation throughout.
  * Only ANSI C compilers are still supported; no more K&R. Files are
    gradually going to be converted to ANSI C only.
  * There is now an option to make ZMOs and ZMRs not count for
    control of objects, only ZMPs. [SW]
Flags:
  * The ZONE player flag has been renamed SHARED, to help seperate the
    ZMP control-only meaning from the command-matching of ZMOs and ZMRs. [SW]
Commands:
  * /preserve switch for @link prevents @chowning. Suggested by Vexon@M*U*S*H
  * Admin WHO and SESSION now includes unconnected descriptors. [SW]
  * Unconnected descriptors can now be booted. Patch by Bellemore@M*U*S*H.
  * Unconnected descriptors can now be paged by admin with page/port. [SW]
Functions:
  * mix() can take more than 10 lists and of unequal length. [3,SW]
  * iname() returns the name of an object from inside (honoring nameformat)
    Idea by Jeffrey@TheHotel.
  * lplayers() returns a list of players in the location. Handy for
    room parents. By Vexon@M*U*S*H.
  * lvplayers(), lvcon(), lvexits() are like lplayers/lcon/lexits, but
    leave out dark things (and disconnected players). Handy for room
    parents. By Vexon@M*U*S*H.
Minor Changes:
  * munge() now passes its delimiter as %1 to make generic sorting easier. [SW]
  * Word-based attribute compression is faster than before, for both
    compression and decompression. [SW]
  * Windows memory-usage information for wizards is now in @uptime, not
    @stats [SW]
  * Word-based attribute compression stats can be viewed on non-Windows
    mushes as well, by defining COMP_STATS. See externs.h for details. [SW]
  * Setting of the internal QUEUE and semaphore attributes does not modify
    an object's last-modified timestamp. [SW]
  * Speaking on a channel that you're gagging is now treated like
    speaking on a channel that you're not on. Suggested by rodregis@M*U*S*H
  * You can use @exitto in place of &DESTINATION to set the destinatino
    for variable exits, though DESTINATION is checked first. [3]
  * WATCHER is another name for the MONITOR flag. [3]
  * max_guest_pennies and guest_paycheck config options. Inspired by [SW]
  * Lock and unlock messages now show object name and dbref, and tell
    you if you unlock an already unlocked object. Suggested by Jamie Warren.
  * A version of portmsg for Win32 is in the win32 directory.
    Donated by CU5@WCX
  * Tweaks to info_slave, which now uses readv/writev. [SW]
  * Lots of code cleanup. [SW]
  * CHAT_SYSTEM, INFO_SLAVE, and FUNCTION_SIDE_EFFECTS are now #define'd
    by default. [TAP]
Fixes:
  * Indentation fixes [SW]
  * Fixes up to 1.7.4p12 merged in.

& 1.7.6p16
Version 1.7.6 patchlevel 16                     April 28, 2004

Fixes:
   * PCRE updated to 4.5 [SW]


& 1.7.6p15
Version 1.7.6 patchlevel 15                     January 25, 2004

Fixes:
   * Improved freebsd hints. [SW]
   * Channel user memory allocation error corrected.


& 1.7.6p14
Version 1.7.6 patchlevel 14                     September 23, 2003

Fixes:
   * Fix to help @search2 by LeeLaLimaLLama@M*U*S*H.
   * The max file descriptor could get stomped in some cases. [SW]
   * Powers and toggles on destroyed objects are reset, as they 
     caused anomalous lsearch/haspower behavior. Report by Mordie@M*U*S*H.
   * Changing channel privs and loading channels with objects no longer
     permitted could cause crashes. Report by Septimus@SW RP Forum.


& 1.7.6p13
Version 1.7.6 patchlevel 13                     August 11, 2003

Fixes:
   * Calling panic() while in the middle of a panic dump would cause a loop.
     Reported by [EEH]. [SW] 
   * Outdated mention of compose.csh removed from compose.sh.SH.
     Reported by Cheetah@M*U*S*H.
   * timestring() dealt wrongly with large arguments. Reported by
     Jules@M*U*S*H. timefmt() had a similar problem, reported by
     Luke@M*U*S*H.
   * Better checking of db save failures. [SW]


& 1.7.6p12
Version 1.7.6 patchlevel 12                     June 23, 2003

Minor changes:
   * Users no longer see last connection information when they 
     connect to Guests. Suggested by Jules@M*U*S*H.
Fixes:
   * Potential problem with ambigious names in the information functions 
     fixed. [SW]
   * The 'chat' config group is no longer displayed when CHAT_SYSTEM
     isn't defined. Report by Mike Griffiths. [SW]
   * cygwin install instructions changed to remove obsolete exim
     version information. Suggested by Cheetah@M*U*S*H.
   * Objects with user-defined locks had problems with finding built-in locks
     on the object. Reported by Walker@M*U*S*H. [SW]


& 1.7.6p11
Version 1.7.6 patchlevel 11                     June 1, 2003

Minor changes:
   * The restart script now insures that GAMEDIR is a real directory
     and CONF_FILE exists therein before proceeding. Suggested by
     Philip Mak.
   * Attribute flag setting messages are more verbose. Suggested by
     Mike Griffiths
   * See_All players may use the ports() function. Suggested by 
     Mike Griffiths.
Fixes:
   * Wizards can no longer @chzone God. Report by Kevin@M*U*S*H.
   * Help fixes by Mike Griffiths.

& 1.7.6p10
Version 1.7.6 patchlevel 10                     May 13, 2003

Minor changes:
   * PCRE (the regex matching engine we use) is updated to version 4.2. [SW]
   * @mail/file now unclears the cleared bit when filing @mail.
     Suggested by Philip Mak.
Fixes:
   * @edit is better with editing ansi. Reported by Trispis@M*U*S*H. [SW]
   * Help file cleanup. [SW]
   * @warnings about missing FAILURE messages were not correctly 
     checked, causing false positives. Reported by Cheetah.
   * Page message no longer ends in a period. Suggested by Time@M*U*S*H.
   * Help fixes by Intrevis@M*U*S*H.
   * BASE_ROOM can't be destroyed any more. Suggested by Philip Mak.


& 1.7.6p9
Version 1.7.6 patchlevel 9                      April 9, 2003

Fixes:
   * index-files.pl now produces a sensible warning for duplicate
     help topics, rather than a perl warning. Suggested by Cheetah@M*U*S*H.
   * Spellnum cosmetic bug with 'seventeen' fixed. Report by Jules@M*U*S*H.
   * Another wrap() buglet tracked down and fixed. Probably the one
     reported by Nymeria@M*U*S*H.
   * Memory leak in flip() and scramble() fixed.
   * Configure test for /dev/urandom from 1.7.5 got left out by mistake.
   * Critical overflow bug in command argument parsing fixed.

& 1.7.6p8
Version 1.7.6 patchlevel 8                      March 21, 2003

Minor changes:
   * The CHANGES file has been renamed so that it always refers to
     a version number, and utils/mkvershelp.pl now generates seperate
     .hlp files for each CHANGES file. This will prevent patch hunk 
     failures when two patchlevels of different versions are released
     and both used to try to modify the same .hlp file.
   * Channel names are restricted to printable characters, with no
     leading or trailing spaces. Suggested by Letters@M*U*S*H.
   * Calling time() with any argument other than 'utc' now generates
     an error. Report by Time@M*U*S*H.
Fixes:
   * Some redundant code cleanup in look_exits suggested by Vadiv@M*U*S*H.
   * Help file fixes by Ves@M*U*S*H, Jules@M*U*S*H, Cerekk@bDv.
   * When page_aliases is on, there's a space between the player's
     name and alias. Suggested by Saturn@M3.
   * Command-checking for ZMR contents didn't function when a ZMR
     was used as a player's personal zone. Reported by BlaZe@M*U*S*H.
   * Default idle_timeout was different in code and mushcnf.dst.
     Reported by James Bond@M*U*S*H. [SW]


& 1.7.6p7
Version 1.7.6 patchlevel 7                      February 20, 2003

Fixes:
   * Some sloppy coding in src/access.c could generate runtime 
     debugging exceptions. Reported by BladedThoth@M*U*S*H.
   * wrap() could behave incorrectly when a line was exactly the length
     of the wrap width and the total input size was larger than 
     any previously wrapped input. Reported by Liam@Firdeloth.
   * Extra NUL characters were sent after telnet codes, which 
     confused Mudnet and maybe some clients. Patch by Alierak.


& 1.7.6p6
Version 1.7.6 patchlevel 6                      January 23, 2003

Minor changes:
   * nearby() always works for see_all players. Reported by Sparta.
   * findable() now requires that executor control either the object
     or the victim or be see_all. Reported by Sparta.
Fixes:
   * POWER^ and CHANNEL^ locks tested the wrong object. [SW]
   * @grep, @wipe, and @edit now report when no attributes are
     matched. Suggested by Procyon@M3
   * Changes to telnet negotiation strings to match those in
     PennMUSH 1.7.7, which seems to fix some problems with display
     of connect.txt in some clients. Report by Howie@NewFrontier.
     Patch by Time@M*U*S*H.
   * @mail/silent wasn't unless you used /send too. Report by
     Moe@Chicago.
   * Wizards could set attributes on garbage objects (which were useless,
     but may have leaked memory needlessly). Reported by Taz@M*U*S*H.
   * @chan/hide didn't check for hide permissions properly in some
     cases. Reported by Tanaku@M*U*S*H.
   * Better explanation of when regexp matching is case sensitive vs.
     insensitive. Suggested by Jake@BrazilMUX, Brazil@BrazilMUX, and
     Vadiv@M*U*S*H.


& 1.7.6p5
Version 1.7.6 patchlevel 5                      January 7, 2003

Fixes:
   * 1.7.6p4 broke 'go #dbref', which broke the ability of followers 
     to follow. Reported by Ellis@M*U*S*H.


& 1.7.6p4
Version 1.7.6 patchlevel 4                      January 2, 2003

Minor Changes:
   * English-style matching now applies to exits in the room
     (so '1st down' can match the first 'down' exit if you're not carrying
     anything that matches 'down'). New english-style matching adjective
     'toward' restricts the match to exits (so: 'look toward 1st down').
Fixes:
   * Code cleanup to fix several potential buffer overflows.
   * The wildcard matcher had problems with backslash escapes in
     some cases, making matching a : in a $command very hard.
     Reported by Wayne@PDX.
   * @chzone could cause crashes on some systems.  Reported by Wayne@PDX.
   * When two exits match, one is no longer chosen at random.
     Instead, the ambiguity should be reported as an error.
     Reported by Intrevis@M*U*S*H.
   * The dbref returned by locate when given the X parameter is
     no longer random, but the last one found (as per the help).
   * Serious bug in reading locks from the db on startup corrected.
   * The profiling timer is turned off duing dumps, as some systems
     (FreeBSD?) appear to continue to use it and interrupt dumps
     due to cpu limiting. Reported by Nathan Schuette.


& 1.7.6p3
Version 1.7.6 patchlevel 3                      December 22, 2002

Minor changes:
   * call_limit now controls the maximum recursion in process_expression,
     instead of maximum calls to p_e per command cycle. This still
     limits stack size, but doesn't get in the way of massive code
     nearly as much. People using a very high call_limit value should
     probably lower it significantly. Patch by Philip Mak.
   * Improved error messages for many database information functions.
     Notably, several functions that require at least one argument,
     now complain if they don't get it rather than returning silently.
     Suggested by Intrevis@M*U*S*H. [SW]
Fixes:
   * @warnings are no longer shown on GOING objects. Suggested by
     Philip Mak.
   * Help fixes by Intrevis, Time, and Ambrosia@M*U*S*H
   * Bug in @decomp/skipdefaults reported by Philip Mak. [SW]
   * Tweaks to utils/mkcmds.sh [SW]
   * home() on a room acts as described in the help. Reported by
     Intrevis@M*U*S*H. [SW]
   * whisper/noisy double-notified the whisperer. Reported by Philip Mak.
   * Crash bug in @mail fixed. Reported by Titan@OtherSpace.


& 1.7.6p2
Version 1.7.6 patchlevel 2                      December 17, 2002

Minor changes:
   * An invalid range argument to @search/lsearch is now coerced
     to be the lowest or highest dbref, as appropriate. The search
     range is also now inclusive. And lsearch(<player>) works.
     Suggested by Philip Mak.
   * mushcnf.dst now includes a default value for call_limit.
     Suggested by Philip Mak.
   * Testing for whether the mush is already running in the
     restart script has been improved by Philip Mak.
Internationalization:
   * Polish translation files (partial) are now being distributed.
Fixes:
   * Fix to win32 warnings. [EEH]
   * Under Win32, a failed accept() call in bsd.c would not be
     correctly handled. Report by BladedThoth@M*U*S*H.
   * Help fixes by Luigi@8bitMUSH, Kyieren@M*U*S*H, Intrevis@M*U*S*H.
   * @map crash bug repoted by Philip Mak, fixed by Walker@M*U*S*H.
   * Modifiying locks now updates the object's modification time.
     Reported by Philip Mak.


& 1.7.6p1
Version 1.7.6 patchlevel 1                      November 26, 2002

Minor changes:
   * When using @nuke to destroy a SAFE object when really_safe is "no",
     provide a warning (but schedule destruction anyway). Suggested by
     Cerekk@bDV.
Fixes:
   * VS.NET project file was defaulting to signed instead of unsigned
     chars, causing crashes. Fixed by BladedThoth@M*U*S*H.
     Several places where we should have cast things to unsigned to
     avoid this kind of thing have been fixed. [SW]
   * The *emit() functions now set the orator correctly.
     Reported by Philip Mak.
   * ccom and cplr are cleared after each command execution so they
     can't be leaked as easily. Suggested by Philip Mak.
   * Linting.
   * If God gives the wrong password to @logwipe, provide some feedback.
     Suggested by Cerekk@bDv.
   * mkcmds.sh was needlessly rebuilding several autogenerated files.
   * The rules for flag characters shown in object headers now allows
     F_INTERNAL flags to be shown (like GOING), just the same as
     when you get a full flag list on examine. Report by Philip Mak.
   * Help fixes by Bird@M*U*S*H, Intrevis@M*U*S*H, Philip Mak.
   * @search type=something would report an error AND match the entire
     database when something wasn't object, player, exit or room. [SW]
   * Cosmetic bug in @malias/list fixed. Report by Tanaku@M*U*S*H.
   * The info_slave now properly obeys the use_dns setting in mush.cnf.
     This requires a full shutdown to put into effect. Report by
     BlaZe@M*U*S*H. [SW]


& 1.7.6p0
Version 1.7.6 patchlevel 0                      November 11, 2002

License:
 * PennMUSH 1.7.6 and later is now released under the Artistic
   License. This is an OSI-compliant open source license. See the file
   COPYRITE for the complete license text.

   Notable changes from the old license:
   * No restrictions on commercial use
   * No requirement to inform developers of improvements or submit
     modifications, though it's still a nice thing to do. Note, however
     that if you redistribute a modified version of PennMUSH, you MUST
     include source code.

   The PennMUSH devteam thanks the copyright holders of TinyMUD,
   TinyMUSH 2.0, TinyMUSH 2.2, and TinyMUSH 3.0 for their assistance
   in making this possible.
Documentation:
   * The README file has been split into README, INSTALL, UPGRADING,
     and I18N files.
Minor Changes:
   * Rooms now hear remits and lemits in them, and can be pemitted
     to. This behavior now matches that of other MUSH servers.
   * AUDIBLE objects now propagate sound @remit'd into them.
     Report by [SW].
   * Added @lock/destroy to limit who can destroy a DESTROY_OK 
     object. Suggested by Luigi@8bit.
   * PARANOID nospoof notification now includes the name of the object's
     owner as well. Suggested by Philip Mak.
   * room() no longer notifies the executor of permission errors out of
     band. It now just returns the error instead, like loc(). Suggested by 
     Philip Mak.
   * Creation times are now public information via ctime(); permission to
     examine is no longer required. This allows objects to use, e.g.,
     %#@[ctime(%#)] as a historically unique identifier of an enactor.
     Suggested by Philip Mak.
   * The reboot.db is now versioned. This will make it possible to
     @shutdown/reboot across patchlevels that change the reboot.db
     format (in 1.7.7 and later versions).
   * Rooms on an @forwardlist now receive the message as a remit,
     rather than a pemit. Suggested by BladedThoth@M*U*S*H.
Fixes:
   * More work on the great table() bug. Looks like a fix. [SW]
   * Improved VS.NET project files by BladedThoth.
   * Plugged a memory leak in deleting @locks. [SW]
   * Fixed @lock-related crash bug reported by Philip Mak. [SW]
   * General linting.
   * process_expression ignores the [ in ansi escapes. Reported in the
     context of #$ by Philip Mak. [SW]
   * Internal changes to compress(), which now returns an allocated
     string. Under Huffman compression, it should no longer be possible
     to overflow a buffer with a pathological compression tree. Initial
     concern voiced by Eyal Sagi.
   * Table and ansi didn't play well together. Reported by Ellis@M*U*S*H.
   * Config file reading should be better on Macs. Patch by Philip Mak.
   * Obsolete checks for OLD_ANSI are removed. [SW]
   * Crash bug in @function fixed. Report by Dallimar@Hemlock.
   * Change to message on failed attribute flag set, to make it more
     generic to cover all the possible failures. Report by Cerekk@bDv.
   * Translations to some languages were broken. Fixed now. Report by
     Sbot@M*U*S*H.
   * QUEUE is now visible if you control an object, as promised in the
     help. Reported by Luigi@8bit.
   * Help fixes by Mortimer@M*U*S*H, Bellemore@M*U*S*H, Hyacinth@8bit,
     [EEH], BladedThoth@M*U*S*H, Moe@M*U*S*H, Viila@M*U*S*H, Walker@M*U*S*H.
   * Comment in src/Makefile fixed by Vadiv@M*U*S*H.
   * A weird crash on @shutdown/reboot, probably attributable to a
     broken library or system call, is now worked-around. Report by
     Solarius@SWWF.
   * Audible objects with @forwardlist set are no longer concealed by
     the DARK flag.
   * Win32 project files no longer use the win32/ directory as an include
     directory, which causes problems. Reported by Gepht.

& 1.7.7p40
Version 1.7.7 patchlevel 40                     December 1, 2004

Major Changes:
  * Another pass at the chunk allocator! Simpler but effective.
    Folks should, however, greatly reduce their chunk_migrate
    value in mush.cnf -- we suggest '50'. [TAP]
Commands:
  * @command/alias can alias commands. Patch by Walker@M*U*S*H.
Functions:
  * zwho() and zmwho(). [EEH]
Minor Changes:
  * utils/penn-install is no longer part of the PennMUSH distribution
    (it's part of the Debian maintainer's stuff). [EEH]
  * Inheritable @locks are inherited off of ancestor objects. 
    Suggested by Zith@Lovarii. [SW] 
Fixes:
  * Infinite recursion in @lock/examine fixed. Report by
    Amy Kou'ai (Amy@ShoujoAi) and Sparta Kerleon (Sparta@ShoujoAi). [TAP]
  * @flag/letter now allows setting a flag's letter to one used by
    another flag that works on different object types. Report by Lenon.
  * Translation corrections by Cheetah@M*U*S*H and [EEH].
  * Added __USE_POSIX to the cflags for linux, and removed 
    checking for -lbind, to help SuSE 9.  Report by Ambrosia@M*U*S*H.
  * Fixes to panic db loading logic. [SW] 
  * escape() shouldn't double-escape the first character of the
    string when it's a special character. Report by Walker@M*U*S*H.


& 1.7.7p39
Version 1.7.7 patchlevel 39                     October 25, 2004

Major Changes:
  * Game and chat database formats have been rewritten. They are 
    much more human-readable, can be extended with new fields
    without using versioning flags, and provide better detection
    and reporting of malformed databases. [SW]
  * Chunk deref counts for locks are now stored in the database. [SW]
Commands:
  * New 'buy' command for purchasing items from vendors that can offer
    multiple items at multiple prices. Patch by Walker@M*U*S*H.
  * restrict_command and @command/restrict can now include an
    error message to be sent when the player can't use the command,
    which supercedes more generic errors. Suggested by Philip Mak.
    Patch by Walker@M*U*S*H.
Functions:
  * lwho() can take an argument to produce the who list from that
    player's viewpoint. Patch by Walker@M*U*S*H.
Fixes:
  * nattr(obj/attrib) returns 1 when matching a non-wildcarded attrib.
    Report by Impster@M*U*S*H.
  * +chan <msg> is now converted to @chat <chan>=<msg> (with noeval)
    so @chat hooks apply to +chatting too. Patch by Walker@M*U*S*H.
  * You must be able to locate a player to perform elock() on them.
    Report by Ambrosia.
  * Help fixes by Sketch@M*U*S*H.
  * Simplification of @version code. [SW]
  * cemit() restrictions are now based on those of @cemit, instead
    of @emit. Report by BlackPhyr.
  * Setting queue_loss to 0 disables queue_loss. A bad idea, but
    more consistent behavior. Suggested by K Moon.
  * Examining objects always shows their actual number of coins,
    whether or not they're admin or no_pay.
  * Code cleanup in @edit and in char routines. [SW].
  * Wrong object checked when reporting money as unlimited. Report
    by Nate Barney. [EEH]
  * New hints/freebsd_5.sh. Suggested by James Lang.
  * INFO command once again reports the server as "PennMUSH",
    not just a version number. Report by Mark Hassman.
  * Win32 linting. Builds with NT_TCP should work again (although
    @shutdown/reboot under NT_TCP is still not functional). 
    Reorganization of the Win32 services macros. [EEH]
  * Fix to bug with login attempts using literal encrypted strings.
    Reported by Cadar and Mirrador.
  * @ps/all shows the right label on top. Patch by qa'toq@bDv.


& 1.7.7p38
Version 1.7.7 patchlevel 38                     August 25, 2004

Commands:
  * @boot/silent disconnects without the standard message.
    Suggested by Thor@bDv.
Fixes:
  * Crash bug in is_objid fixed. Report by Wayne@PDX.
  * God could cause a flag to lose its type status, and then become
    inaccessible. Report by Wayne@PDX.


& 1.7.7p37
Version 1.7.7 patchlevel 37                     August 23, 2004

Major changes:
  * @adisconnect is triggered on every disconnection, partial or full.
    This mirrors the behavior of @aconnect. Use %1 (the number of
    remaining connections) to distinguish between partial and full
    disconnects in @adisconnect code.
Minor changes (user-visible):
  * When a player disconnects, their recv(), sent(), and cmds()
    values are passed to triggered @adisconnects as %2, %3, and %4.
    The number of remaining connections is passed as %1.
    Suggested by Jessica Hawthorne and Wayne@PDX.
  * No_Pay players now have their money reported as unlimited by
    examine and score (but money() still returns a useful integer value).
    ex/debug can be used to see the object's Pennies field.
    Suggested by Wayne@PDX.
Fixes:
  * ex obj/*1 and similar was matching like ex obj/*1*. Reported by
    Math@HavenMUSH.
  * inc() and dec() with out-of-range integers now return a more
    useful error instead of odd behavior. Suggested by Jessica Hawthorne.
  * Win32 bug with renamed temporary database files resolved.
    Reported by AndromedaMU.
  * Help fixes by Mike Griffiths.
  * @mail commands with no message list were not using current folder.
    Report by Jessica Hawthorne.

& 1.7.7p36
Version 1.7.7 patchlevel 36                     August 9, 2004

Functions:
  * l/lv/n/nv/x/xvthings() functions by Walker@M*U*S*H.
  * New flag to locate(), 'y', for matching player names like pmatch(),
    without requiring a leading * before the name like the 'p' flag. [SW]
  * lattr()/nattr() works for mortals on non-owned objects, showing
    or counting only attribs they can examine. Suggested by Philip Mak,
    patch by Walker@M*U*S*H.
Minor changes (user-visible):
  * Mortals can no longer teleport HEAVY admin through exits.
    Suggested by Ambrosia@M*U*S*H.
Minor changes (internals):
  * win32 directory has subdirectories for msvc6 and msvc.net. [EEH]
  * locate() on dark rooms now works for see_all players. Suggested
    by Wayne@PDX.
Fixes:
  * @mail subjects are stripped of ansi before being stored (escape
    chars were always smashed on display). Suggested by Wayne@PDX.
  * @command/delete by God of a non-existing command caused a crash.
    Report by Wayne@PDX.
  * Follow works again. Report by Shirow.
  * Fix to digest()'s sha hash on systems without OpenSSL. [SW]
  * @list/command no longer includes duplicates. Report by Relay@M*U*S*H. [EEH]
  * comp() again returns -1/1 instead of -2/2. Report by Jessica Hawthorne.
  * sort() of large floats works again. Report by Jessica Hawthorne.
  * Linting of warnings in funlist.c. Report by Nymeria@M*U*S*H.
  * It was possible for wizards to create circular zone chains that
    would cause an infinite loop. Report by Wayne@PDX.
  * safe_ansi_string was double-prepending starting ansi codes.
    Report by Shirow.
  * Debian packaging improvements. [EEH]
  * Help fixes by Mike Griffiths.


& 1.7.7p35
Version 1.7.7 patchlevel 35                     July 21, 2004

Attributes:
  * NO_NAME and NO_SPACE attribute flags, when applied to @o-message
    attributes, omit either the enactor's name or the space after it
    when sending the message to others. Patch by Walker@M*U*S*H. [3]
Commands:
  * @break <expression>=<new command> now runs <new command>
    instead of simply stopping execution when <expression> is true.
    New command @assert breaks and runs new command when <expression>
    is false.  Suggested by Philip Mak and Zebranky@M*U*S*H. Patch by 
    Walker@M*U*S*H.
  * The new command 'huh_command' is responsible for handling unmatched
    command input. By default, it produces the usual Huh? message, but
    it can be overridden with @hook. Logging of huhs is now controlled
    in restrict.cnf and the log_huhs mush.cnf directive is removed.
    Suggested by T'orA and Walker@M*U*S*H.
  * New @decompile/prefix switch generalizes @decompile/tf.
    Prefixes are now applied even when decompiling multiple attributes,
    and a bug in doing so is corrected. Patch by Walker@M*U*S*H.
  * New @edit/first switch only replaces first occurrence of string.
    Suggested by Kevin@M*U*S*H.
Functions:
  * malias() function for examining mail aliases. Inspired by
    Kevin@M*U*S*H.
  * llocks()/locks() lists locks on an object. Patch by Walker@M*U*S*H.
  * lset() function works like @lset. Patch by Walker@M*U*S*H.
  * lockflags() and llockflags() show short and long flags set on a lock.
    Patch by Walker@M*U*S*H.
  * lattrp() is lattr() including parent attribs. Patch by Walker@M*U*S*H.
  * nattr(obj/wildcardpattern) is now supported. Patch by Walker@M*U*S*H.
  * nattrp() is nattr() including parent attribs. Patch by Walker@M*U*S*H.
  * xattr(obj/wildcardpattern,start,count) extracts the corresponding
    elements from lattr(). xattrp() is xattr() including parent attribs. 
    Patch by Walker@M*U*S*H.
Minor changes (user-visible):
  * @lset and lock() recognize locks beginning with user:. Patch by
    Walker@M*U*S*H.
  * When a player causes an ambiguous channel match, the error message
    mentions CHAN_USEFIRSTMATCH, which now has a help entry.
    Suggested by Luke@M*U*S*H.
  * New sort options: sorting by dbref name, idle time, connection seconds, 
    creation time, owner dbref, and attribute values.  sort() and any 
    functions that use list2arr() are now ansi-aware. Patch by Walker@M*U*S*H.
  * You can @name yourself to your @alias; this swaps name and alias.
    Suggested by Oriens@Alexandria. Patch by Walker@M*U*S*H.
Minor changes (internals):
  * Several global variables are now encapsulated in a single structure
    to reduce potential namespace clashes.
  * Reorganization of some filecopy.c code. [SW]
Fixes:
  * @mail manipulation specifying folder 0 explicitly when the
    current folder is non-zero didn't work right. Report by 
    Jess Hawthorne.
  * Buffer overflow in string handling fixed. Report by Ashen-Shugar.
  * @sitelock/name of an already locked name no longer creates extra
    entries. Report by Nymeria@M*U*S*H.
  * make depend no longer produces an unterminated Makefile.SH.
    Reported by Bytor and Cheetah@M*U*S*H.
  * Help fixes by [SW].
  * Fix to replace_string2 to prevent overflow situations. Report by
    Atuarre. [SW].
  * Removed non-static shutdownsock prototype in hdrs/mysocket.h.
    Report by Kholnuu@M*U*S*H.
  * SQL code should be much more memory-efficient. [SW]
  * Code cleanup and fixes to some memory leaks with strcoll. [SW]


& 1.7.7p34
Version 1.7.7 patchlevel 34                     June 22, 2004

Flags and Powers:
  * Debit power allows the giving of negative amounts of money.
    Suggested by Hemlon@SevenStones.
  * The setting and resetting of flags and powers can be logged 
    by using the new 'log' restriction. Changes were made in
    flaglocal.dst which you must carry over into flaglocal.c
    (or, if you don't use flaglocal.c, just rm src/flaglocal.c and
    flaglocal.dst will be copied in its place). Suggested by Sholevi@M*U*S*H
    [SW]
  * Setting and resetting @powers are once again logged by default. [SW]
Locks:
  * @lock/speech can now be set by unprivileged players. @lock/speech
    now applies to all players (it is no longer automatically overridden
    by admin). SPEECH_LOCK`*FAILURE attributes can be used to override 
    the default failure messages when @lock/speech fails.
Commands:
  * ex/parent examines an object and shows attributes that will be
    inherited from its parents (if you are permitted to examine
    the parent as well). Suggested by BladedThoth@M*U*S*H. 
  * examine now shows the complete (examinable-by-enactor) chain of 
    parent objects, not just the nearest parent. Suggested by Luke@M*U*S*H.
Functions:
  * mailsend() is a function form of @mail/send. Suggested by Moe@ChicagoMUSH
  * ncon, nvcon, nexits, nvexits, nplayers, nvplayers, nwho, nvwho 
    functions to count the number of each thing. Patch by Walker@M*U*S*H.
  * xcon, xvcon, xexits, xvexits, xplayers, xvplayers, xwho, xvwho functions 
    to extract slices of potentially long contents, etc. lists. [Rhost,TM]
    Patch by Walker@M*U*S*H.
Minor changes (user-visible):
  * Players can no longer be set CHOWN_OK. Suggested by Intrevis@M*U*S*H.
    If you have existing CHOWN_OK players, you probably want to unset
    this from them, or the results will be confusing (they'll continue
    to appear to have the flag, even though it won't be testable or
    settable or clearable; this is desired behavior).
  * If you're See_All and Pemit_All, you may now @cemit on any channel.
    Based on a suggestion by Philip Mak.
  * Attempting to give a player more than max_pennies will give them
    enough to get them to max_pennies, instead of being treated as
    an error. Similarly, taking away more pennies than they have will
    take away exactly all their pennies.
  * Improved errors for unprivileged users doing @boot/port.
    Suggested by Intrevis@M*U*S*H. [TAP]
Minor changes (internals):
  * pre OS X Macintosh OSes are no longer supported. Hints for 
    Darwin are improved. [SW]
  * An extra file descriptor only needed on Sun OS boxes was being
    opened on all unix systems. [SW]
  * If no config file name is given on the netmush program's command line,
    it will assume you mean mush.cnf instead of quitting. You should still
    be using the restart script instead of netmush directly, though, as it
    does important things like using the right database... [SW]
  * 'make local-files' will copy all the src/*local.dst files to their
    respective .c counterparts. Suggested by Nymeria@M*U*S*H. [SW]
Fixes:
  * Configure handles the case where SO_KEEPALIVE works but TCP_KEEPIDLE isn't
    defined. [SW]
  * Win32 portability fixes and mingw hints. [EEH]
  * Raising max_logins from 0 with @config/set wouldn't take existing
    connections into account. [SW] 
  * $commands starting with # (that don't look like an @force by dbref)
    will now be matched. Reported by Intrevis@M*U*S*H.
  * version() is verbose again. Reported by Sholevi@M*U*S*H.
  * The double-add of SQL_OK on minimal.db is now really fixed.
    See p33 changes for information. Report by Mordie@M*U*S*H.
  * Help fixes by Kevin@M*U*S*H and Cerekk@bDv.
  * @boot/desc on one's own descriptor is no longer translated to
    @boot/me. [TAP]
  * Overflow of integer argument in giving pennies fixed. Report by
    Sholevi@M*U*S*H.
  * Typo in fun_vcross() fixed. [SW]
  * Configure does better when ssl shared libraries, but not static
    libraries, are available. You can use -D no_openssl to skip SSL checks.


& 1.7.7p33
Version 1.7.7 patchlevel 33                     June 3, 2004

Minor changes (internals):
  * IsPlayer, etc. macros rewritten for clarity by Luke@M*U*S*H.
  * Use enums in place of some more #defines and magic numbers. [SW]
  * New did_it_with() hc function simplifies passing a dbref as %0
    to did_it actions. [SW]
Fixes:
  * The SQL_OK power could get double-added. If this happened to you,
    delete one of them and double-check that all sql-using objects
    still have the power set. Report by Mordie@M*U*S*H.
  * Missing include in game.c fixed.
  * Improper include in bufferq.c fixed. Report by Leona and Walker@M*U*S*H.
  * Obsolete bzero() uses removed. [SW]
  * New win32/pennmush.dsp.
  * Help fix by bleeder@M*U*S*H.
  * Mac OS X linting [SW].


& 1.7.7p32
Version 1.7.7 patchlevel 32                     May 26, 2004

Major Changes:
  * SQL support. PennMUSH can now operate as an SQL client and perform
    queries against an SQL server. Currently only the MySQL server is
    supported. This adds the @sql command, the sql() and sqlescape()
    functions, and the Sql_Ok power. See README.SQL for some 
    additional information.  Mostly based on patches by Hans Engelen.
  * Creating a leaf attribute automatically creates associated branch
    attributes if they are not already present. [TAP]
  * When a $command matches on an object, but the object's use-lock or
    command-lock prevents the command from being run, the object's
    COMMAND_LOCK`FAILURE, COMMAND_LOCK`OFAILURE, and COMMAND_LOCK`AFAILURE
    attributes will be triggered if the $command never successfully 
    matched, rather than returning a Huh? to the player.
  * Exits and rooms may now run $commands. Rooms are treated as being
    located in themselves for purposes of location checks. Exits are
    treated as being located in their source room. Suggested by [TAP].
Commands:
  * 'empty <object>' attempts to get each item in <object> and put
    it alongside <object> (in <object>'s location).
  * 'give <object> to <player>' syntax added.
Minor Changes (user-visible):
  * @COST attribute is now evaluated, so you can make costs depend
    on who's paying, a selected item, etc. Suggested by Walker@M*U*S*H.
    Also, the amount given is passed in as %0, so you can code
    vendors that accept any amount.
  * New OBJID^<objid> lock atom.
  * The server now maintains a rolling log of activity (commands issued,
    evaluations parsed, and locks evaluated), that is dumped to the log 
    file on panic, or can be seen by God with @uptime. This aids 
    debugging code that causes a "clean" panic rather than a crash. 
    Suggested by Intrevis@M*U*S*H.
  * When checking a use/command/listen-lock on an object with patterns
    that get matched, we only check the lock once and cache the result,
    to prevent multiple lock evaluations if multiple patterns match. [TAP]
  * @chan/recall now shows nospoof tags for @cemit'd lines.
    Suggested by Sholevi@M*U*S*H.
  * SUSPECT flag can now be applied to any type of object.
    Suggested by Oriens@Alexandria.
Minor Changes (internals):
  * fun_escape() and fun_secure() use the same list of special characters, 
    rather than each having their own copy. [SW]
  * Buffer queue code used by @chan/buffer and the activity log refactored
    into src/bufferq.c and hdrs/bufferq.h.
  * Added mush_panicf(), with printf()-style format and arguments. [SW]
Fixes: 
  * @scan correctly shows attributes on parents again. Report by
    Wayne@PDX.
  * @shutdown/panic and @shutdown/paranoid work again. [SW]
  * A panic DB could be created before the database files were actually read,
    causing problems on the next restart. [SW]
  * Win32 and Debian installer portability fixes. [EEH]
  * Code cleanup around errno. [SW]
  * The locate() function now respects visibility and interactions.
    Report by Jules@M*U*S*H.


& 1.7.7p31
Version 1.7.7 patchlevel 31                     May 11, 2004

Minor Changes:
  * netmush is now started with only a single argument - the path to
    the configuration file. The error log file (typically game/netmush.log)
    is now configured in mush.cnf. Suggested by Vadiv@M*U*S*H.
  * The restart script now bases its decision about whether the mush
    is already running on the full path to the configuration file,
    which means you can leave mush.cnf named mush.cnf without fear
    of restart problems when multiple mushes are using the same
    host. This also facilitates make update. Suggested by Vadiv@M*U*S*H.
  * The GAMEDIR environment variable can be passed to 'make update'
    to cause it to update *.cnf files in directories other than
    game/ (using the template *.dst files in game/). 
    E.g.: make GAMEDIR=/home/othermush/game update
Commands:
  * @nscemit. Suggested by Mystery8@ST:AW.
Functions:
  * nscemit(). Suggested by Mystery8@ST:AW.
Flags:
  * New HEAVY admin flag, prevents an object from being teleported
    by a mortal between two containers they own. Admin without this
    flag can now be teleported.
Fixes:
  * Help fixes by Anri@AkaneaMUSH and Intrevis@M*U*S*H.
  * mix() now treats empty lists as empty, instead of containing a single
    null element. Report by Luke@M*U*S*H.
  * @power messages no longer reference 'flags'. Report by Nymeria@M*U*S*H.
  * Crash bug with @clone in new power system fixed.


& 1.7.7p30
Version 1.7.7 patchlevel 30                     May 6, 2004

Major changes:
  * CHAT_SYSTEM option removed. If you don't want to use the chat system,
    use restrict.cnf to disable @channel, @chat, etc.
  * USE_MAILER and MAIL_ALIAS options removed. If you don't want to 
    use the @mail or @malias systems, use restrict.cnf to disable
    the associated commands.
  * QUOTA, EMPTY_ATTRS, and FUNCTION_SIDE_EFFECTS options are now 
    runtime options, instead of compile-time.
  * SINGLE_LOGFILE option removed, and log filenames are now 
    runtime options. You may now give the same name to
    multiple log files and get a more fine-grained version of the
    same effect. Based on ideas by Vadiv@M*U*S*H.
Minor changes:
  * New IP^ and HOSTNAME^ tests for boolexps. Suggested by Luke@M*U*S*H.
  * ALLOW_NOSUBJECT option removed. We always use the beginning of the
    message as the subject if one is not provided.
  * JURY_OK and UNINSPECTED_FLAG options removed. Use @flag to add
    flags if you need them. ONLINE_REG and VACATION_FLAG options
    removed (default to always defined, add or remove with @flag as
    desired).
  * MEM_CHECK option removed from options.h; it is now a runtime
    option in mush.cnf.
  * @function/restrict can be applied to softcoded @functions, and
    @function/add can accept a list of restrictions as a fifth argument.
    Patch by Luke@M*U*S*H.
  * log_walls run-time configuration option removed. Use the
    logargs option in restrict.cnf instead.
Fixes:
  * Crash bug in anonymous attributes fixed. Report by Intrevis@M*U*S*H.
  * lplayers() was broken. Report by T'orA@M*U*S*H.
  * Failing to create a player by providing a bad password now gives
    a better error. Suggested by [NJG].
  * Setting/clearing a chan title on a notitles channel works, but
    reminds you that titles are off. Suggested by Dan@InNomine.
  * haspower_restricted removed from mushcnf.dst to stop spurious
    warning on startup. Report by Nymeria@M*U*S*H.


& 1.7.7p29
Version 1.7.7 patchlevel 29                     April 28, 2004

Major changes:
  * Anonymous attributes via #lambda. See help anonymous attributes. [SW]
  * Wizards (other than God) and royalty are no longer treated as No_Pay
    unless the No_Pay power is explicitly set on them, although they
    can still give (themselves or others) as many pennies as they wish.
    This helps stop runaway wizards in the queue (they'll run out of cash
    like anyone else). To get the old behavior back, @power your admin
    No_Pay. You probably want to @power any globals that use search(),
    children(), mail*stats(), etc, No_Pay as well. Suggested by Walker@M*U*S*H.
  * game/restrict.cnf, alias.cnf, names.cnf are renamed in the tarball and
    made with make update like mush.cnf. Suggested by Philip Mak. [SW]
  * @powers now operate under the same code as the @flag system, so God
    can add and modify powers in the MUSH with @power/add, etc. 
Commands:
  * @nsemit, @nsoemit, @nslemit, @nsremit, @nszemit and function forms
    of the same. Suggested by Cloud@M*U*S*H.
Functions:
  * andlpowers(), orlpowers(), andpowers(), orpowers().
  * align() performs fancy text alignment tricks. Patch by Walker@M*U*S*H.
  * sent() and recv() show more player descriptor data from SESSION.
    Suggested by Ricochet@M*U*S*H.
  * scan() with a single argument assumes the executor's point of
    view. Suggested by Cheetah@M*U*S*H.
  * valid() can also check for syntactically correct passwords,
    command names, and function names.
Minor changes:
  * No more CRYPT_SYSTEM in options.h. We try everything and we
    always reset passwords to SHS. Patch by Vadiv@M*U*S*H.
  * Wizards and other privileged players can @chan/recall on channels they're
    not on. Suggested by Trispis@M*U*S*H. [SW]
  * A separate ip address to bind the SSL port to can now be specified
    in mush.cnf.
  * @flag/type allows God to change flag types. Suggested by Renee@ShoreSide.
  * After each @startup is enqueued (during startup or @restart/all),
    we immediately run up to 5 queue cycles. This allows, e.g., God's
    @startup to up to five levels of @dol/@tr/@switch/etc and still have
    the queued code run ahead of other startups. This requires that you
    keep God's dbref as #1. Based on comments by Philip Mak and o
    Trispis@M*U*S*H.
  * The message after successful @password is now clearer, to avoid
    confusion in some unusual cases. Report by Kholnuu.
  * Makefile is no longer set executable. Report by Luke@M*U*S*H.
  * Server now handles telnet NOP and AYT commands. Suggested by
    Philip Mak and Liz (author of Muckclient).
  * announce.c is no longer distributed. portmsg.c cleanup.
Fixes:
  * @undestroy on an invalid (garbage, or !going) object now produces
    an error message. Suggested by T'orA@M*U*S*H.
  * On shutdowns, all queue deposits are now refunded.
  * Ansi behavior on second and later lines of text fixed by Walker@M*U*S*H.
  * Database reading improvements for win32 - ideally, you should now
    be able to read a database written on win32/unix on either system.
  * allof() now evaluates its separator argument. [SW]
  * firstof() doesn't add an extra space before the value it returns. [SW] 
  * Slackware portability fixes by Dale @ Wolfpaw.net hosting
  * ]page properly noevals (the right hand side) now. Report by 
    Cheetah@M*U*S*H.
  * Partial channel match listings no longer reveal channels the player
    isn't allowed to see. Report by Taz.
  * Help fixes by Trispis@M*U*S*H and Tanaku@M*U*S*H.
  * ssl() and terminfo() don't work on other players unless you're
    See_All, as promised. Based on patch by Tanaku@M*U*S*H.
  * lcon, etc. all do an INTERACT_SEE interaction check now.
    Suggested by Thor@bDv.
  * Code cleanup. [SW]
  * Fixes from 1.7.6p16


& 1.7.7p28
Version 1.7.7 patchlevel 28                     March 12, 2004

Major changes:
  * You can add customized configuration parameters to set in mush.cnf
    by adding a couple of new lines into the local_configs() function
    in local.c. (YOU MUST UPDATE YOUR local.c FROM local.dst IN THIS
    PATCHLEVEL). Patch by grapenut@M*U*S*H.
  * Object ids: An object id is the string "#dbref:ctime"
    where #dbref is the object's dbref and ctime is its creation time
    in integer format. The %: substitution returns this
    id for the enactor, and the objid() function returns it for an
    arbitrary object. Object ids can be used in place of softcode that 
    stores dbrefs to insure that a recycled dbref isn't used in place
    of the intended one. The matcher code will also match objects by
    id any time it's matching by dbref.
  * @command/add and @command/del. You can add a custom command
    (which will have the same precedence as a standard server command),
    and then @hook it to softcode, effectively promoting the precedence
    of softcoded globals, and letting them take advantage of some
    command parser settings. Patch by Walker@M*U*S*H.
Functions:
  * tr() accepts ranges of characters like a-z instead of having to
    give each one. [SW]
  * escape() also escapes parens and commas now. Suggested by Philip Mak. [SW]
  * time() can now take a time offset or object argument (in the latter
    case, time offset is read from object's TZ attribute). Patch by
    Walker@M*U*S*H.
  * vcross() performs cross products of vectors. [SW]
  * merge() can now take a list of characters. [SW]
Minor changes:
  * You can @set multiple flags at once by giving them as a list.
    Suggested by Walker@M*U*S*H and others.
  * Channel names are recognized when surround by <>'s, too. [SW]
  * 'move' is now a command_alias for 'goto' (in alias.cnf), and not
    a separate command.
  * PAGE_LOCK`{,O,A}FAILURE attributes now activated when a page/pemit fails
    due to the victim's @lock/page. Suggested by Sholevi@M*U*S*H.
  * Tweaked game message for failing to provide correct password to
    @password. Suggested by Philip Mak.
  * New command 'warn_on_missing' (defaults to disabled), aliased to the
    '[' character. If enabled, players who attempt to write commands
    starting with functions will get errors. Suggested by [SW] and
    Cheetah@M*U*S*H.
  * Renaming something triggers its ONAME and ANAME attributes, if present.
    The old name is passed as %0; the new as %1. Suggested by Philip Mak.
  * Owner information on ex/br is reported using the usual object_header()
    so dbref and flags appear. Suggested by Rince@M*U*S*H.
  * Flags that are F_DARK or F_MDARK no longer appear on @flag/list
    by non-admin. Suggested by Philip Mak.
  * Warn players who set themselves SHARED with a weak zone lock.
    Suggested by Philip Mak. [SW]
  * @halt can now take "here". Suggested by Thor@bDv.
  * When parsing eqsplit commands, don't evaluate the left side
    of the equal sign if the command was run with ].
Fixes:
  * Fixes to robustify file reading on Windows systems.
  * The 'nofixed' command restriction works as expected now (previously,
    you had to use 'nofix').
  * Exit movements are now translated into explicit GOTO commands,
    so @hooks and restrictions on GOTO are now applied. Patch by
    Walker@M*U*S*H.
  * The AE/ae accent characters can now be produced (accent(a,e)).
    Patch by Luke@M*U*S*H.
  * @hook/ignore would double-evaluate arguments. Reported by 
    Ambrosia@M*U*S*H. [SW]
  * Mingw error in src/Makefile.SH fixed. Report by Thor@bDv. [SW]
  * Help fixes by Cerekk@bDv, Mike Griffiths, Steve Varley, Thor@bDv, [SW],
    Dahan, Jason Stover, and Kyieren@M*U*S*H.
  * cmdlocal.dst now includes flags.h. By Dahan.
  * Win32 portability fixes by Dahan, Nathan Baum, [EEH].
  * utils/mkcmds.sh is now smarter about choosing temp filenames, so
    parallel make should work. Fixed by Cheetah@M*U*S*H.
  * The Zone: data in examine could be wrong.


& 1.7.7p27
Version 1.7.7 patchlevel 27                     January 25, 2004

Minor Changes:
  * New etimefmt() formatting codes to make it easier to get nice-looking
    results without 0-valued times. Suggested by ranko_usa@M*U*S*H. [SW]
  * Autodetect existence of /usr/kerberos/include to make compile 
    easier for RH9 sufferers.
  * src/Makefile is now autobuilt from src/Makefile.SH. IF you use
    local hacks that require src/Makefile, this is likely to be a problem
    for you. You'll want to start patching Makefile.SH instead.
  * Fewer warning flags are now provided to the compiler by default.
    You can set your own warning flags instead by defining the
    warnings variable in config.over.
Fixes:
  * The startups option actually does what it's supposed to now.
  * Potential DOS in etimefmt fixed. Report by Ashen-Shugar. [SW]
  * Code cleanup. ok_tag_attribute should work. [SW]
  * Channels are automatically ungagged only on initial connection
    (not reconnection, partial disconnection, etc.). Suggested by
    Mordie@M*U*S*H.
  * notify() calls during startup would crash. Reported by Mordie@M*U*S*H. [SW]
  * Fixes from 1.7.6p15.


& 1.7.7p26
Version 1.7.7 patchlevel 26                     December 15, 2003

Commands:
  * Add /regexp switch to @switch and @select. Suggested by BladedThoth. [SW]
  * New /spoof switch to @pemit, @remit, @lemit, @oemit, @emit,
    causes the message to appear to be generated by the cause, rather
    than the enactor, which makes globals like $ooc show the right
    NOSPOOF information (instead of the name of the global command object).
    Patch by Philip Mak.
Functions:
  * hostname(), ipaddr(), and cmds() take a dbref or descriptor number
    of a connected player and return the hostname, ipaddr, and number
    of commands executed. Suggested by Sholevi@M*U*S*H and Renee@ShoreSide,
    code by Sholevi@M*U*S*H.
  * Add reswitch*() functions. Suggested by BladedThoth. [SW]
  * insert() can take a negative position argument to insert from
    the right. Patch by Sholevi@M*U*S*H.
  * New firstof() and allof() functions return the first true value
    or all true values from a set of expressions. Patch by Sholevi@M*U*S*H.
  * tr() works like the Unix utility, translating characters. Patch
    by Walker@M*U*S*H.
Attributes:
  * Attributes may be set DEBUG to cause their evaluation to be
    debugged selectively. Patch by Pozzo@SWForum.
  * @desc can no longer be gotten remotely without privileges.
    To implement this, a new attribute flag NEARBY was added,
    which prevents visual attributes from being remotely accessed.
    See new configuration directive 'read_remote_desc' if you prefer
    the old behavior. Patch by Philip Mak.
  * @desc on privileged objects can now be evaluated by mortals.
    To implement this, a new attribute flag PUBLIC was added,
    which overrides safer_ufun for that attribute. This flag is dangerous
    and should be avoided unless you are sure you know what you're doing.
    Patch by Philip Mak.
Minor Changes:
  * "+<channel> <text>" complains if <channel> is ambiguous, and
    displays a list of matching channels. Patch by Luke@M*U*S*H.
  * Code cleanup around @oemit by Philip Mak.
  * If an object has an IDESCFORMAT but no IDESCRIBE, interior viewers
    now see the DESCRIBE formatted by IDESCFORMAT (instead of
    the DESCRIBE formatted by DESCFORMAT). Suggested by Philip Mak.
  * Ported to Win32 with the Mingw development environment. 
    See win32/README.mingw for compile instructions. [EEH]
  * null() can now take any number of arguments. Patch by Walker@M*U*S*H.
  * Using @chan/quiet to control the quiet flag on a channel no longer works
    (Actually, it never did). Use @chan/priv instead. [SW]
  * The NO_WARN flag now prevents disconnected room warnings, too.
    Suggested by several people. Patch by Philip Mak.
  * @sitelock/name !name still unlocks a reserved name, but no longer 
    removes that name from names.cnf. Suggested by Nymeria. [SW]
  * Some cleanup of fopen() calls. [SW]
  * The reference to channel Creator is now Owner in @chan/decomp.
    Suggested by Howie@NFTrekMUSH. [SW]
  * The name of the channel being tested is passed as %0 in channel locks.
    Suggested by Philip Mak. [SW]
  * help for @chownall mentions the /preserve switch.  Warnings from @chown 
    and @chownall tell which objects they're for. Suggested by
    Mordie@M*U*S*H. [SW]
  * Home wrecking is allowed again. Suggested by Philip Mak.
Fixes:
  * Puppets in containers with @listen container=* now hear the
    outside world correctly. Patch by Philip Mak.
  * The email sent on player registration now double-quotes the
    player name in the example connect statement. Suggested by
    David Kali.
  * Two rooms should never be nearby() each other. Fix by Philip Mak.
  * can_look_at() now handles the look/out case, too. Fix by Philip Mak.
  * Help fixes by Viila@M*U*S*H, MetBoy@M*U*S*H, Cheetah@M*U*S*H.
  * @flag/alias or @flag/add without giving an alias no longer crashes 
    the MUSH.  Report by Wildfire.
  * Correctly retrieve user full name from /etc/passwd fields under
    Linux in Configure. Record it in config.sh. Reported by Vadiv@M*U*S*H.
  * Debian package changes. [EEH]
  * As the help promises, XCH_CMD and SEND attributes don't work
    for non-Wizards. Really.


& 1.7.7p25
Version 1.7.7 patchlevel 25                     October 30, 2003

Fixes:
  * Crash bug in the interaction between parents and attr trees
    fixed. Report by Walker@M*U*S*H.
  * Improvements to how locks are decompiled. Built-in locks with the
    no_inherit flag cleared are handled better.  If the object doing
    the @decompile is referenced in a lock key, it's decompiled as 'me'
    rather than by dbref, to make it easier to port between games.
    Report by Cerekk@bDv. [SW]
  * The error typically logged by info_slave on a mush crash is worded 
    better. [SW]
  * panic() renamed mush_panic() as the Mach kernel now has a public
    system call panic(). Report by Jeff Ferrell.


& 1.7.7p24
Version 1.7.7 patchlevel 24                     October 19, 2003

Minor Changes:
  * The puppet flag can now apply to rooms. Suggested by Philip Mak.
  * @tel/inside allows priv'd players to teleport into another player's
    inventory (instead of to their location). Suggested by Philip Mak.
Fixes:
  * Startups from a created minimal.db did not properly initialize
    the objdata htab, so subsequent use of that htab (e.g. adding
    players to channels) would crash. Report by [LdW].
  * Help fixes by BladedThoth@M*U*S*H and Philip Mak.
  * Attempting to clear a branch attribute when it has leaves now
    gives a better message. Also better message for inability to
    write an attribute due to tree issues. Patch by Luke@M*U*S*H.
  * Bug in @debugforwardlist fixed by Luke@M*U*S*H.


& 1.7.7p23
Version 1.7.7 patchlevel 23                     October 10, 2003

Major Changes:
  * Forking dumps now work with the chunk memory manager. [TAP]
Minor Changes:
  * Chunk allocator improvements in partial read/writes and for
    Win32. [TAP]
  * Use the SHA0 algorithm from OpenSSL instead of our own when possible. [SW]
Functions:
  * New digest() function for generating checksums via a variety of 
    algorithms. [SW]
  * cowner() returns the dbref of a channel's owner. Suggested by
    Sholevi@M*U*S*H. [SW]
  * Added baseconv(), for converting numbers from one base to another.
    Useful for tweaking things like Myrddin's bboard code. Suggested
    by many people. [SW]
Fixes:
  * Remove warnings in set.c and pcre.c. Report by Nymeria@M*U*S*H
  * @power messages now show the canonical name of the power.
    Suggested by Cheetah@M*U*S*H.
  * Adding DARK players to channels produced a duplicated message.
    Reported by Mystery8@ST:AW.
  * Players set WIZARD and ROYALTY would get double notification 
    of some GAME: messages. Fixed now. [SW]
  * Chatdb corruption possible when admin add players to channels.
    Reported by several folks, diagnosed by Mordie@M*U*S*H.


& 1.7.7p22
Version 1.7.7 patchlevel 22                     September 30, 2003

Minor Changes:
  * When possible, sockets are now set SO_KEEPALIVE and TCP_KEEPIDLE.
    This may help prevent disconnections of idle players behind
    poorly designed NAT routers and the like, and make the use of
    the IDLE command unnecessary. Patch by Philip Mak.
  * Better failure messages for 'get blah's blah', especially when
    the container or contained object is ambiguous. Suggested by
    Philip Mak. 
Fixes:
  * Attempting to unset attribute flags actually set them.
    Report by Ambrosia@M*U*S*H. [SW]


& 1.7.7p21
Version 1.7.7 patchlevel 21                     September 23, 2003

Major Changes:
  * Attribute trees. Attributes may now be organized hierarchically
    like files and directories in a filesystem, using the backtick (`)
    character as the branch separator. Attribute access restrictions
    propagate down trees. New wildcard ** is introduced to match
    all attributes at all tree levels. Suggested by Tabbifli. [TAP]
Locks:
  * New framework for performing lock failure activities in hardcode.
    As a proof-of-concept, the attributes FOLLOW_LOCK`FAILURE,
    FOLLOW_LOCK`OFAILURE, FOLLOW_LOCK`AFAILURE do what you'd expect
    when set on a potential leader.  Suggested by Sholevi@M*U*S*H.
Channels:
  * New per-channel flags NoTitles, NoNames, and NoCemit do what you'd
    expect. Set them with @chan/privs. Based on suggestion by 
    Saturn@M3.
  * @chan/recall/quiet omits timestamps. Suggested by Vadiv@M*U*S*H.
Commands:
  * 'help <wildcard-pattern>' now lists all help topics that match that 
    pattern.  By popular request. [MUX,SW] 
  * @flag/letter can be used to change or clear the one-letter alias for a 
    flag.  Suggested by Nymeria@M*U*S*H. [SW]
  * @flag/list by God notes disabled flags. Suggested by Nymeria@M*U*S*H. [SW]
Functions:
  * rand() now comes in a two-argument (low,high) flavor, and randword()
    selects a random word from a list. The latter is aliased to
    pickrand() to match Mux's name. Patch by Luke@M*U*S*H.
Minor Changes:
  * Although we're Pueblo 2.50 compliant, go back to sending Pueblo 1.10
    as the server version until everyone upgrades their clients so
    they can handle the 2.50 string. Suggested by Shirow.
  * The locate() function is no longer noisy (no longer notifies
    the executor in addition to returning a value). Suggested by
    Mystery8@ST:AW. 
  * @lock/interact now has a higher priority than other interaction
    checks, so it will work for Wizards. Suggested by Viila@M*U*S*H.
  * Tweaks to facilitate a Debian package of PennMUSH. [EEH]
Fixes:
  * max descriptor could get stomped in some cases. [SW]
  * Removed extra struct def in hdrs/mushtype.h. Suggested by Kyle.
  * Help tweak by Kevin@M*U*S*H.
  * Fix to locks on players messing up their connection failure counts.
    Reported by Luke@M*U*S*H.
  * Fix to @entrances by Luke@M*U*S*H.
  * Fix to Win32 not handling a missing minimal.db by Luke@M*U*S*H.
  * The confirmation message for setting/clearing attribute flags would use
    the flag name given as an argument, not neccessarily the the full name of
    the flag. Reported by Vadiv@M*U*S*H.  [SW]
  * Fix a potential memory leak in ident.c [SW]

& 1.7.7p20
Version 1.7.7 patchlevel 20                     September 4, 2003

Major Changes:
  * minimal.db is no more. If you start up the server and there's no
    db to be found, it creates a new minimal database in memory
    on the fly. Feel free to delete your coopy of minimal.db. [SW]
    (In related news, the default OSUCC on #0 in minimal.db is gone. 
    Suggested by Cheetah@M*U*S*H. So much for the mists.)
Minor Changes:
  * SSL connections are now ended before the dump when rebooting,
    but their descriptor information sticks around to ensure that
    their @adisconnect is run after the reboot. Based on suggestions
    by Vadiv@M*U*S*H and [TAP].
  * When _DEBUG is defined in a win32 build, don't copy pennmush.exe
    to pennmush_run.exe. Makes debugging easier. Patch by Luke@M*U*S*H.
  * In pueblo mode, no longer clear past images after each room look.
    Patch by Konstantine Shirow.
  * In pueblo mode, we no longer render ansi attributes or colors with
    HTML tags; we assume the client will correctly handle them as ansi
    intermixed with Pueblo. This solves a variety of problems.
    Based on a discussion with Konstantine Shirow.
  * When matching $commands and ^listens, insure that a matching attribute
    exists before testing locks. This may break some strange locks using
    %c, but hopefully won't. Suggested by Cheetah@M*U*S*H.
  * The @scan command temporarily sets %c to the command to be scanned
    (without "@scan" prefixed) so that it can detect commands that use
    %c-matching. Based on ideas from Cheetah and Walker@M*U*S*H.
  * Added support for Pueblo's md5 checksum. We track it on each
    descriptor, though we don't do anything with it currently.
  * Speed-up to fun_merge. Patch by Walker@M*U*S*H.
  * Internal cleanup of flags in channel_broadcast.
  * Wizards may @name themselves to names forbidden in names.cnf.
    Patch by LeeLaLimaLLama@M*U*S*H.
  * We are now forgiving of stupid non-RFC-compliant telnet clients
    that send CR only even when they claim to be sending CRLF
    (Read: MS Windows XP telnet). MS bug reported first by
    Intrevis@M*U*S*H.
  * Misleading restrict_command on @clone removed from restrict.cnf,
    as @dig/@open/@create permissions already control @clone.
    Suggested by Philip Mak.
Functions:
  * lstats() and quota() now allow objects to see stats/quota on other
    objects they control (e.g., on their owners, perhaps). Suggested
    by Philip Mak.
  * hastype() can now test for type GARBAGE. Suggested by Tanaku@M*U*S*H.
Commands:
  * The new ']' command prefix causes the rest of the command-line
    not to be evaluated by the expression parser. Try: ]think [add(1,1)]
    Inspired by Elendor.
  * @hook/ignore. [mux]
  * @hook/override [Rhost, though they don't call it that]
Attributes:
  * @debugforwardlist forwards DEBUG output to dbrefs on the list.
    Suggested by Balerion@M*U*S*H.
Tests:
  * A new test harness for developing regression test suites in perl
    for PennMUSH is now included; few test suites are. If you can figure
    out how to use this, write some tests for us! (If you can't, don't
    ask about it, please :)
Locks:
  * @lock/interact can prevent other players from transmitting any
    normal sound to you (that is, you won't hear them speak, pose, 
    emit, etc., like gagging them in a client). It doesn't control
    page (use @lock/page) or @mail (use @lock/mail). You still
    hear 'presence' messages (connects/disconnects/arrivals/leaves)
    so you can have a sense of who can hear you but you can't hear.
    Patch by Philip Mak.
Fixes:
  * Configure script no longer keeps adding -lssl -lcrypto over and
    over to the Makefile. Report by Sholevi@M*U*S*H.
  * Portability fixes for compiling with MSVC5 by Luke@M*U*S*H.
  * The behavior of spaces inside parentheses that aren't part of a
    function has been improved. Report by Jason Newquist. [TAP]
  * txt/*.html files were being improperly escaped before being
    sent to Pueblo connections. Report by Konstantine Shirow.
  * mushdb.h includes flags.h, as it relies on constants from there.
    Suggested by Philip Mak.
  * Better error reporting on some failure messages in chunk allocator.
    Patch by Philip Mak.
  * @config/set with an invalid option now returns an error.
    Report by Sholevi@M*U*S*H.
  * Fix to interaction checking in notify_anything that could result
    in the wrong check being performed. Report by Philip Mak.
  * Help fixes by LeeLaLimaLLama@M*U*S*H, Sunny@M*U*S*H, Sketch@M*U*S*H.


& 1.7.7p19
Version 1.7.7 patchlevel 19                     August 19, 2003

Fixes:
  * When SSL connections are dropped on reboot, other players weren't
    seeing disconnect messages. Now they are.
  * Two calls to flaglist_check_long didn't get converted to the new
    abstraction layer, making flag_broadcast not work right.
    Report by Luminar@M*U*S*H.


& 1.7.7p18
Version 1.7.7 patchlevel 18                     August 19, 2003

Major Changes:
  * The flag handling code has been additionally abstracted to 
    allow, in a future patchlevel, @powers to be handled in the
    same way that flags are now.
Minor Changes:
  * Wrap the OS-dependant code for making sure the mush always has a free
    file descriptor available for use in a pair of functions. [SW]
Fixes:
  * Linted some ssl-related warnings. Reported by Cheetah@M*U*S*H.
  * Compile failed in timer.c unless USE_MAILER was defined.
    Reported by Sunny@M*U*S*H.
  * Bug allowing players to view internal and mortal_dark attributes
    introduced in p17 has been fixed. [TAP]


& 1.7.7p17
Version 1.7.7 patchlevel 17                     August 11, 2003

Major changes:
  * SSL support, including server and client authentication as options.
    This should be considered experimental.  New ssl() function returns 1
    if a player/descriptor is using SSL, 0 otherwise. New file README.SSL
    documents how to set up SSL. Two things to note:
    - SSL connections are dropped on @shutdown/reboot, so SSL users may 
      wish to write client triggers to reconnect. 
    - Output flushing behaves slightly differently for SSL connections.
  * The way lock keys are handled internally has been rewritten to allow
    them to be tracked by the same chunk-management code that handles
    attributes. [SW]
  * @mail message texts are now stored with the chunk-management code. [SW]
  * The new code can no longer read databases created by versions of Penn
    before 1.7.5p0. If you need to do this, load it in 1.7.6, shutdown,
    and use that database. [SW]
Minor changes:
  * A new minimal.db is distributed (older ones probably won't work,
    and this one probably won't work with older versions). [TAP]
  * Contents/exits lists and functions that use first_visible (like
    lcon, lexits, etc.) are now affected by INTERACT_SEE. Suggested by
    Prospero@Metro.
  * @chan/recall now displays the last 10 lines by default. Use
    @chan/recall <chan>=0 to get the full buffer. Suggested by [TAP].
  * Various boolexp tweaks. [SW]
  * @power provides more verbose feedback. Suggested by Mordie@M*U*S*H. [SW]
  * Additional chunk tweaks, including limiting migrations to one
    per second. [TAP]
  * PROFILING #define for use when profiling the code (surprise). This
    just disables the CPU timer.
  * When matching $-commands, only call the slower capturing wildcard match
    function when we already know it succeeds, since it won't most of the time.
    The faster non-capturing function is checked first to find a match. [SW]
  * PCRE is initialized once, at startup, rather than testing to see if it has
    to be done before each place regular expressions are used. [SW]
  * The TERSE flag now applies to objects, not just players. Suggested
    by Aur@M*U*S*H.
  * The terminfo() function now returns SSL status as well.
  * help-like commands without arguments now use the command name
    as the argument. E.g. 'news' now looks for topic 'news', instead of
    'help'. If not found, we fall back on help. Patch by Mike Griffiths.
  * When an object is zoned to an unlocked ZMO, the ZMO is now autolocked
    to =me instead of $me, because it's probably less confusing.
    Suggested by Luke@M*U*S*H.
  * @name now automatically trims leading and trailing spaces from its
    newname argument, to avoid confusing people who use edit() to 
    generate new names and leave in spaces. Report by [TAP], patch by [SW].
Commands:
  * New 'logargs' and 'logname' restrictions in restrict.cnf allow
    per-command logging. Suggested by Saturn @ M3.
Functions:
  * The sha1() function has been renamed sha0(), since that's what it
    really does. [TAP]
  * trimtiny() and trimpenn() work like trim(), but force the TM or
    Penn argument style.
  * New 'logargs' and 'logname' restrictions in restrict.cnf allow
    per-function logging. Suggested by Saturn @ M3.
Fixes:
  * The side-effect version of name() was producing a weird return
    value. Reported by Saturn@M3.
  * Problems with restrict_command and restrict_function with multiple
    restrictions now fixed. Report by Sholevi@M*U*S*H.
  * stddef.h now included in src/extchat.c. Report by [EEH]. [SW]
  * INFO output now includes a missing newline. Report by [EEH]. [SW]
  * help BUILDER updated. Report by Laura Langland-Shula.
  * down.txt message wasn't being sent. Report by Sholevi@M*U*S*H. [SW]
  * New Win32 project files that include the chunk code. [EEH]
  * @chan/what no longer highlights the channel's name, as this is
    confusing if you use ansified channel names. Suggested by 
    Oriens@Alexandria.
  * ex/mortal now operates more correctly. Report by Amy Kou'ai.
  * Fixes from 1.7.6p13.

& 1.7.7p16
Version 1.7.7 patchlevel 16                     June 23, 2003

Commands:
  * New switch /room for 'with' to run a $command available in a remote
    location. Suggested by Mike Griffiths. [SW]
Functions:
  * Added the terminfo() function, which returns information about a
    client's name and capabilities for a particular connection. [SW]
  * New lports() function. Like lwho() but returns port descriptors.
    For mux2 compatibility. [SW]
  * Functions that return information about a connected player now treat
    integer arguments as a port descriptor to look up, rather than using
    the least-idle connection of a player. To force a player name to
    be treated as such even when it's a number, prefix it with a * in
    softcode. For mux2 compatibility. [SW]
  * Players can use ports() on themselves and use the descriptors
    they're connected to as arguments to the information functions.
    For mux2 compatibility. [SW]
Minor Changes:
  * Compute various chunk stats (total used, total free space, etc.)
    on demand instead of keeping running totals. [TAP]
  * @chan/what displays information about a channel's recall buffer, if any.
    [SW]
  * @chan/recall'ed lines are more clearly marked as such. Suggested by
    Oriens@Alexandria. [SW]
  * Consolidation of a common idiom used to format times throughout the source
    into a simple function call. [SW]
  * The time a @mail was sent was stored, unusually, as a string.
    No longer. Now it's handled the same way as all other times. [SW]
Fixes:
  * Bug in resizing @chan/recall buffers fixed. Reported by Oriens@Alexandria.
    [SW]
  * Objects with user-defined locks had problems with finding built-in locks
    on the object. Reported by Walker@M*U*S*H. [SW]
  * Unregistered() macro was checking wrong flag name. Report by
    Matt Kirby.
  * Help fix by Adu@M*U*S*H.
  * Potential problem with ambigious names in the information functions fixed.


& 1.7.7p15
Version 1.7.7 patchlevel 15                     June 1, 2003

Fixes:
  * Problem with checking command flag masks when the number of
    flags was an even multiple of 8. Reported by Nymeria and
    Mordie@M*U*S*H.
  * Tweak to improve efficiency of ancestor checking code and delint
    warning reported by Cheetah@M*U*S*H.
  * SESSION output no longer misaligned with 5-digit dbrefs.
    Reported by Cheetah@M*U*S*H. [TAP].
  * Fixes from 1.7.6p11.
  * game/txt/index-files.pl now uses locale information in the
    environment to, e.g., correctly lowercase accented characters.
    Report by Krad@M*U*S*H.
  * Modified several Makefile.SH targets to prevent Javelin from
    releasing patches that don't have the autogenerated files
    up-to-date for Windows folks.
  * Removed some dependence on typedefs that may or may not be in system
    header files. [SW]
  * Patch compiler warnings. [SW,EEH]
  * Help fixes by Mike Griffiths and Oriens@Alexandria.


& 1.7.7p14
Version 1.7.7 patchlevel 14                     May 22, 2003

Major changes:
  * Ancestors: an object can be configured to serve as an 'ultimate
    parent' of every room, exit, thing, or player, and attributes
    that are not found on an object or any of its parents may be inherited
    from the ancestor for that object type.  The ORPHAN flag prevents
    ancestors from being used on an object.  Patch by Walker@M*U*S*H.
  * Mail messages now track not only the dbref of the sender but the
    sender's creation time, so messages from dbrefs that have been
    nuked and recreated can be distinguished from messages from the
    original sender. This modifies the maildb and make it not usable
    with older versions. All existing @mail is grandfathered in, and
    can't be tracked this way. Suggested by Philip Mak.
  * New chunk memory allocator can be used to greatly reduce process
    memory requirements by swapping little-used attribute texts out
    to disk and caching often-used attribute texts in memory.
    This is incompatible with forking dumps, so if you use it,
    you'll do nonforking dumps.  Configurable in mush.cnf, see comments
    there. [TAP]
  * Hardcode: new interaction type INTERACT_PRESENCE marks the
    arrival/departure/connection/disconnection/grows ears/loses ears
    messages. Many message types that used to be considered auditory
    (like most @verb-style messages) are now marked as visual instead.
Functions:
  * strreplace() works like replace() for strings. [SW]
  * fraction(), for turning floating-point numbers into fractions. [SW]
  * root(), for finding roots higher than the square root. [SW]
Minor changes:
  * We now use wrapper functions atr_value and safe_atr_value instead of
    uncompress(AL_STR(...)) or safe_uncompress(AL_STR(...)), so we
    can do future work with attribute storage cleanly. [TAP]
  * @*payment attributes now receive the amount of money paid in
    as %0. Suggested by Sholevi and Time@M*U*S*H. [SW]
  * Config options that take times now accept a notation describing what kind
    of units to use. For example, 3600s, 60m, 30m1800s, and 1h all refer to
    the same period of time. Suggested by Time@M*U*S*H. [SW]
  * Doxygen commenting of non-static members is essentially complete!
    Pennhacks see: http://www.pennmush.org/docs/1.7.7/html/
  * The mail() function no longer matches non-player objects by name.
  * Several additional messages (locks, parents, etc.) are now quieted by
    the QUIET flag. Patch by [EEH].
  * New config option default_home sets the room to send homeless things
    to. [TAP]
  * Added visual progress indicators for utils/mkcmds.sh so that slow
    systems won't think they're hung. Suggested by Cheetah@M*U*S*H.
Fixes:
  * Fixes from 1.7.6p10.
  * The 'i' sort type was not properly implemented. Reported by
    Noltar and BlaZE@M*U*S*H.
  * Cleanup of all accesses to ATTR values to use AL_STR() in preparation
    for future work on attribute storage. [TAP]
  * The 'any' string for specifying flag types didn't work properly.
    Reported by Krad@M*U*S*H.
  * The connect screen may now appear correctly under windows telnet. [SW]
  * The more efficient channel buffer shifting code now handles
    pathological cases correctly.
  * The tag*() functions could leave tags open at the end of full
    buffers. No longer.
  * Code cleanup in src/notify.c.
  * @rejectmotd and @wizmotd set the wrong messages. Report by
    Konstantine Shirow. [SW]
  * Using @chan/buffer to resize a recall buffer gives feedback. Reported by
    Sholevi@M*U*S*H. [SW]
  * Help fix for grab() by Adu@AbryssMUSH.
  * You can no longer destroy the base_room (or default_home). Suggested
    by Philip Mak. [TAP]

& 1.7.7p13
Version 1.7.7 patchlevel 13                     April 9, 2003

Major changes:
  * Interactions (something like "realms" in mux2). Two functions
    in local.c can now be used to control conditions under which
    objects can see, hear, or match each other. Possibly useful for
    implementing umbral worlds, etc. Patch by Vadiv@M*U*S*H.
Functions:
  * children(), syntactic sugar for lsearch(all,parent,<dbref>).
    Suggested by Kyieren@M*U*S*H. Patch by BlaZe@M*U*S*H.
  * powers() can now take a second argument to set an @power.
    Suggested by Rob@BtFMUSH.
Minor changes:
  * @config/set can now set null strings. Suggested by Cheetah@M*U*S*H.
  * In restart, set LC_ALL as well as LANG from the given LANG value,
    in case the user's got an LC_ALL in their shell.
  * The channel buffer shifting code has gotten much more efficient.
    Suggested by [TAP].
  * @function/restrict can accept arguments of the form '!<restriction>'
    to clear a restriction. Suggested by Saturn@M3.
  * Most of the asterisk lines between different login message files
    have been removed. Suggested by Vadiv@M*U*S*H most recently.
Fixes:
  * Fixes from 1.7.6p9.
  * Win32 portability fixes. [EEH]
  * deny_silent in access.cnf was ignored in several cases, and no
    longer is. Patch by Cloud@Sci-Fi Chat
  * Help fixes by Cheetah@M*U*S*H and LeeLaLimaLLama@M*U*S*H.


& 1.7.7p12
Version 1.7.7 patchlevel 12                     March 21, 2003

Commands:
  * @channel/buffer creates a buffer for a channel to store the most
    recent messages broadcast on the channel. @channel/recall can be
    used to recall them. These are not stored across reboots and should
    be set up by #1's @startup.
Functions/Substitutions:
  * accname() gives the accented name of an object (applying @nameaccent).
  * %~ gives the accented name of the enactor.
Minor Changes:
  * The chat-related commands and functions have been moved out
    of bsd.c and funmisc.c and into extchat.c. Patch by Vadiv@M*U*S*H.
  * The notification stuff has been moved out of bsd.c and into a new
    notify.c file.
  * @name no longer requires a password for changing player names,
    and ignores one if given. Suggested by Ambrosia@M*U*S*H (and others).
  * @hook can not be used on the @password or @newpassword commands.
  * The dump_complete message is also shown after a forking dump,
    if one is defined. Suggested by Nathan Schuette.
  * @lock/leave on a room now prevents people within it from leaving
    via exits or via @tel. Suggested by Peter Bengtson, patch by
    BlaZe@M*U*S*H.
Fixes:
  * Fixes from 1.7.6p8
  * Cleanup of a few new db[x] mentions in the source to use dbdefs.h
    macros. Inspired by Vadiv@M*U*S*H.
  * @command/restrict didn't work properly for most flags, especially
    new ones. Reported by Caesar and Sholevi@M*U*S*H.
  * @pemit/list didn't honor NOSPOOF. Patch by Cheetah@M*U*S*H.


& 1.7.7p11
Version 1.7.7 patchlevel 11                     February 22, 2003

Commands:
  * New IDLE command (socket-level) does nothing, and does not update
    the socket's last_time (so it doesn't change idle times). Useful
    for people behind lame NAT firewalls that timeout their connections if
    nothing is sent for 5 minutes. Suggested by Bolt and BladedThoth@M*U*S*H.
Fixes:
  * Win32 (and other OS) portability fixes. [EEH]
  * Fixed the openssl Configure thing again. The right way, this time.

& 1.7.7p10
Version 1.7.7 patchlevel 10                     February 22, 2003

Fixes:
  * Fix to stupid typo in Configure script that breaks on systems
    without openssl. Argh.

& 1.7.7p9
Version 1.7.7 patchlevel 9                      February 20, 2003

Functions:
  * New function scan() works like @scan. Suggested by Viila@M*U*S*H.
Flags:
  * New flag, MISTRUST, prevents an object from controlling anything
    but itself.
Configuration:
  * mush.cnf directives ansi_justify, globals, and global_connects have
    been removed (they are now always on).
  * New unconnected_idle_timeout directive in mush.cnf controls
    timeouts for connections idle at the connect screen.
  * New max_guests directive in mush.cnf can limit the number of
    guests allowed to connect at once. Suggested by Sholevi@M*U*SH.
Minor Changes:
  * New lflags search class takes a list of flag names.
  * Improved connection failure messages.
  * Somewhat more informative message when you @chan/gag,hide,mute
    all channels at once. Suggested by Tanaku and Kevin@M*U*S*H.
  * Began commenting files using doxygen.
  * Internal code cleanup. Mostly converting some magic numbers to
    #define'd symbols, and some #define'd symbols to enums for better
    debugging and improved readability. Also some conversion of old
    K&R style functions. [SW]
  * sort() and the set functions understand all the same comparison
    types as comp(). [SW]
  * Case-sensitive comparison currently isn't always possible, depending
    on the locale the mush is running on. Help files reflect this. [SW]
  * @uptime shows the time of the last successful database save, and
    the time of future events like saves, not just the time until them.
    Suggested by Cheetah@M*U*S*H. [SW]
  * Improvements to reporting of failed saves. [SW]
  * Code cleanup. [SW]
  * tel() now takes a third argument that makes it function like
    @tel/silent. Suggested by Cheetah@M*U*S*H. [SW]
  * @idescformat operates like @descformat for internal descriptions.
    Suggested by Tanya@M*U*S*H.
Fixes:
  * local_startup() was getting run earlier than in the past due to
    changes in the startup sequence. This has been rectified, so
    local_startup() again runs after all other initialization (and
    just before all object startups are triggered). Report by
    BladedThoth and grapenut@M*U*S*H.
  * Improved testing for openssl libraries in Configure. The old
    approach used to cause problems on systems with runtime-only
    openssl installations without development libraries.
  * help opaque mentions that opaque blocks look/outside. Suggested
    by Cheetah@M*U*S*H.
  * itext() and inum() now generate an error on a null argument,
    regardless of tiny_math and null_eq_zero settings. Reported by
    Intrevis@M*U*S*H.
  * Another fix to the new matcher. Bug report by Kyieren@M*U*S*H.
  * @flag/alias was broken. Fixed. Reported by Kevin@M*U*S*H.


& 1.7.7p8
Version 1.7.7 patchlevel 8                      January 27, 2003

Minor Changes:
  * command_add now expects to receive the flag list and the
    switch list as strings. Folks who hack into cmdlocal.c should
    take note and read example in the new cmdlocal.dst
Fixes:
  * Players were not created with all the player_flags. In a related
    bug, checking of command flag restrictions wouldn't work with
    all flags. Reported by Cory Descoteau.
  * Flagmasks on commands weren't grown properly when flags were added.


& 1.7.7p7
Version 1.7.7 patchlevel 7                      January 25, 2003

Fixes:
  * Crash bug in zone-checking during @dbck fixed.


& 1.7.7p6
Version 1.7.7 patchlevel 6                      January 23, 2003

Major changes:
  * Rewrite of the flag system. The new system allows for any number
    of flags, which may apply to any set of object types (the flags/toggles
    distinction has been eliminated). Flags without single-character
    abbreviations are better supported. Flags are stored in the object
    database, and are referenced in hardcode and the db by the name
    of the flag rather than bit positions.  Older databases will be
    automatically converted to the new format on load, but can not be
    converted back (so make backups!). New flaglocal.dst file for
    hardcode patch hackers to add custom flags.
  * Rewrite of the matcher code (src/match.c). Some semantics of the
    matching have changed: matching adjectives are parsed earlier and
    restrict the match for greater efficiency; they also behave more
    close as described in the help with respect to object ordering.
    In addition, you can now do things by dbref without controlling
    the object in many cases that previously required control.
    Provoked by bug reports by Intrevis@M*U*S*H and Philip Mak.
Commands:
  * @flag allows God to manipulate flags within the game, including
    adding new flags. Flags additions/changes are maintained across
    reboots, so this command does not need to be run at every startup.
Functions:
  * lflags(), orlflags(), andlflags() return or test flag lists.
Minor changes:
  * New NUMVERSION macro defined in hdrs/version.h that can be tested
    by hardcode hacks to add code conditional on version.
  * Much cleanup of @wall. Minimally-user-visible changes:
    The @rwallemit, @rwallpose, @wallemit, @wallpose, @wizemit and
    @wizpose commands have been removed. @wall no longer accepts the
    /wizard, /royalty, and /pose switches, and @rwall and @wizwall accept
    the /emit switch. Suggested by Vadiv@M*U*S*H, though he'd really
    rather see @wall removed.
  * @lock and @unlock now show which type of lock was set/cleared.
    @lset now specifically notes that lock flags are being changed.
    Suggested by Tanaku@M*U*S*H.
Fixes:
  * @boot/me will no longer boot a connection if it is the sole
    connection the player, even if it's technically inactive.
    Suggested by Ambrosia@M*U*S*H.
  * @boot'ing an active self (by descriptor) crashes the MUSH.
    Discovered by Ashlynn@ChicagoMUSH.
  * The thorn and eth characters generated with accent() would
    convert to 'th' when stripped or viewed under NOACCENT, which
    could be very confusing in object names. Same for the German sharp
    s, which converted to 'ss'. Until we can cleverly set up separate
    tables for object name unparsing, these have been reverted to their
    old behavior so that stripaccents(accent(X,Y)) should return X for
    any X and Y. Reported by DeeJee, Intrevis, and Time (@M*U*S*H).


& 1.7.7p5
Version 1.7.7 patchlevel 5                      January 7, 2003

Fixes:
  * Fixes from 1.7.6p5.


& 1.7.7p4
Version 1.7.7 patchlevel 4                      January 2, 2003

Minor Changes:
  * When room_connects is on, @aconnect and @adisconnect also
    functions on things when players (dis)connect inside them.
    Suggested by Philip Mak. [SW]
  * Parser-enforced argument counts for user-defined @functions,
    as an option to @function.
Config:
  * New mush.cnf option max_global_fns allows increasing the number
    of @functions allowed without editing source code. If you change
    this, you should reboot the MUSH or bad things can happen.
    Suggested by hilikiradi@Dardalani.
Fixes:
  * mkcmds.sh doesn't always regenerate every file, only what's
    needed. Speeds up compiles. Suggested by Philip Mak. [SW]
  * Fixes from 1.7.6p4.


& 1.7.7p3
Version 1.7.7 patchlevel 3                      December 25, 2002

Commands:
  * @sitelock/check <host> tells you which rule, if any, would match.
Fixes:
  * The objdata hashtable routines had a serious bug that could
    cause crashes.


& 1.7.7p2
Version 1.7.7 patchlevel 2                      December 22, 2002

Major Changes:
  * The LOCAL_DATA define has been removed along with the pointer
    in the object structure. The local functions called on creation,
    destruction, and cloning are now always called. Objects can
    now store data in a single hashtable using the set_objdata()
    and get_objdata() functions. As a proof of concept, the transitory
    channel lists on objects are now stored here, and the "channels"
    pointer has been removed from the object structure. Design
    and much of the implementation by Vadiv@M*U*S*H.
Powers:
  * can_nspemit power can be used to provide access to @nspemit
    without a Wizard bit. [SW]
Functions:
  * lpos from Mux, TM3. [SW]
Fixes:
  * Fix to some gcc-specific macros reported by Peter Bengston and
    Michael Holbrook. [SW]
  * Improvements to stripaccents/noaccents conversions. [SW]
  * Fixes from 1.7.6p3.


& 1.7.7p1
Version 1.7.7 patchlevel 1                      December 17, 2002

Minor Changes:
  * ex obj/attrib returns the attribute value even if it's veiled,
    if a specific (non-wildcard) attribute is given. Suggested by
    Nhoj@M*U*S*H.
Fixes:
  * Win32 portability fixes. [EEH]
  * Fixes from 1.7.6p2

& 1.7.7p0
Version 1.7.7 patchlevel 0                      December 8, 2002

Major Changes:
  * Clients that understand telnet NAWS (See RFC 1073) can tell the mush
    what dimensions a given connection's display is.  Added the
    width() and height() functions, and SCREENWIDTH and SCREENHEIGHT
    psuedo-commands for getting/setting this information from the mush.
    This changes the reboot.db format and requires a full shutdown. [SW]
  * Two new atoms for locks. "#true" in a lock is always evaluated as true
    (anyone can pass), and "#false" is always evaluated as false (no one
    can pass). Suggested by Vadiv@M*U*S*H.
Internationalization:
  * The pronoun sets are no longer hardcoded. If you're running in a
    locale other than C or en*, you'll see weird looking pronoun descriptions
    for things like %s until a translation team translates them to your
    locale's language. Suggested by Dandy@M*U*S*H.
Attributes:
  * @DESCFORMAT can be used to separate description contents from formatting.
    Suggested by Philip Mak.
  * VEILED attribute flag causes attribute value not to be displayed
    on default examine, but otherwise accessible as usual. Good for spammy
    data attributes. See 'help attribute flags'. Suggested by Cheetah@M*U*S*H.
Commands:
  * examine/all shows contents of veiled attributes. Suggested by
    Intrevis@M*U*S*H.
Flags:
  * The FIXED and ROYALTY flags are no longer optional.
Minor Changes:
  * Object creation times are no longer optional.
  * Warnings are no longer a compile-time option; they're turned on.
    You can stop automatic warnings in mush.cnf, as before.
  * Cleanup of the telnet-option code in general. [SW]
  * Consolidation of much of the code for functions that return information
    about the least-idle connection of a given player. [SW]
  * The tiny_attrs configuration option has been removed.
  * Removed a lot of preprocessor checks for conditionally including header
    files that always succeed because they're standard C headers. [SW]
  * Removed the Size_t typedef in favor of the standard size_t. [SW]
  * Some optimization hints for the GCC and VS.NET compilers. [SW]
  * We try to be more conservative about when we show lines of
    asterisks around motd-type messages, to avoid showing them when
    there's no message.
  * Continued ansi-C-ification of function declarations.
& 1.8.0p13
Version 1.8.0 patchlevel 13                     July 5, 2006

Fixes:
  * Crash bug in pcreate() fixed. Report by Phreq@M*U*S*H.
  * Crash bug in setunion() fixed. Report by Gurenk@ST:Legacy.


& 1.8.0p12
Version 1.8.0 patchlevel 12                     March 25, 2006

Minor changes:
  * New config option keepalive_timeout for setting the socket-level
    are-you-there ping interval used to help work around broken routers. [SW]
  * Changing the SO_KEEPALIVE interval works on more OSes, including OS X. [SW]
  * Passwords are masked when commands that require them are logged
    in command.log. Suggested by Sumta. [SW]
Fixes
  * Added help entry for @debugforwardlist. Suggested by d'Ark@M*U*S*H.
  * Help fixes by Talvo@M*U*S*H.
  * When objects are nuked, their creation time is reset to 0. 
    This prevents garbage objects from maintaining the same objid.
    Suggested by Cooee@PDX
  * When doing english-style matching, plain numbers ('3') were
    treated as adjectives (like '3rd') and shouldn't have been.
    Fixed. Reported by Stinky@M*U*S*H.


& 1.8.0p11
Version 1.8.0 patchlevel 11                     February 25, 2006

Fixes:
  * Help clarification to ancestors inspired by Viceroy@GuiltyPleasures. [TAP]
  * Help clarification in @set by Skaven@M*U*S*H.
  * Freebsd hints files combined and simplified.


& 1.8.0p10
Version 1.8.0 patchlevel 10                     January 29, 2006

Minor changes:
  * Row and field separators in sql() may now by more than one
    character. Patch by Walker@M*U*S*H.
Fixes:
  * Fix to GNU libc detection in Configure by Petr Salinger.
  * Definition of MAILER in options.h.dist made to work by Luke@M*U*S*H.
  * Fix to double-parsing of row and field separators in sql()
    by Walker@M*U*S*H.


& 1.8.0p9
Version 1.8.0 patchlevel 9                      December 12, 2005

Fixes:
  * On amd64 systems running FreeBSD (and possibly others), connections
    could break after about 32 connections. Report by nails@M*U*S*H.
  * The CONF and CONFGROUP structures are renamed PENNCONF and
    PENNCONFGROUP to work around brokenness in Debian's openssl0.9.8
    package.


& 1.8.0p8
Version 1.8.0 patchlevel 8                      September 15, 2005

Fixes:
  * /noflagcopy switch to @cpattr/@mvattr works now. Report by
    Kimiko Muffin.
  * SHS encryption now works on 64-bit architectures that define
    uint32_t. Report by Licenser@M*U*S*H.
  * MySQL detection by Configure was accidentally removed
    in 1.8.0p7/1.8.1p2. It's back. Report by Walker@M*U*S*H.
    Same applies to SO_KEEPIDLE and some other Configure units.


& 1.8.0p7
Version 1.8.0 patchlevel 7                      August 29, 2005

Fixes:
  * lsearch() with no results no longer returns #-1. It still does so when
    there's an error. Suggested by Nathan Baum. [SW]
  * Improved messages for @link of exits. Report by Nathan Baum. [SW]
  * Restart script more portable to older bourne-like shells.
    Patch by Walker@M*U*S*H.
  * Fix to MinGW reboot. Patch by Nathan Baum.
  * Help fixes by Tyr@M*U*S*H, Talvo@M*U*S*H, Dizzy@Forgotten Time,
    and Trinsec@M*U*S*H.
  * @flag/add of a flag with a name that is a unique prefix of an existing 
    flag wouldn't add the new flag. Reported by Mike Griffiths. [SW]
  * @config/set of an invalid option would still return a success message.
    Report by Sholevi@M*U*S*H. [SW]
  * sql() without a field delimiter defaulted to using the row delimiter,
    instead of a space. Report by Kali@M*U*S*H.
  * lock() didn't set user-defined locks properly. Report by 
    Dahan@M*U*S*H. [SW]
  * Infinite loop in fraction() fixed.
  * FIXED players may no longer teleport through exits. Report by
    Anyasha@bDv2
  * Better messages when attempting to wipe SAFE attributes.
    Suggested by Nathan Baum.


& 1.8.0p6
Version 1.8.0 patchlevel 6                      June 24, 2005

Fixes:
  * Weird logging ouput with function logargs fixed. Report by Sholevi@M*U*S*H.
  * sort() and set functions now ignore ansi. Patch by Walker@M*U*S*H.
  * @hook memory leak fixed. Reported by Shari@M*U*S*H.


& 1.8.0p5
Version 1.8.0 patchlevel 5                      May 30, 2005

Minor changes:
  * help substitutions{2,3,4} aliased to help %{2,3,4} respectively
    for convenience. Suggested by Tokeli@M*U*S*H.
  * help for ulocal() clarified. Suggested by Dahan@M*U*S*H.
  * help fixes by Sketch@M*U*S*H.
Fixes:
  * next() on a thing or player behaved improperly. Reported by
    Sketch@M*U*S*H.
  * ancestor_* config options allow dbref specified with #<n> as
    well as just <n>. Suggested by Nathan Baum.
  * New MSVC6 project files. [EEH]
  * NUMVERSION no longer starts with a 0, which made some compilers
    think it might be an octal constant. Suggested by Shane DeRidder.
  * @attribute did not check for validity of attribute names before
    adding them. Report by Dahan@M*U*S*H.
  * #<dbref> <action> forces ignored @hooks. Report by Mike Griffiths.
  * access.cnf checks attempt to check against ipv6-ized versions
    of ip addresses listed in sitelocks as well.
  * Sort of dbrefs in @oemit was broken, which could lead to  
    multiple messages to same target. Report by Cheetah@M*U*S*H. [TAP]
  * Setting a password ending in % is now feasible. Report by Marc 
    DVer [TAP].


& 1.8.0p4
Version 1.8.0 patchlevel 4                      March 20, 2005

Fixes:
  * @list powers crashed the MUSH. Report by Kevin@M*U*S*H.
  * Multiplayer whisper-poses now use the correct conjugation of the
    verb "to sense". Suggested by Cheetah@M*U*S*H.
  * @attribute NAME and @attribute @NAME can both be used to display 
    information about attributes. [SW]


& 1.8.0p3
Version 1.8.0 patchlevel 3                      February 26, 2005

Fixes:
  * 1.8.0p2 fixed ""hi when chat_strip_quote was on, and broke it
    when it was off. Fixed both ways now. Report by Cheetah@M*U*S*H.
  * The @break fix in 1.8.0p2 stopped compound break actions
    in {}'s from working correctly. Fixed now. Report by 
    Kevin@M*U*S*H. [TAP]
  * @list/list() works right with flags/powers now.
  * MS VS.NET project file now includes sql.c/h and bufferq.c/h.
    Report by T'orA@M*U*S*H.
  * playermem() and objectmem() now return #-1 NO MATCH consistently
    when they can't match their argument to an object of an appropriate
    type. Suggested by Cheetah@M*U*S*H.


& 1.8.0p2
Version 1.8.0 patchlevel 2                      February 2, 2005

Fixes:
  * @break/@assert could double-evaluate the right side.
    Patch by Walker@M*U*S*H.
  * ""hi didn't produce the right output. Patch by Walker@M*U*S*H.
  * Better output for @warn me=none and invalid warning lists.
    Suggested by T'orA@M*U*S*H
  * Help fix by Meyer@M*U*S*H.
  * Bug in reading dbs when no chatdb present. Discovered by
    Benigo@M*U*S*H.


& 1.8.0p1
Version 1.8.0 patchlevel 1                      January 16, 2005

Fixes:
  * Win32 portability fixes. NT_TCP builds work again, too. [EEH]
  * pennv180.hlp file added to MANIFEST so it's distributed now.
    Report by Nymeria@M*U*S*H.
  * More translation files included. [EEH]
  * Help fixes by [EEH] and Chili@M*U*S*H.
  * cflags() now shows the N (nonames), T (notitles), and C (nocemit)
    flags for channels. Suggested by Prospero@Metro.
  * If A can't receive from B (due to interactions), then A's
    puppet would send a null line when it heard B. Now the puppet
    doesn't send at all. Fix by Prospero@Metro.
  * Multiple simultaneous flag sets behaved oddly when one of the
    flags affected listener/hearer status. Report by Cheetah@M*U*S*H.
  * NUMVERSION corrected.

& 1.8.0p0
Version 1.8.0 patchlevel 0                      January 1, 2005

Major Changes (since 1.7.6):
  * SQL support (MySQL server).
  * SSL support.
  * Attribute trees.
  * Object ids uniquely identify an object across recycling dbrefs.
  * Anonymous attributes via #lambda.
  * Ancestor objects for each object type.
  * Interactions (something like "realms" in mux2) control conditions
    under which objects can see, hear, match, or establish the presence
    of each other. See local.c.
  * New flag/power internals, no more limits on number of flags, 
    flags can be added/removed at runtime.
  * New game/chat db formats, more readable, extensible, and 
    better at detecting problems.
  * New framework for performing lock failure activities in hardcode.
  * Customized mush.cnf configuration parameters can be easily added.
  * New chunk memory allocator does our own paging to disk,
    so the resident memory footprint is much lower.
  * Lock system rewrite. #true and #false atoms for locks.
  * minimal.db is no more. If you start up the server and there's no
    db to be found, it creates a new minimal database in memory.
  * New commands: @command/alias, buy, @boot/silent, @assert, huh_command,
    @decomp/prefix, @edit/first, ex/parent, empty, @nscemit, @function, 
    @nsemit, @nsoemit, @nslemit, @nsremit, @nszemit, ], @command/add,
    @command/del, warn_on_missing, @switch/regexp, @*emit/spoof,
    @tel/inside, @hook/ignore, @hook/override, @chan/recall, with/room,
    IDLE, @sitelock/check, SCREENWIDTH, SCREENHEIGHT, ex/all
  * New functions: zwho, zmwho, l/lv/n/nv/x/xvthings, malias, locks, llocks,
    lset, lockflags, llockflags, lattrp, nattr/p, xattr/p, mailsend,
    x/xv/n/nv/exits/players/things, nsemit/cemit/remit/lemit/oemit/zemit,
    andlflags, andlpowers, orlflags, orlpower, andpowers, orpowers,
    align, sent, recv, scan, valid, allof, firstof, tr, vcross, hostname,
    ipaddr, cmds, reswitch*, digest, cowner, baseconv, randword,
    trimtiny, trimpenn, terminfo, lports, strreplace, fraction, root,
    children, accname, lpos, width, height
  * New behaviors: @adisconnect, No_Pay, @name, @lock/speech, examine,
    @cemit, give, @cost, SUSPECT, @startup, escape(), time(), merge(),
    @set, move, @name, etimefmt(), insert(), PUPPET, help, rand, DEBUG,
    TERSE, powers(), @config/set, @function/restrict, %~, @lock/leave,
    tel(), @descformat, @idescformat, @aconnect
  * @lock/interact can prevent other players from transmitting any
    normal sound to you (that is, you won't hear them speak, pose, 
    emit, etc., like gagging them in a client). 
  * New flags: HEAVY, ORPHAN, MISTRUST
  * New powers: Debit, Can_NSPemit
  * New attribute flags: NO_NAME, NO_SPACE, DEBUG, NEARBY, PUBLIC, VEILED
  * New channel flags: Notitles, Nonames, Nocemit
  * You can log setting/resetting of flags/powers, as well as individual
    commands or function calls.
  * Rolling activity log dumped on panic dumps or visible with @uptime.
  * A new test harness for developing regression test suites in perl
    for PennMUSH is now included; few test suites are. If you can figure
    out how to use this, write some tests for us!
  * More and better telnet negotiation.
  * Many internal improvements. Many old compile-time options removed
    or replaced by run-time options. Source code commenting using
    doxygen. Improved internationalization.
  * New config directives: unconnected_idle_timeout, max_guests,
    max_global_fns, read_remote_desc, default_home
Minor Changes (since last 1.7.7):
  * The LFAIL/OLFAIL/ALFAIL messages are activated whenever a @lock/leave
    is checked and failed, not just when a 'leave' command fails.
    (So they work for failed attempts to leave rooms by exits/@tel).
    Suggested by Zith@Lovarii.
Fixes (since last 1.7.7):
  * Help for grab() now references graball(). Report by Sketch@M*U*S*H.
  * Reference to 'ducats' in code replaced by appropriate plural
    currency unit. Report by Kinumi@ShoujoAi.
& 1.8.1p10
Version 1.8.1 patchlevel 10                     September 13, 2006
Fixes:
  * Cleaned up some compiler warnings. [SW]
  * The AAHEAR and AMHEAR attribute flags work on listening parents. 
    Report by PAD@M*U*S*H. [GM]
  * Flags without a letter would truncate the list of set flag letters.
    Reported by Intrevis@M*U*S*H and Nathan Baum. Patched by latter.
  * Win32 lacks the LC_MESSAGES setlocale() category. Reported by Intrevis.
  * Trying to ignore signals could crash on Win32. Reported by Intrevis.
  * Fixed parse errors in non-C99 compilers. Reported by Intrevis.
  * Help fixes by Talvo, Sketch
  * Fixes for 64-bit platforms [SW]
  * @dump/paranoid produced corrupt databases. 
    Reported by Marvin@M*U*S*H. [SW]
  * Better support for dealing with databases with a different number of 
    attributes on an object than expected. Marvin and Luke. [SW]
  * Fixed the example in cmdlocal.c. Reported by Tokeli [SW]
  * Fix in CHAT_TOKEN_ALIAS. [GM]

Functions:
  * link() now takes an optional third argument to make it act like
    @link/preserve. Suggested by qatoq@ST:Foundations.

Minor Changes:
  * The hash table code now calls a cleanup function on data when deleting
    an entry. [SW]
  * The above is used in db.c, function.c and plyrlist.c [SW]
  * @config compile reports if MySQL support is present. (This does not 
    mean the game is configured to use it.) [SW]
  * restart copies log files from the last time the mush was running to
    game/save/ instead of deleting them. [SW]


& 1.8.1p9
Version 1.8.1 patchlevel 9                      July 9, 2006

Fixes:
  * Fixes from 1.8.0p13.


& 1.8.1p8
Version 1.8.1 patchlevel 8                      June 3, 2006

Attributes:
  * New 'AAHEAR' and 'AMHEAR' attribute flags, when set on an
    ^listen attribute, cause it to behave like @aahear or
    @amhear respectively, instead of like @ahear. Suggested by
    Jules@M*U*S*H. Patch by Talvo@M*U*S*H.
  * New UNIMPLEMENTED_COMMAND command handles commands that
    are known but not implemented (currently just @SQL). By default,
    produces a standard message, but can now be @hooked, etc.
    Suggested by Talvo@M*U*S*H. [TAP].
  * @conformat and @invformat are now passed a |-delimited list
    of object names, unparsed in the default fashion, as %1. Patch
    by Talvo@M*U*S*H.
Functions:
  * default() can now take any number of obj/attr cases. Suggested
    by Nathan Baum, patch by Talvo@M*U*S*H.
  * lwhoid(), mwhoid(), xwhoid(), xmwhoid() work like lwho(), etc.
    but return objids instead of dbrefs. Patch by Talvo@M*U*S*H.
  * stringsecs() converts timestrings to seconds. Patch by Talvo@M*U*S*H.
Minor changes:
  * %u is now set to the evaluated typed $command (when a $command
    is matched) and is available to locks. Suggested
    by Jules@M*U*S*H, patch by Talvo@M*U*S*H.
  * Rooms reachable from FLOATING rooms are now considered topologically
    connected, just like rooms reachable from the base room.
    Patch by Nathan Baum.
  * %i0-%i9 evaluates to itext(0)-itext(9) for convenience in iter(). 
    Suggested by Nathan Baum. Patch by Talvo@M*U*S*H.
  * When safer_ufun is on, you must control an object to @function
    an attribute on it. This prevents, e.g., mortals with @function power
    from making attributes on wizard objects into @functions. 
    Suggested by Talvo@M*U*S*H.
  * Internal eval_lock_with function added to support passing special
    %0/%1 values to lock evaluations. Suggested by Malix@8bit.
  * Improved @uptime display by Ambrosia@M*U*S*H.
  * Players may @search a ZMP if they pass the zone lock. Patch by
    Talvo@M*U*S*H.
Fixes:
  * cbuffer() crash fixed. Report by qa'toq@ST:Foundations. [GM]
  * regex crash bug fixed. [GM]
  * insert() added an extra delimiter when inserting at end of list.
    Report by Sangman. [SW]
  * make distclean is more thorough. Patch by Ranmir@M*U*S*H.
  * EQSPLIT commands with no equal sign that were hooked were passed to the 
    hook attribute with an equal sign (and nothing to the right).
    Fixed. Suggested by Talvo@M*U*S*H.
  * zwho/zmwho can now be used by see_all players on any zone.
    Suggested by Talvo@M*U*S*H.
  * crecall() now accepts 1 or 2 arguments, as promised. Report by
    Sketch@M*U*S*H.
  * attrib_set(obj/attr,) sets the attribute to a single space
    when EMPTY_ATTRS is off. Patch by Talvo@M*U*S*H.
  * Portability fix in fun_speak. [EEH]
  * Fix to TZ parsing in src/funtime.c by Jules@M*U*S*H.
  * Fix to speak() for fragments of speech by Talvo@M*U*S*H based on
    report by Trelane@M*U*S*H.
  * Typo fixes in game/aliascnf.dst by Talvo@M*U*S*H.
  * Help fixes by Talvo@M*U*S*H, Sketch@M*U*S*H.


& 1.8.1p7
Version 1.8.1 patchlevel 7                      March 21, 2006

Major changes: ** PLEASE READ **
  * The FIXED flag's restriction on 'home' is no longer applied in
    the hardcode but through restrict.cnf. A new entry has been
    added to restrictcnf.dst for this -- people running existing
    MUSHes that use the FIXED flag will want to copy this to their
    restrict.cnf.
Locks:
  * @lock/take controls who may 'get' something from a container 
    or location; note that @lock/enter no longer controls this on
    containers but only controls who may 'enter'. The container's
    TAKE_LOCK`*FAILURE attributes provide messages on a failed get.
    Suggested by BladedThoth@M*U*S*H. Patch by Talvo@M*U*S*H.
Commands:
  * @chan/recall can take an extra argument to specify the line to
    start the recall from. Suggested by Sholevi@M*U*S*H. Patch by 
    Talvo@M*U*S*H.
Functions:
  * ulambda() is a version of u() that can take #lambdas. [GM]
  * speak() for language processing. Suggested by Nymeria@M*U*S*H.
    Patch by Talvo@M*U*S*H. [3]
  * width() and height() take an optional second argument to set the
    default values. Patch by Nathan Baum.
  * unique() function removes contiguous duplicates in lists. [SW]
  * nextdbref() returns the next dbref on the free list. 
    Suggested by Jules@M*U*S*H. Patch by Talvo@M*U*S*H.
  * Specifying more than one type to locate() now makes each of them
    preferred (not just the last one). Suggested by Anyasha@ST:Foundations.
  * namelist() parses a list of dbrefs and possibly-quoted names a la page
    and returns the corresponding dbrefs. Patch by Talvo@M*U*S*H.
  * crecall() is a functional form of @chan/recall. Suggestd by
    Cheetah and Trinsec@M*U*S*H. Patch by Talvo@M*U*S*H.
Flags:
  * The LIGHT flag now overrides the DARK flag consistently. DARK
    objects will show up in LIGHT rooms and anything set both
    LIGHT and DARK is effectively LIGHT. Suggested by Renee@ShoreSide.
    Patch by Talvo@M*U*S*H.
Minor changes:
  * @poll by itself now displays the  current poll instead of clearing it.
    @poll/clear does that. [SW]
  * Added aliases for @atrlock/@atrchown/atrlock to 'attr' versions
    in aliascnf.dst. Suggested by Talvo@M*U*S*H.
  * Players who already have a forbidden name (as their name or alias)
    may change to that name. Patch by Talvo@M*U*S*H.
  * New alias_flag() and alias_power() hardcode functions for hackers.
    Patch by Talvo@M*U*S*H.
  * Mortals can use @power/list and @power <power> commands.
    Patch by Talvo@M*U*S*H.
  * Restriction-checking by power fixed in cases where no flag
    restrictions were applied. Patch by Talvo@M*U*S*H.
  * New type GARBAGE for @search/lsearch type class.
  * @pemit/list now accepts player names as well as dbrefs, a la page.
    Patch by Talvo@M*U*S*H.
Fixes:
  * pcre.c includes config.h again. [EEH].
  * Help fixes by Talvo@M*U*S*H.
  * Fixes from 1.8.0p12


& 1.8.1p6
Version 1.8.1 patchlevel 6                      February 25, 2006

Major Changes:
  * pcre updated to 6.4. This includes such nifty features and
    named captures. [SW]
  * NT_TCP code has been removed from the server. It was deemed
    less useful than keeping the networking code unitary and
    the ability to @shutdown/reboot. Patch by Nathan Baum.
Flags:
  * New LOUD flag (admin-settable) causes an object to bypass
    speech (including chat) and interaction locks. Admin and others
    with Pemit_All no longer pass interaction locks automatically
    unless they are also LOUD. Patch by Cheetah@M*U*S*H.
Locks:
  * New DBREFLIST^<attrib> lock key checks to see if the enactor
    appears in a list of dbrefs/objids stored on an attribute of
    the object, simplifying a very common need. Suggested by
    NightDaemon@M*U*S*H, patch by Cheetah@M*U*S*H.
Powers:
  * Many_Attribs power allows an object to have more attributes
    than the max_attrs_per_obj parameter. Suggested by Nymeria@M*U*S*H.
Functions:
  * decompose() now decomposes ansi codes into ansi() calls.
    Patch by Sketch@M*U*S*H.
  * mapsql() efficiently feeds sql query results to an attribute. [GM]
  * wildgrep()/wildgrepi() are versions of grep()/grepi() that now take 
    wildcard patterns instead of substrings. [SW]
  * regmatch()/regedit() now has a more flexible syntax for assigning
    subpatterns to %q-registers. [SW]
  * decompose() no longer inserts an initial backslash all the time.
    Suggested by Trinsec@M*U*S*H.
  * ordinal() returns the spelled-out ordinal form of an integer.
    Suggested by Malone@HavenMUSH.
Minor Changes:
  * Font size tags (for pueblo) are not quite so huge for room names.
  * The /noeval switch for @command is now called /noparse.
    Patch by Nathan Baum.
  * hints/cygwin.sh has been removed, as no hints were needed to
    build on cygwin when tested with 1.5.19-4. win32/README.cygwin
    has been added to document the cygwin build process.
  * Added hints/darwin-fink.sh and README.OSX. [SW]
Fixes:
  * Track_Money objects with No_Pay still reported coins lost to
    queue costs, even though they didn't pay them. Report by
    Cheetah@M*U*S*H. [GM]
  * Help fixes by Trinsec@M*U*S*H, Cheetah@M*U*S*H.
  * Various %c weirdnesses fixed by Cheetah@M*U*S*H.
  * Better message in restart when mush.cnf not found by Talvo@M*U*S*H.
  * @alias provides more specific error messages for invalid aliases
    of various sorts. Suggested by Intrevis@M*U*S*H.
  * Function restriction localize now appears in @function info output.
    Better error messages when attempting to use invalid function
    restrictions.  Reported by Trinsec@M*U*S*H.
  * Linting of warnings. [SW]
  * Command and function names may now really start with punctuation 
    characters.  Reported by Talvo@M*U*S*H.
  * Fixes from 1.8.0p11.


& 1.8.1p5
Version 1.8.1 patchlevel 5                      January 29, 2006

Major Changes:
  * @attrib/access no longer treats one-word flag lists that don't
    match a single flag as a set of flag characters. You must now always
    specify a space-separated list of full flag names.
Commands:
  * @list/locks and list(locks) lists all defined locktypes.
    Suggested by Jules@M*U*S*H, patch by Walker@M*U*S*H.
  * New @search classes 'start' (nth element of return list to start
    with) and 'count' (how many elements to show, from <start>).
    Useful for getting results a page at a time. Patch by Walker@M*U*S*H.
Functions:
  * nsearch()/nlsearch()/nchildren() return the number of objects that
    would be returned by the equivalent search/lsearch/children call.
    Patch by Walker@M*U*S*H.
Minor Changes:
  * delete() can use a negative length argument to delete characters
    leftward, a la MUX. [MUX, SW].
  * In @mail commands, <n>: is now recognized as meaning 'all messages
    in folder n'. Notably, @mail 3: now lists all messages in folder 3,
    rather than reading all messages in folder 3. Patch by Sketch@M*U*S*H.
  * When one alias in a list of aliases being set is invalid, we
    now report it with specificity. Suggested by Talvo@M*U*S*H.
  * You no longer need to escape commas in decompose(). Suggested by
    Trinsec@M*U*S*H.
  * @sitelock rules for Guest access can now be specified per-guest
    character. Suggested by Talvo@M*U*S*H.
  * process_expression now parses for regex pattern captures by default,
    so lots of things will work better under regedit(). Use of a ufun
    clears the captured registers so dollar signs in ufuns don't
    need escaping. Patch by Walker@M*U*S*H.
  * Refactoring of ufun code by Walker@M*U*S*H.
Fixes:
  * Help fixes by Trinsec@M*U*S*H and Talvo@M*U*S*H and qa'toq@M*U*S*H.
  * Crash bug in page fixed. Reported by the fine folks at ST:Foundation.
    Patch by Walker@M*U*S*H.
  * Win32 portability fixes. [EEH]
  * Fixes from 1.8.0p10.


& 1.8.1p4
Version 1.8.1 patchlevel 4                      December 6, 2005

Major Changes:
  * Errors in matching switches to commands are ignored when the
    command is hook/ignored or hook/overriden, so you can override
    a built-in command and provide your own switches. Suggested by
    Trinsec@M*U*S*H.
Mail:
  * @mailfilter attribute causes incoming mail to be be automatically
    filed to a folder if it evaluates to a folder name/number.
    Patch by Sketch@M*U*S*H.
Commands:
  * @prompt/@nsprompt work like @pemit/list, but add a telnet GOAHEAD
    at the end of the message when emitting to players; players whose
    clients handle GOAHEAD (e.g. tf) will get the message displayed
    as a prompt in the input window. Suggested by Trinsec@M*U*S*H.
  * The PROMPT_NEWLINES socket command can be used to add a newline
    after the GOAHEAD in a prompt, for clients that mix up prompt
    lines with other output.
Functions:
  * namegrab() and namegraball(). Patch by Walker@M*U*S*H.
  * prompt() and nsprompt() (the function equivalents of @prompt/@nsprompt).
  * textentries(). Suggested by Trinsec@M*U*S*H.
  * cdesc(), cusers(), cmsgs(), cbuffer(), cstatus(), clflags() 
    functions. Suggested by d'Ark@M*U*S*H.
  * numversion() returns Penn version as an integer (1008001004) 
    for softcode use.
Minor changes:
  * @chan/list works better for people who increase CHAN_NAME_LEN.
    Suggested by Trinsec@M*U*S*H.
  * Help fixes by Trinsec@M*U*S*H, Chili@M*U*S*H.
  * Several powers (tport_anything, tport_anywhere, no_money, no_quota,
    debit, sql_ok) are now aliased to TinyMUSH/TinyMUX equivalents
    as well, for better code portability. [3,MUX]
Fixes:
  * center() behaves better when given a fourth argument but
    not a third one. Also fixes to cases where the right fill
    string is one longer than the left. Report by Ian@M*U*S*H
  * Fixes from 1.8.0p9.


& 1.8.1p3
Version 1.8.1 patchlevel 3                      September 15, 2005

Fixes
  * Bugfixes from 1.8.0p8 applied.


& 1.8.1p2
Version 1.8.1 patchlevel 2                      September 5, 2005

Commands:
  * @edit/check shows the results of an @edit without actually doing
    it, to avoid inadvertent overediting. Patch by Walker@M*U*S*H.
Functions:
  * sortkey() sorts a list by mapping each list element through a
    function and applying a standard sort type. Patch by Walker@M*U*S*H.
Minor changes:
  * "% " (percent-space) is now parsed to a literal percent-space,
    making it easier to type things like "I'm 50% happy". And
    % at end of line is parsed to a literal %.  Patch by Sketch@M*U*S*H.
  * @nameformat now receives the default-formatted name as %1
    so you can edit from that if you prefer. Suggested by Talvo@M*U*S*H.
  * Added netbsd hints. Suggested by Tyr@M*U*S*H.
  * hastype() can take a list of types to check for, not just one. [SW]
  * Add @function/preserve, which does the same thing as the localize
    restriction. [MUX] [SW]
  * Leaving out the <filler> argument to align() defaults it to a
    space. Suggested by Tyr@M*U*S*H, patch by Walker@M*U*S*H.
  * Improved error message for setq() with odd arguments.
    Report by Malix@8bit.
  * When variable exits fail due to invalid/not permitted destination,
    the enactor is told what the attempted destination was.
    Suggested by Nathan Baum.
  * Rooms may now @search/search() their owners. Suggested by Kali@M*U*S*H.
Fixes:
  * @function/restrict mentioned in help. [SW]
  * Clearer help on parallel setq. Suggested by Trinsec@M*U*S*H. [TAP]
  * lsearch() didn't refund pennies when it failed because of lack of 
    permissions or invalid search criteria. Reported by Nathan Baum. [SW]
  * lsearch() could return garbage objects. Report by Nathan Baum. [SW]
  * %+ now only records argument count from last ufun, not from other
    (builtin) functions. Report by Cheetah@M*U*S*H.
  * Some linting of float comparisons. Report by Cheetah@M*U*S*H.
  * page <player>= now pages the player with a blank line instead of
    repaging the last paged player with "<player>". Report by Cheetah@M*U*S*H.


& 1.8.1p1
Version 1.8.1 patchlevel 1                      June 27, 2005

Fixes:
  * Players could set the 'internal' attribute flag, which causes
    confusion. Report by Cooee@PDX.
  * Setting attribute flags by character alias did not work 
    properly.


& 1.8.1p0
Version 1.8.1 patchlevel 0                      June 25, 2005

Major Changes:
  * Players may have multiple aliases, by specifying a semicolon-separated
    list to @alias. Players may list their usual @name as one of their
    aliases, and the @name command may be used to switch to any alias.
    The maximum number of aliases per non-Wizard player may be limited by the 
    max_aliases config directive. Suggested by Nymeria@M*U*S*H. [3]
  * 'home' is now a standard command, with no special precedence.
    It can be @command/disabled and/or @hook'd. Suggested by
    several people. If 'home' is disabled, 'goto home' will no longer
    work (but @tel to home is still allowed).
Flags:
  * A player with the TRACK_MONEY flag set gets a message any time
    their objects spend or lose money. Patch by Walker@M*U*S*H.
  * New Pueblo_Send power allows use of xch_cmd and send tags.
Mail:
  * The @MAILFORWARDLIST attribute can be set to a list of dbrefs or
    objids to which any @mail received should be forwarded. Your own
    dbref may be listed if you wish to retain a copy
    of the message as well. You must pass the @lock/mailforward of
    any player listed in your @MAILFORWARDLIST. Suggested by T'orA@M*U*S*H.
Functions:
  * setq()/setr() can set multiple registers in parallel. Suggested by
    Nathan Baum. [SW]
  * center() can now take multi-character fills, and can have different
    left and right fills. Suggested by Boris@M*U*S*H.
  * attrib_set() is a version of set() for setting attributes that
    has a more comfortable syntax and that can clear attributes
    without wiping whole attribute trees like wipe(). Suggested by
    Kevin@M*U*S*H. [TAP]
  * extract()'s second and third arguments are now optional, and default
    to 1. Suggested by Philip Mak.
  * lsearch() can now take more than one class/restriction pair, and
    will require them all to be met. New "mindb" and "maxdb" classes
    specify low and high dbrefs, and replace the old <low>,<high>
    parameters, which are now deprecated. Suggested by qa'toq@bDv.
  * alias() and fullalias() functions. [EEH]
  * New function restriction "localize" causes q-registers to be
    saved and restored around the function as if localize() or
    ulocal() were used; handy for @functions. Patch by grapenut.
  * flip() and reverse() no longer require escaping of commas.
    Suggested by Yar Kramer.
Channels:
  * Channels, by default, now ignore interaction rules defined in
    local.c, so they can be used as "OOC" communication between
    players who wouldn't be able to interact "IC"ly. A new per-channel
    permission, "interact", changes this behavior back to enforcing
    interaction rules on the channel. @lock/interact always applies,
    however. Suggested by Shamash.
  * New channel_flags config directive sets default permissions
    for newly-created channels.
Minor changes:
  * The %+ substitution returns the number of arguments passed to
    a function and is useful in ufuns and @functions.
    Suggested by Nathan Baum.
  * The rules for valid command and functions names (e.g. for @command/add)
    have been relaxed to allow @foo, +blah, and others with punctuation.
    Suggested by Mike Griffiths.
  * @hook/list <command> lists hooks on a command. Suggested by Nathan Baum.
  * @INVFORMAT works like @CONFORMAT for the inventory command.
  * Help for mail and chat functions moves to pennmail.hlp and
    pennchat.hlp, respectively. Suggested by Kevin@M*U*S*H.
  * Settings and resetting multiple attribute flags at once is now
    supported more flexibly. Suggested by Sholevi@M*U*S*H.
  * The restart script handles mush.cnf files with Windows-style 
    line endings more gracefully. Reported by CBeilby@M*U*S*H.
  * @attribute/access now understands the privilege 'none' to mean
    'no associated attribute flags'. Report by Tyson Cochrane.
  * @flag/alias flag=!alias removes a flag alias. Suggested by
    Relay@MatrixMUSH.
  * @search now refers to things as things instead of objects.
    Suggested by Zebranky@M*U*S*H.
  * Suggested restrictions to disable hardcoded chat and mail
    are in restrictcnf.dst for those who want to do that. 
    Patch by Kevin@M*U*S*H.
  * TZ attribute is now visual by default, since time() gets it anyway.
    Suggested by Mike Griffiths.
Fixes:
  * Fixes include from versions up to 1.8.0p6.
& 1.8.2p8
Version 1.8.2 patchlevel 8                     Jan 01, 2008

Minor changes:
 * 'make versions' now provides some feedback.

Fixes:
 * width() and height() do not return 0 when set to invalid input.
   By Talvo.
 * Array underflow bug found by running under Valgrind.
 * Crash bug when too many objects are nested. Reported by Paige, fixed
   by Javelin and Intervis.

& 1.8.2p7
Version 1.8.2 patchlevel 7                     October 6, 2007

Minor changes:
  * nwho() now takes an optional viewer argument like lwho(). By Sketch.

Fixes:
  * Clarified the behavior of eval() and get_eval() in help. Suggested by
    Talvo and Javelin.
  * A failed db save no longer broadcasts a success message in addition to a
    failure one. Reported by Cooee.
  * The open database file wasn't getting closed on a failed save.
  * Crash bug in sortkey(). Fix by Nathan Baum.
  * Crash bug in pathological container cases reported by Paige@M*U*S*H
    fixed by Javelin.
  * 'help @desc' brings up @describe instead of @descformat.
    Suggested by Nymeria.
  * Removed mention of Win32 requiring a particular attribute
    compression algorithm. Any will work, and always have.
    Reported by Andrew Klein.
  * Crash bug in @purge. Javelin.  

& 1.8.2p6
Version 1.8.2 patchlevel 6                       July 9, 2007

Development team changes:
  * After many years of valuable work, Talek has retired from
    development.  

Minor changes:
  * Removed the gmalloc malloc option. [SW]
  * KEEPALIVE flag makes the server send a telnet NOP after
    a short period of inactivity; helps prevent timeouts from
    NAT/router devices with a short timeout. [MUX]

Fixes:
  * Fixed assorted small memory leaks. [SW]
  * Fix to fraction() when dealing with numbers that can't
    be fractioned. Discovered by Ashen-Shugar. [GM]
  * Fixed handling of telnet NOPs sent by clients. [SW]
  * The OpenSSL random number pool wasn't getting adequately
    initialized on systems without /dev/urandom [SW]
  * Infinite loop in math code. Reported by Ashen-Sugar. [GM]
  * mkvershlp.pl skips over emacs backup files.

& 1.8.2p5
Version 1.8.2 patchlevel 5                      June 13, 2007

Minor changes:
  * Assorted gcc warning fixes. [SW]

Fixes:
  * Cleaned up some unsafe signal handler functions. [SW]

Help files:
  * Mention examine lock in help lattr(). Talvo.

& 1.8.2p4
Version 1.8.2 patchlevel 4                      May 16, 2007

Minor changes:
  * speak() uses accented names. Sketch.
  * config() no longer lists options that can't be set
    with @config/set. Suggested by Trispis. [SW]
  * 'page foo\=bar' pages the last person you paged. Fix by Nathan
    Baum.
  * Receipt of a SIGUSR1 (Causing a shutdown/reboot) is explictly
    logged. Suggested by Interloper. [SW]
  * @wipe reports the number of attributes deleted. [183]

Fixes:
  * You can no longer save objects slated to be destroyed
    by using @set foo=!GOING (The help file for GOING now tells
    the truth) Reported by Cooee. [SW] 
  * Useless variable in real_unparse() removed. Reported by
    Taladan. [SW]
  * 'make portmsg' works, and portmsg.c rewritten to current
    Penn standards. [SW]
  * case() would replace #$ in the default argument, contrary
    to the help file. Reported by Talvo. [SW]
  * Memory leak in grep(). [SW]
  * Quotes can be around the player name on the login screen
    always, instead of just when player_name_spaces was
    on. Suggested by Dan Widdis. [SW]
  * '{think foo} bar' exhibited odd behavior. [GM]
  * 'make test' wouldn't work right unless '.' was in you path.
     Fix by Nathan Baum.
  * stdin and stdout weren't getting closed, potentially causing
    problems when trying to log out of a shell after starting
    a mush. Reported by K Moon. [SW]
  * NetBSD compile and general warning fixes. [SW]
  * Favor difftime(3) over subtraction of time_t variables. [SW]
  * Clarification of attribute trees in HELP @WIPE. Suggested by
    Talvo.
  * Loading a db with empty attributes used as the roots of
    attribute trees didn't work if empty_attrs is set to no.
    Reported by Kevin. [SW]
  * Bugs in wiping attribute trees with attributes the wiper
    doesn't have permission to delete fixed. [SW]
 
& 1.8.2p3
Version 1.8.2 patchlevel 3                      March 11, 2007

Fixes:
  * Unterminated buffer in sortkey() fixed. Reported by Balerion.
    Patch by Javelin.
  * Memory leaks in setunion() and revwords() fixed by Javelin.
  * Crash bug in speak() fixed. Reported by Trinsec. Patch by Javelin.
  * Crash bug in buy fixed. Reported by Amy. Patch by Javelin.
  * If we should fail to clear a semaphore attribute for some
    reason (e.g., it's the branch of an attribute tree), reset
    the semaphore count on the attribute to 0. Patch by Javelin.
  * iter() dealt badly with freeing buffers when CPU_LIMIT or
    function_invocation_limit was hit. Found by Ashen-Shugar. [GM]
  * @ps/all displayed the wrong  queue entry count for mortals.
    Reported by Cheetah. [SW]
  * @hook/override of say would get an extra leading " if that was
    used instead of the literal say command. Reported by Tuxedo Ian.
    [SW]
  * Fixed a bug where speech seemed to come from the wrong 
    object for nospoof information. Reported by Jules. [SW]
  * The help entry for @poll failed to mention @poll/clear.
    Reported by Cooee. [SW]

& 1.8.2p2
Version 1.8.2 patchlevel 2                      January 27, 2007

Fixes:
  * Vector functions with an empty vector didn't return anything.
    Reported by Talvo. [SW]
  * Several typos in server messages. Fixed by Sketch, Stoko.
  * Help fixes by Malix, [GM], Talvo, Sketch, and others.
  * Crash bug in lmath() fixed. [GM]
  * Crash bug in list functions fixed. [GM]
  * list2arr in C now removes markup. list2arr_ansi() was added. [GM]
  * Compilation problems on IRIX and similar OSes. [SW]
  * Matcher bug with multiple wildcards fixed. Reported by Ian. [SW]
  * Garbled output of locks from examine. Reported by Intrevis. [SW].
  * regraballi() couldn't use its output seperator argument. Reported
    by Jules. [SW]
  * Looking at an object used the looker, not the lookee, as the origin
    of the name for @ahear/@aahear/@amhear. [SW]
  * Fixed the distribution of random numbers with a huge range. Reported
    by Luke. 

& 1.8.2p1
Version 1.8.2 patchlevel 1                      November 26, 2006

Fixes:
  * Corrected inadvertent breakage of null comparisons. Patched by
    Javelin.
  * Added overview since 1.8.0 to help 1.8.2p0. [EEH]


& 1.8.2p0
Version 1.8.2 patchlevel 0                      November 26, 2006

Major Changes (since 1.8.0):
  * Players may have multiple aliases.
  * 'home' is now a standard command.
  * Errors in matching switches to commands are ignored when the command
    is hook/ignored or hook/overriden.
  * @attrib/access no longer treats one-word flag lists that don't match
    a single flag as a set of flag characters.
  * pcre updated to 6.4.
  * NT_TCP code has been removed from the server.
  * The FIXED flag's restriction on 'home' has been moved to restrict.cnf.
  * New commands: @edit/check, @function/preserve, @hook/list, @prompt,
    @nsprompt, @list/locks, UNIMPLEMENTED_COMMAND, PROMPT_NEWLINES,
    @poll/clear.
  * New functions: alias, fullalias, attrib_set, sortkey, namegrab/all,
    ns/prompt, textentries, cdesc, cusers, cmsgs, cbuffer, cstatus,
    clflags, numversion, nl/nsearch, nchildren, decompose, mapsql,
    wildgrep/i, ordinal, ulambda, speak, unique, nextdbref, namelist,
    crecall, l/m/x/xmwhoid, stringsecs
  * New attributes: invformat, mailforwardlist, mailfilter
  * New substitutions: %+, %  (percent-space), %i0-%i9, %u
  * New locks: mailforward, take
  * New behaviors: @flag/alias, @attribute/access, flip(), reverse(),
    lsearch(), extract(), center(), setq(), setr(), page, align(),
    regedit(), delete(), @search, @pemit/list, @poll, width(), height(),
    locate(), @chan/recall, insert(), default(), @conformat, link().
  * New flags: loud, track_money.
  * New powers: pueblo_send, many_attribs.
  * New attribute flags: aahear, amhear.
  * New config directives: channel_flags.
  * New function restriction "localize" causes q-registers to be
    saved and restored around the function as if localize() or
    ulocal() were used; handy for @functions.
  * New DBREFLIST^<attrib> lock key checks to see if the enactor
    appears in a list of dbrefs/objids stored on an attribute of
    the object.
  * The LIGHT flag now overrides the DARK flag consistently.

Minor Changes (since 1.8.1):
 * decompose() now properly handles all manner of spaces, as well as
   replacing 5 or more spaces with [space(<count>)]. Report by Malix. [GM]

Fixes (since 1.8.1):
 * Fix crash bug in decompose(). Report by Malix.
 * The mush can listen to ports above 32000. Suggested by Nathan Baum.
 * Fix the mix() bug that prepends the separator to the list. [GM]
 * Win32 experienced erratic time behavior when compiled with MSVC++ 8
   or higher. Reported by Intrevis@M*U*S*H.
 * Win32 project and readme files for MSVC++ 6 and .Net updated. [EEH]
 * Help fixes by Kevin@M*U*S*H.
& 1.8.3p13
Version 1.8.3 patchlevel 13                     Feb 13, 2010

Minor Changes:
 * align() columns can now have ansi color definitions. [GM]
 
Fixes:
 * Heisencrashbug in command parser fixed. Reported by Mercutio. [GM]
 * Bug in randword() and extract() fixed. [MG]
 * Fix several memory leaks. [SW]
 * Help fixes by aumiiari and others. [MG]
 * Add more specific log messages when the chatdb fails to load, from
   report by Dan@M*U*S*H. [MG]

& 1.8.3p12
Version 1.8.3 patchlevel 12                     Feb 07, 2010

Major Changes:
 * 'mud_url' @config. If this is enabled, accessing the mush with an HTTP
   browser will redirect the user to the selected mud_url. (This may need
   some work and testing by a public place with many clients.) [GM]
 * The internal code for object matching has been rewritten, hopefully
   fixing a few bugs and improving match results in some cases. [MG]

Minor Changes:
 * align() can now do full justification. Suggested by Trinsec@M*U*S*H [GM]
 * Wrapping fixes in align(). Reported by Trinsec@M*U*S*H [GM]
 * Guests will no longer see "Guests can't do that" if @mail is restricted
   to noguest. [GM]
 * Helpfile cleanup. [MG]
 * Expand the @lock key optimizer. Try '@lock me=!!=me'.
 * When objects are destroyed, references to them in locks
   are replaced by #FALSE, so that a newly created object reusing
   some dbref won't pass locks it shouldn't.
 * /'s can now be included in the subject of a @mail 
   message via doubling it up -- @mail foo=a//s//l/What's up? 
   Suggested by Paige.
 * locate() now ignores spaces in its 3rd argument. [MG]
 * Change the default mud_name in mush.cnf from TinyMUSH
   to PennMUSH. Suggested by many people over the years.
 * @firstexit can now take multiple exits, and can affect exits in other
   rooms. Suggested by AnneLions. [MG]
 * Changed some default mush.cnf options. [MG]
 * Remove the old patches.h way of showing installed patches. It was 
   broken and rarely used anyways.
 * Removed the little-used "page_cost" @config option. [MG]
 * Removed costs for @find, @zemit, @entrances and @mail/stats. [MG]
 * @hide can now affect a single descriptor, rather than all of a player's
   connections. A player is only considered hidden if all his connections
   are hidden. Wizards can also @hide other players. [MG]
 * Wizards no longer automatically @hide when set DARK (but are hidden when
   connecting dark with "cd"). [MG]
 * sql() now takes a fourth argument, to return the number of affected rows.
   Suggested by Mercutio.
 * baseconv() fixes for malformed input, "-" ambiguity in base 63/64, and
   missing "-" sign for single-digit output.
 * Flag names now have similar restrictions to attribute names. [MG]
 * The @ns*emit commands and ns*emit() functions are no longer restricted;
   when used by mortals, they work exactly the same as the non-ns versions.
   Suggested by Michael Blackburn. [MG]
 * Update autoconf to 2.65.
 * @grep/print now shows a : before the attribute contents, the same as
   examine. Suggested by Cheetah. [MG]
   
Commands:
 * Removed the /functions, /attribs, /commands and /flags switches from
   @config. Use @list/<switch> instead. [MG]
 * @decompile changes: added /name, the opposite of /db. You can now give a
   '=<prefix>' without needing the /prefix switch, and can use other
   switches with /tf, like @decomp/tf/flags <obj>. Suggestedby Trinsec. [MG]
 * @entrances can now take multiple switches, to show multiple types. [MG]
 * Removed the obsolete @map command. [MG]
 * @boot <player> now boots all of <player>'s connections, not just the
   first. Similarly, @boot/me boots all your idle connections. [MG]
 * @dump/debug was broken and undocumented. [MG]
 * Removed page/blind (and the blind_page config option). [MG]

Functions:
 * llocks() without any arguments returns a list of the standard locks.
 * unsetq(), to erase queue registers. [GM]
 * and[l]flags(), or[l]flags(), andlpowers() and orlpowers() now all return
   #-1 if an invalid flag/power is given. Suggested by AnneLions. [MG]
 * benchmark(), to benchmark softcode. [DC]
 * Added "flag" as a category to valid(), to check for valid names for
   @flag/add and @power/add. [MG]
 * New pfun() function, which evaluates attributes from your parent as if
   you were inheriting them, even if you have your own copy of the attr. [MG]
 * locate() can take a new parameter, 'x', which causes it to only match 
   exact object names, ignoring partial matches. Suggested by Minion. [MG]
 * ncand()/ncor(), short-circuit versions of nand()/nor(). [MG]

Fixes:
 * Bug in ansi() when no colors are given and buffer_len is reached has
   been fixed. Reported by Chris Humbert. [GM]
 * Bug caused by silly assumptions in list2arr() regarding remove_markup
   fixed. Reported by Stoko@M*U*S*H. [GM]
 * Using some substitutions on the connect/motd/etc attributes introduced
   in p11 could cause a crash. Reported by Minion@M*U*S*H. [GM]
 * Substitions on the connect/motd/etc attributes now work as expected
   when a player is connected. Suggested by Minion@M*U*S*H. [GM]
 * English matching works better with possessive get
   (get box's 2nd thing). Reported by israphel.
 * Various additions and changes to the translatable server messages by
   Stoko. Also updated the I18N file, and added /po/pennmush.pot.
 * 'No such file' messages were logged by mistake when connect_file and
   similar options were set to a dbref/attr. Reported by Zalethon. [MG]
 * Some cygwin C library versions define the imaxdiv_t type but not the
   associated imaxdiv() function. Split them up into 2 configure checks.
   Reported by Rankard.
 * Several math functions didn't complain if their first argument wasn't
   a valid number. Reported by Jules. [MG]
 * @wipe would incorrectly set the attribute list for an object in some 
   cases, making some attributes appear to be deleted. Reported by
   Cooee@M*U*S*H. [MG]
 * The Pueblo_Send @power did not allow objects to send restricted HTML 
   tags, just attributes. Reported by Daniel Powell. [MG]
 * Fixed a crashbug in @uptime. [MG]
 * Various Pueblo fixes. By Sketch.

& 1.8.3p11
Version 1.8.3 patchlevel 11                     Jan 01, 2010

Major changes:
  * The WHO, DOING and SESSION commands are now normal game commands,
    and can be @hook'd, typed in lower-case, etc. (The WHO at the login
    screen is separate.) If you have a softcoded 'who' command, you will
    need to @hook/override WHO for it to continue working. Suggested by
    Bane. [MG]
  * The "take" command has been moved from the hardcode into alias.cnf.
    If you want to keep it as an alias for "get", you should add the line
    "command_alias get take" into your alias.cnf. [MG]

Configuration:
  * The *_file options (connect_file, motd_file, etc) can now be a
    #dbref/attribute instead of a filename, in which case the given
    attribute is evaluated and the result shown in place of the text file.
    Based on patches by Nathan Baum and Mercutio@M*U*S*H. [MG]

Commands:
  * @decompile now takes multiple attribute patterns after the /
    (@dec obj/attr attr2) [GM]
  * @channel/decompile now shows the dbref of the channel mogrifier,
    instead of its name. [SW]
  * @pemit now takes a /port switch, which sends the message to the
    specified port. Suggested by Mercutio. [MG]
  * @hook/list without a <command> now shows all commands which have hooks.
    Based on a patch by Trinsec. [MG]
  * @search now takes multiple <class>=<restriction> pairs. [MG]
  * The IDLE command now takes an optional argument, which it prints back
    to the descriptor which sent the command. [MG]
  * IDLE no longer increases the cmds() for a descriptor. [MG]

Functions:
  * die() now takes up to 700 dice.
  * remove() will now remove a list of words.
  * table() now supports <, > and - as alignment parameters to field width.
  * testlock(<boolexp>, <victim>) tests a lock without setting it.
    Suggested by Mercutio@M*U*S*H. [GM]
  * lnum() now takes a fourth argument: A step. [GM]
  * cwho() now takes an optional second argument, to control whether
    online, offline or all players are returned. Suggested by Mercutio,
    based on a patch by Ifrit. [MG]
  * room(<room>) now returns <room>, instead of #-1. Also, room(<exit>)
    returns the exit's source room, rather than the destination. Suggested
    by Null@M*U*S*H. [MG]
  * Fixed a bug in how align() strips spaces when wrapping text. Reported
    by Paige@M*U*S*H. [MG]
  * pemit(<port number>, <message>) sends <message> to the specified
    port, like @pemit/port. Suggested by Mercutio. [MG]
  * lports() and lwho() take an optional second argument to include
    connections at the login screen. Suggested by Mercutio. [MG]
  * namelist() now takes an optional #dbref/attr, called for each invalid
    name in the first argument. [MG]
  * lmath() can now do lt, lte, gt, gte, eq and neq. Also, lt(), lte(),
    etc, can all take more than 2 arguments. [GM]
  * Anyone can now use ctime() on any object. [MG]
  * locks() reported built-in locks as being user: locks. [MG]

Fixes:
  * Help fixes by various folks.
  * lsearch() with invalid syntax was failing to report it as such, causing
    confusion when lsearch(me,exits) returned the same as lsearch(me). [GM]
  * fun_merge() was eating characters when ansi was present. Reported
    by Nammyung. Fixed. [GM]
  * Windows compile fixes.
  * Math-y crashbug fixed. Reported by Ghost@M*U*S*H. [GM]
  * page/port didn't evaluate its arguments properly. Reported
    by adkins@drigon.com. [SW]
  * randword() with a single element list wasn't dealing correctly
    with extra spaces. Reported by Minion. [SW]
  * @listen/^-listens should now be triggered with the object being
    spoofed as %#, not the object doing the spoofing, when @message/spoof
    (and @pemit/spoof, etc) are used. Reported by Mercutio@M*U*S*H. [MG]
  * Fixed some minor type-related warnings when compiling on cygwin. [MG]
  * @functions which were set "localize" would report being set "Userfn"
    as well, and functions set "Userfn" weren't reported as such. [MG]
  * Objects could be set with flags which weren't valid for their object
    type, if such flags were in the <type>_flags config option. Found by
    Kitai. [MG]
  * Crashbug in the command parser fixed. Found by Freon, patch by Javelin.
  * Added some missing punctuation in channel messages. Reported by Stoko.

   
 Minor changes:
  * @listen/^-listens now carry over ANSI. Requested by Mercutio. [MG]
  * @adisconnect now has %5, which is true if the disconnecting descriptor
    was @hide. Suggested by Minion@M*U*S*H [GM]
  * @pemit <name>= would show nospoof info if <name> was set Nospoof. Now,
    it does nothing at all. Reported by Minion. [MG]
  * The connect screen can now contain ANSI color. Patch by Mercutio.
  * Small bug fix in @search. [MG]
  * Built-in functions can be set FN_LOCALIZE to preserve %q-regs. [MG]
  * Refactoring of ufun(), ulocal(), u[l]default() and ulambda(). [MG]
  * The "Not enough money to queue command" message tells you which object
    was attempting to queue the command. Suggested by Daniel Powell. [MG]

Tools:
  * New script in utils/ for searching change logs: grep-cl.pl [SW]

& 1.8.3p10
Version 1.8.3 patchlevel 10                     Aug 24, 2009

Major changes:
 * Switched project management (Bug tracking, revision control, etc.)
   to Google Code. See http://code.google.com/p/pennmush

Minor changes:
 * @search and lsearch() now only charge 100 pennies if an evaluating
   search (EVAL, EPLAYER, EROOM, ETHING, EOBJECT, EEXIT or ELOCK) or
   an exhaustive attribute search (COMMAND, LISTEN) is performed.
 * The %u sub now works for built-in commands, as well as $-commands.
   Useful for @hooks. [MG]
 * The use command now understands english matching. Suggested by
   Yuriko.
 * Rooms can now use @open/open(). [MG]
 * Mortals can now use '@attribute <attrib>' to see the default flags
   of a standard attribute. [MG]
 * @channel/priv now uses 'thing' instead of 'object' for channels
   which allow things to join. 'object' is kept as an alias. [MG]
 * The chatdb now saves channel buffers and mogrifier objects, so you
   don't need to put @chan/buffer or @chan/mogrifier in @startup. [MG]

Flags:
 * The HEAR_CONNECT flag is now used (instead of MONITOR) to allow
   players to see 'GAME: Foo has [dis]connected.' messages. MONITOR
   on players now enables ^-patterns, the same as on things/rooms.
   Any players with the MONITOR flag will have it replaced with the
   HEAR_CONNECT flag automatically. Requested by Malix@8BitMUSH. [MG]

Functions:
  * lpids(), getpids(), and pidinfo() provide information about
    wait/semaphore process ids and processes. Suggested by
    Yuriko@M*U*S*H, code by Javelin.
  * lalign() works like align(), but takes a single arg with a list of
    columns, instead of one arg for each column. Suggested by Teal. [MG]
  * New lockowner() function returns the owner of an @lock. Suggested
    by Paige. [MG]

Fixes:
  * @pcreate without a password would crash the game. Fixed. [GM]
  * DARK-disconnected on channels was turned into DARK-connected, on
    disconnect. Reported by Paige@M*U*S*H, among others.
  * MOGRIFY`BLOCK wasn't being called, as help @channel6 said it was.
    Oops. [GM]
  * Help fixes, by Sketch and others. [GM]
  * @clone could mess up the names of the original and the clone. 
    Reported by qa'toq. [SW]
  * Crash bugs in rand() and randword(). [SW]
  * Added --disable-zlib configure option to turn off using
    zlib to work directly with compressed databases. Passing this to
    configure makes the game act like pre p8 ones. [SW]
  * member() now ignores ANSI in matches. Reported by Minion. [MG]
  * Regexp $-commands are now ansi aware. As in: ansi is passed to %0-%9. [GM]
  * hidden() now works on descriptors as advertised. Reported by Teal. [MG]
  * @name could cause a crash. Fixed. Reported by Zedekiah@M*U*S*H [GM]
  * @nscemit/silent didn't work. Reported by Paige. [MG]
  * Win32 compile fixes and project file updates.
  * The chatdb failed to load when objects of the wrong type were listed
    as channel members. Reported by Teal. [MG]
  * flags() on an attribute used as the root of a tree would include the
    ` twice.
  * baseconv() would hang the MUSH if passed a negative <number>. Reported
    by Mercutio. [MG]

& 1.8.3p9
Version 1.8.3 patchlevel 9                      Feb 28, 2009

Fixes:
 * Starting up without an existing database was broken in p8.
   Reported by many people. [SW]
 * p8 didn't compile for many people for a number of reasons.
   [SW]
 * match() was broken. Reported by Kimiko. [SW]

& 1.8.3p8
Version 1.8.3 patchlevel 8                      Feb 26, 2009

Major changes:
 * @chan/mogrifier - Mogrify (mangle) any and all aspects of @channel
   chatter. e.g: make <Public> into [cilbuP]. [GM]

Minor changes:
 * The restart script appends a timestamp to the backups of
   existing databases and log files that it makes. Suggested
   by Ray,
 * @setting a flag that's already set will say so. Suggested by
   Kimiko, patch by Talvo.
 * Added 'magic sort': Sorts strings with embedded numbers and
   dbrefs.
 * Controlling whether info_slave is used or not moved into configure
   from options.h. (--enable-info_slave/--disable-info_slave). [SW]
 * Experimental change to attribute lookup to reduce the number of
   expensive string comparisions needed. [SW]
 * Updated the Mersenne Twister PRNG to a newer version (Look up
   SFMT for details). [SW]
 * New configure options --enable-sse2, --enable-sse2 and
   --enable-altivec. Currently only used in a few spots, including
   the new version of the PRNG. [SW]
 * Remove the MALLOC_PACKAGE option and csrimalloc, the only remaining
   non-system malloc() choice for it. csrimalloc didn't compile any more
   and there are better memory debugging tools available these days (The
   rational for keeping it when other malloc packages were removed.) [SW]
 * The mush can now read and write gzip-compressed databases without 
   relying on external programs if the server has zlib installed. [SW]
 * @search and search() now have a 'command' and 'listen' search class,
   allowing @searches for objects that respond to given $-commands and
   listen patterns. [GM]
 * New config option to reserve space on startup for the chunk swap
   file to reduce on-disc fragmentation (With a supported OS). [SW]
 * @shutdown/reboot makes an effort to verify that the executable
   still exists before trying to restart. Suggested by Alrynnic. [SW]

Commands:
 * @config/save foo=bar acts like @config/set but also attempts to
   alter the original configuration file to reflect the new value. [SW]
 * Wizards can specify a garbage dbref for @create and @pcreate to
   re-use instead of the first free one. Suggested by Mercutio, based
   on patch by Talvo.

Functions:
 * Improved the soundex() implementation. [SW]
 * Removed the arbitrary limit on the number of @functions. [SW]

Fixes:
 * locate() always used english matching even when not explicitly told
   to. Patch by Talvo.
 * sha0 hashing was broken on 64 bit systems without OpenSSL. Reported
   by Exaurdon. [SW]
 * The dump_complete message wasn't being shown on a successful forking
   dump. Reported by cquesnel. [SW]
 * speak() deals better with message strings like 'you," he adds, "rock!"'
   Reported by Summer, fix based on Javelin's analysis.
 * speak() deals better with mismatched quotes. Reported by Summer. [SW]
 * A long-standing bug where it was possible for multiple mushes to use
   the same port (One on an IPv6 version, one on a IPv4 one) is now
   harder to trigger and gives a better error message. [SW]
 * Plug a memory leak in decode64().
 * wild matching with ansi involved has been fixed. [GM]
 * clflags() sometimes truncated its result. Reported by dbwiddis. [SW]

& 1.8.3p7
Version 1.8.3 patchlevel 7                      Oct 01, 2008

Minor changes:
 * If compiling with a recent enough version of gcc to support the
   -fstack-protector option to detect buffer overruns, use it.
 * Compile with -mdynamic-no-pic on powerpc OS X, resulting in a smaller
   binary.
 * On newer Linux systems, detect when various indexed and cached files
   are changed and automatically reload them instead of waiting for a 
   @readcache.
 * New map data structure with integer keys, used in various places.
 * Queue entries now have process ids, used to identify and act on that
   particular action list. This and associated commands inspired
   by [Rhost].
 * New configure option --disable-sql to turn off checks for all supported
   SQL servers.
 * @name strips out quotes around player names even if spaces in them are
   disabled.
 * The test suite can now use valgrind to identify buffer overflows and
   similiar problems triggered by tests, by passing the --valgrind option
   to test scripts.
 * Significantly reduce memory usage in @sitelock rules. 

Commands:
 * '@hook/override cmd=#1234' will look at all attributes on the object
   for a matching $command. By Talvo.
 * @sitelock/delete NNN will remove the sitelock rule with that number.
 * @halt/pid NNN will remove a specific queue entry. Get the pid from 
   @ps. [Rhost]
 * @wait/pid will adjust the wait time of queue entries. [Rhost]
 * @chan/title <channel> will display your current channel title. 
   @chan/title <channel>= will clear it. Patch by Talvo, suggested by
   Ender.
  * @chan/recall could be used on any channel, not just by people on
   a given channel. Patch by Talvo.

Functions:
 * controls(<who>,<what>/<attribute>) tests if someone can change or
   create a specific attribute on an object. By Talvo.
 * hasattr() and family also understand foo(<object>/<attribute>) in
   addition to the traditional two-argument form. Suggested by Impster,
   patch by Talvo.
 * cbufferadd() - Add text to a channel buffer without broadcasting it.
   Allows for @chan/recall on an @chat that's been overridden.
 * Rewrote the internals of round() to avoid some nasty kludges. [SW]
 * ljust() and rjust() take fill strings now, not just single
   characters. Suggested by Nyssa, patch by Talvo.
 * baseconv() now supports up to base64.
 * The undocumented (And unusable) orpowers() and andpowers() functions
   were removed.
 * andlpowers() and orlpowers() were missing help files. Reported by
   Parusso.

Fixes:
 * Potential infinite loop in error logging fixed. Reported by Yuriko.
 * Compilation fixes on various platforms. [SW]
 * A repeatingly crashing info_slave won't block login attempts.
 * @chan/what reports the number of actual lines stored in 
   recall buffers, not the number of blocks. Reported by
   qa'toq [SW]
 * portmsg didn't compile. Reported by Impster. [SW]
 * A chat db with a garbage object on a channel would fail to load.
   Reported by Rince. 
 * Fixed a double free error in page. By Ricochet.
 * Many help file and source documentation fixes reported by far too
   many people to list.
 * Hard-to-trigger double free() in help file reindexing fixed.

& 1.8.3p6
Version 1.8.3 patchlevel 6                      Jan 01, 2008

Major changes:
 * If configure finds a copy of the pcre library installed, that will
   be used instead of the (old) version bundled with Penn. use
   --with-pcre=/path/to/it if it's not in the usual places, or
   --with-pcre=no to force use of the bundled version.

Minor changes:
 * @sitelock when there are no rules will now say that instead of
   having no output. By Talvo.
 * Log files use locking to prevent the small chance of more than one
   process writing to the same error log at the same time.
 * info_slave's logging is more clear as to its source.
 * Several places that used the select() system call now favor poll()
   and/or socket timeouts instead. (The main event loop still uses
   select() for now.)
 * A wildcard help topic search (help foo*) that only matches one
   entry will display that entry. Suggested by Cheetah.
 * New switches for commands no longer have to be added to the
   SWITCHES file; the internal list of switches is now built based on
   what switches are given in the command table and cmdlocal.c
   additions. Suggested by Talek. 


Flags and powers:
 * The announce power now also grants the ability to change the motd.
   Suggested by Yuriko.
 * New hook power grants rights to use @hook. Suggested by Paige.
 * Windows compile fixes by Intrevis.

Commands:
 * @motd gives better feedback when clearing a message.
 * The @tport/@otport/@atport/etc. attributes that get evalulated on a
   @teleport now get the dbref of the object doing the teleport in %0
   and the teleported object's old location in %1. Suggested by Daniel
   Cheng.

Functions:
 * root() uses an improved algorithm to give a more precise
   result.
 * log(N,2) uses the C log2() function if available.
 * log(N,e) takes the natural logarithm of N, like ln().
 * lports() now takes an optional viewer argument, a la lwho(). By
   Talvo.

Fixes:
 * Typo in info_slave preventing simultaneous hostname lookups fixed.
 * Compiliation fix with some compilers. Reported by Kimiko.
 * ident lookups of new connections was broken for several
   patchlevels.  Works again. Sometimes.
 * Cleaned up some warnings generated by gcc 4.2
 * Fixed some minor bugs detected by running under valgrind.
 * OpenBSD configuration fixes.
 * Fixes from 1.8.2p8

& 1.8.3p5
Version 1.8.3 patchlevel 5                      October 6, 2007

Major changes:
 * Significant rewrite of ansi parsing and better ansi support
   for many string-handling functions. Patch by Sketch.
 * Rewrite of the softcode regression testing framework, and 
   addition of more tests. [SW]

Minor changes:
 * Store a pointer to the start of a player's mailbox in objdata
   instead of the connection struct.
 * Experimental rewrite of hash tables to use the cuckoo hashing
   algorithm, with constant-time lookups even in the worst case.
   (And appears to have generally faster lookup even in normal usage.)
 * Regular expression @sitelocks save the compiled regexp instead of
   recompiling every time the rule is tested.
 * Added %4 to @pageformat, which is the default page message.

Commands:
 * Added @message, which makes it easy to use @chatformat or
   @pageformat via @hooks, or to create your own *format.

Functions:
 * Added message(), the function version of @message.

Fixes:
 * decode64() does better validation of its input. [SW]
 * Various compile fixes reported by Interevis and Kimiko.
   Win32 patched by Intrevis.
 * @sitelock does better error reporting. [SW]
 * Crash bug related to regeditall fixed.
 * @decompile didn't handle attribute trees correctly.
 * Compile failure in funstr.c on some systems. Fixed by Boris.
 * '@set =foo' failed silently. Reported by Talvo.
 * Fixes from 1.8.2p7

& 1.8.3p4
Version 1.8.3 patchlevel 4                      July 9, 2007

Major changes:
  * Parts of the build process that used a shell script to regenerate
    certain headers now use perl scripts instead, making them much
    faster. [SW]

Minor changes:
  * The hash tables used by lmath() and html functions now
    use perfect hashing to speed up lookups. [SW]
  * The various slab allocators used by attributes and locks
    and other areas have been replaced with a generic
    slab allocator. Also, many more allocations are handled
    by the new code.
  * Use the writev() system call to send data to unencrypted
    connections in bigger chunks instead of using multiple send()s of
    smaller chunks.
  * New lock types can be added via src/local.c instead of having to
    alter the table in src/locks.c. Based on patch by Talvo.
  * Builtin lock names and default flags are stored in a hash table
    instead of a list. [SW]

Attributes:
  * @chatformat allows you to customize Channel chat messages
    that you see. [GM]

Commands:
  * '@list allocations' displays allocation information.
  * @stats/tables no longer dumps mem_check information.
  * @search (and by relation search()) now has an 'elock'
    search class, permitting boolean expression searches. [GM]
  * @channel/recall extended to support recalling by time. Example:
    '@chan/recall Foo=1h' will recall lines only from the past
    hour. Patch by Talvo.
 
Functions:
  * cond() works like an if, else if, else if ... ncond(),
    condall(), ncondall() also added. [GM]
  * speak() accepts a 1st argument beginning with '&' to use
    an arbitrary speaker name. [GM]
  * New speakpenn() function handles : <pose> in Penn style.
    Suggested by Sketch, patch by Javeln.
  * lmath() accepts dist2d and dist3d. Suggested by Jess.
  * functions(local) returns just local @functions. [SW]
  * New encode64() and decode64() functions convert between
    normal text and base64 encoded text on games that have
    SSL support compiled in. [SW]
  * encrypt() and decrypt() now take an optional 3rd argument
    to control using base 64 encoding. Suggested by Noltar.
 
Fixes:
  * Compile fixes for some linux (And other?) systems that expect
    all libraries to be after source files on the command line
    when linking. Reported by Balerion.
  * Compile fix for some Postgresql installations. Reported by
    Nymeria.
  * Fix to fraction() when dealing with numbers that can't
    be fractioned. Discovered by Ashen-Shugar.
  * Fixes to align() and coalescing by Javelin. Bugs reported by
    Sketch and tramp.
  * Fixes to speak() to bring it closer to Tiny's behavior in
    common cases by Sketch and Javelin.
  * Fixes to ANSI output where extra ^[[m were being sent.
  * Default flags weren't getting set on some attributes in certain
    cases. Report by Talvo.
  * Fixes from 1.8.2p6

& 1.8.3p3
Version 1.8.3 patchlevel 3                      June 13, 2007

Minor changes:
  * The sockets used to talk to info_slave changed from streams
    to datagrams, simplifying code. [SW]
  * info_slave deals better with simultaneous connections. [SW]
  * info_slave requires the presence of the socketpair(2) function.
    It was already using it anyways.
  * Use of some system calls with portability issues encapsulated in
    wrapper functions. [SW]
  * sql() returns error codes directly instead of notifying %!. [SW]

Functions:
  * lattr() and lattrp() take an optional delimiter argument. Suggested
    by Nathan Baum. [SW]
  * New csecs() and msecs() functions, like ctime() and mtime() but
    returning the time in seconds instead of a formatted string. Based on
    a patch by Talvo.
  * ctime() and mtime() take an optional second argument to control which
    time zone the time is displayed for: UTC or the server's. [SW]
  * fn() by Javelin
  * letq(). Suggested by Nathan Baum. [SW]
  
Fixes:
  * Assorted compiler warning fixes. [SW]
  * Compile fix on OS X 10.3. Reported by Viila. [SW]
  * @sql wasn't enabled if Sqlite3 was the only database turned on.
    Reported by qa'toq.
  * Problems with sql() using Sqlite3. Reported by qa'toq. [SW]
  * Problems with null queries using MySQL. Reported by duckwa. [SW]
  * Start fixing code that assumes that int and long are the same
    size. [SW]
  * Linting of code that uses strcpy, strncpy() and sprintf() to
    rule out remote possibilities of buffer overflows. [SW]
  * align() off-by-one error in left coalescing fixed. Reported by
    Sketch. [Javelin]
  * User locks were broken in the last patch. Reported by Michael Brazaitis.
    [SW]
  * ./configure --without-ssl works. Reported by Starr. [SW]
  * objid matcher didn't work properly. [SW]
  * Many functions that used parse_dbref updated to use parse_objid,
    to see more objid compliance. [GM]
  * Fixes from 1.8.2p5

& 1.8.3p2
Version 1.8.3 patchlevel 2                      May 16, 2007

Major changes:
  * configuration is now done by autoconf. ./Configure is
    now ./configure and its options have changed. See
    INSTALL and ./configure --help [SW]
  * Support for the postgresql SQL server. Javelin.
  * Support for sqlite3 SQL databases. [SW]

Minor changes:
  * You can no longer run a mush as root. [SW]
  * cemit_noisy config option.  Suggested by Kimiko. [SW]
  * @function sorts the list of user-defined functions
    by object and then name. Suggested by Trinsec. [SW]
  * Better logging of the register login screen command
    for systems without a sendmail program. [SW]
  * Assorted refactoring of source code. [SW]
  
Functions:
  * isobjid(). By Balerion.
  * player() returns the dbref of the player connected to a given
    port.  By  Nathan Baum.
  * root(X,3) uses the C cbrt() function if available. [SW]
  * New formats for align() that allow flowing text. Javelin.
  * isdbref() understands objids. By Balerion.

Fixes:
  * regmatch() broken with %q-registers. Javelin. 
  * Better checking of dbref config options to make sure they're
    valid objects. Suggested by Talvo. [SW]
  * Fixed assorted cases of accidently modifying const objects.
    Thanks to Jake. [SW]
  * Fixed a crash bug in strmatch(). [GM]
  * wrap() of Pueblo tags didn't work very well. Fixed by
    Sketch.
  * @wipe's count is accurate when attribute trees are being
    deleted. Reported by Talvo.
 
& 1.8.3p1
Version 1.8.3 patchlevel 1                      March 11, 2007

Minor changes:
  * page command now processes page output through PAGEFORMAT
    attribute, allowing user-set page messages. [GM]
  * sql_host configuration option now permits alternate tcp port.
    Suggested by Mercutio. Patch by Javelin.
  * Refactoring of fun_stringsecs to help function etime_to_secs.
    Patch by Javelin.
  * %1 in @aconnect works like in @adisconnect. Patch by Javelin.

Fixes:
  * restart script once again includes DATEMSK export for
    extended convtime support. Reported by KimikoMuffin.
  * Memory leak in 1.8.3p0 regedit fixed.
  * Fixes included from 1.8.2p3.
  * Document change in @chan/title behavior with commas.

& 1.8.3p0
Version 1.8.3 patchlevel 0                      January 27, 2007

Major changes:
  * Rewrite of color handling. [GM]

Minor changes:
  * Cleaned up the internals of @wipe. [SW]
  * strmatch() now takes a third argument, to store wildcard captures. [GM]
  * Termination of OS/2 support. [SW]

Fixes:
  * Fixes included from versions up to 1.8.2p2.
& 1.8.4p8
Version 1.8.4 patchlevel 8                                 Nov 11, 2011

Major changes:
 * ssl_slave is enabled by default by configure if OpenSSL and libevent2 are present. Passing --disable-ssl_slave to configure will still disable it. [SW]
 * The newline_one_char config option has been removed -- %r now always returns a single-char newline (\n). [MG]
 * Microsoft Visual Studio 2010 project files contributed by Daniko.

Minor changes:
 * crunch_code and crypt_code in funcrypt.c are no longer static. Requested by qa'toq@M*U*S*H. [MG]
 * @dump now notifies the executor when the dump is complete. Suggested by Padraic. [MG]
 * There is now a slight delay between a client connecting to the MUSH, and the connect screen being shown. This means that the "<-- ... -->" HTML comments are no longer needed around the connect screen when mud_url is enabled, the HTML shown when someone connects to the MUSH with a browser works better, and that Pueblo clients will usually only get the HTML connect screen, instead of seeing both. Also, telnet negotiation should complete before the screen is shown, making terminfo() and width() give useful values for people using softcoded connect_files. Commands can still be used before the connect screen is displayed. [MG]
 * When looking at an object, all its components (describe, descformat, conformat and exitformat) now share registers: a q-register set in the desc can be accessed in the conformat, and so on. [MG]
 * When you fail to @mail a player because you don't pass their @lock/mail, the MAIL_FAILURE verbs will be triggered, as per 'help failure'.  Suggested by Cheetah. [MG]
 * When using channels() on an object, the permission checks now resemble those for cwho() / @channel/who. Based on a patch by Padraic. [MG]
 * Guests no longer control anything, including themselves, and can't ever build, create or destroy objects. They can still examine themselves, for backwards compatability. Suggested by [SW]. [MG]
 * Changed many things which were evaluating an attribute value manually to use call_ufun() instead, for better %+ / %= values, among other benefits. [MG]
 * fetch_ufun_attrib now takes a new flag, UFUN_NAME, which will add the object's name to the beginning of the attr value (respecting no_name and no_space attr flags), for @o-* attrs. [MG]
 * Clean up the functions that send data across the network to connections. [SW]
 * Updated intructions for compiling with MySQL support on Windows contributed by Daniko.
 * Improve ssl_slave cleanup code on lost connections and shutdowns. [SW]
 * @list locks and list(locks) sort their results. [SW]
   
Fixes:
 * @lock/infilter, not @lock/infitler. [SW]
 * @shutdown/reboot handles failed database saves much more gracefully. [SW]
 * Help fixes by Wiggles and Trelane. [MG]
 * Fix a few places that could trigger an integer division exception. Reported by Ashen-Shugar. [SW]
 * A number of places in the hardcode incorrectly took TINY_MATH into account when deciding if something was a valid number or not. From a report by Daniel Powell. [MG]
 * doing() now evaluates the DOING attribute with better values for %# and %@. From a report by Padraic. [MG]
 * Fix some cases where functions like lcon() could return partial dbrefs at the end of a long output string. [SW]
 * When magic-sorting strings with embedded dbrefs, setunion() no longer treats different objects with the same name as being identical. Reported by Minion. [MG] [GM]
 * type() and hastype() claimed to work on GARBAGE objects, but actually returned #-1 NO SUCH MATCH. Reported by Jules. [MG]
 * A few messages were sent with incorrect nospoof data. Reported by Jules. [MG]
 * Fix a harmless but annoying race condition when making a SSL connection to a game in the middle of starting. [SW]
 * Fixed minor memory leak in chat system. [MG]
 * @channel/decompile didn't recreate the ANSI in a channel's name. [MG]
 * Channel names can now contain any amount of ANSI, as long as the visible name is 30 chars or less in length. Suggested by Kimiko Muffin. [MG]
 * @channel/rename allowed you to give channels invalid names. [MG]
 * @readcache rebuilds the linux file watch list, allowing deleted files to be watched for changes again when re-created. [SW]
 * Crash bug in @boot/me. Reported by Minion. [SW]
 * Fix in handling clients like putty that send telnet commands right away instead of waiting for the mush to send them first. Reported by Time. [SW]

Functions:
 * isregexp() to validate regexp patterns. Suggested by Padraic. [DC]
 * sqlescape() doesn't need to have commas escaped. Suggested by Daniko and Padraic. [SW]
 
Commands:
 * 'examine' and 'brief' now take an /opaque switch, which omits contents listings. Useful for spammy objects like the player_start room. [MG]

& 1.8.4p7
Version 1.8.4 patchlevel 7                                 Sep 25, 2011

Deprecation:
 * @elock, @eunlock, @ulock and @uunlock are deprecated. [SW]
 * @doing is now deprecated (see below).
 * The "newline_one_char" mush.cnf option is now deprecated, and will soon always be "Yes". If you have it set to No and have any code that assumes strlen(%r) == 2, you should change it now. [MG]

Major changes:
 * DOING is now a standard attribute. Your @doing can be any length, and doing() returns the whole string (though it will still be truncated when displayed on WHO), can contain ANSI and will be evaluated each time it's displayed, allowing for random/rotating doings. The @doing command will escape its input before setting into an attribute, for backwards compatability, but is now deprecated; use &doing to store code. [MG]
 * All objects with the same flags or powers set share the same storage for those flags. Large games should see slightly reduced memory use. Suggested by [GM]. [SW]

Minor changes:
 * Rewrite memcheck allocation tracking to use a more efficient data structure. [SW]
 * Help file improvements, by Ender and others. [SW] [MG]
 * Added a new 'getting started' helpfile, that gives a brief overview of how to move, talk, use channels and @mail. Suggested by Wiggles. [MG]
 * @decompile now uses '&attr obj=value', even for standard attributes, to avoid possible clashes with command names. Suggested by Mercutio. [MG]
 * Extended convtime understands timestamps of the form 'YYYY-MM-DD hh:mm:ss'. Suggested by Padraic. [SW]
 * pemit() now accepts a list of port numbers, to pemit to multiple ports at once. Suggested by Padraic. [MG]
 * Built in functions and commands can now be marked as being deprecated. Using one of these functions or commands results in a warning to the owner of the object executing them. Deprecated functions and commands might be removed in future patch levels; code using them needs to be rewritten. [SW]
 * Rewrite function restriction parsing and reporting to make it easier to add new restrictions. [SW]
 * Code cleanup. [SW]
 * Channels are now ungagged on disconnect, instead of connect, so you'll see your "<Foo> Bar has connected." message next time you log in. [MG]
 * WARN_ON_MISSING can now be @hooked. Suggested by Padraic. Also, help has been added for that and UNIMPLEMENTED_COMMAND. [MG]
 * fn() didn't always work correctly on a UserFn function, especially when nested in another function. Reported by Padraic. [MG]
 * Accents are no longer stripped from output sent to players who haven't logged in (those at the connect screen). Suggested by geradon. [MG]
 * Softcode functions are now passed an additional argument, eflags, by the hardcode, which should be used when the function calls process_expression(). See HACKING.184 for more info. [MG]

Functions:
 * Mortals can now use lwho(me). Allows for lwho(%#) on ancestors to be used by all. Suggested by Minion. [MG]
 * xwho() now takes an optional <looker> arg, like lwho(). [MG]
 * rand() without an argument returns a floating point number greater than or equal to 0 and less than 1. [SW]
 * itemize() is now more ANSI-aware. Reported by Jules. [MG]
 * fullalias() didn't include old-style exit aliases (which were a part of the exit name). [MG]

Locks:
 * New locks, @lock/filter and @lock/infilter, which must be passed (along with any @filter/@infilter set) for an object to forward sound. Patch by Padraic.

Fixes:
 * Verified that Penn compiles using the clang compiler, and fix a few warnings it generated. [SW]
 * Better fix for the DBREFLIST issue fixed in p6. [SW]
 * @pemit/list stopped reporting when it failed to match an object in p5. Reported by Padraic. [MG]
 * 'page' evaluated its args incorrectly when used in an $-command. Reported by Invidia@Dune3. [MG]
 * Win32 compile fixes by Daniel Powell. [MG]
 * Fix an off-by-one error in wrap(). Report by Padraic, patch by Minion [MG]
 * Sorting code didn't do proper objid checks, so setinter(#1:123, #1:456) would return #1:123 instead of nothing. [MG]
 * The Can_spoof power was only aliased to Can_nspemit (its original name) in upgraded dbs, not in new games created from minimal db. Reported by Ben Ramsey. [MG]
 * Fix a crash bug in @function/restrict on malformed input. Reported by Padraic. [SW]
 * Some fixes to the test suite. Reported by Covenent. [MG]
 * @pageformat included nospoof information. Reported by Jules. [MG]
 * case() clobbered $0-$9 subs. Reported by Jules. [MG]
 * Named regexp captures -- (?P<NAME>pattern) -- were broken in a recent patchlevel. Reported by Jules. [MG]
 * Markup wasn't stripped from queued commands, making it possible for ANSI to bleed. Reported by Wiggles. [MG]
 * Pueblo players couldn't see ANSI in connect screens. From a report by geradon. [MG]
 * money() behaved incorrectly when the tiny_math config option was on. Reported by Daniell Powell. [MG]
 * Databases with 8-bit characters couldn't be saved using the internal libz compression routines. [SW]
 * It was possible to create a player with a forbidden name from the login screen. Reported by Andrew Bell. [MG]

& 1.8.4p6
Version 1.8.4 patchlevel 6                                 Jul 29,  2011

Minor changes:
 * Clean up the linux inotify file monitoring code a bit. [SW]
 * @forwardlist can be inherited (But defaults to no-inherit). Suggested by Padraic.
 * @pemit/port now takes the /list switch, to pemit multiple ports at once. Suggested by Padraic. [MG]
 * When you 'register' a character at the connect screen, you can re-use the command to send a new password to the same email address, as long as you haven't connected yet. Suggested by Minion. [MG]
 * @odescribe/@adescribe are no longer triggered when a Terse player moves into a room, as he doesn't see the @describe. Suggested by Padraic. [MG]
 * exit-oneway and exit-multiple warning checks now take global exits into account. Suggested by Padraic and qa'toq. [SW]

Functions:
 * valid() can be used with the 'qreg' category to check if a string is a valid q-register name.  [SW]
 * crecall() now returns an error when given an invalid channel, and no longer returns an error when used on a channel with nothing to recall. Suggested by Trinsec. [MG]
 * Added uptime(), which returns much of the information from @uptime. From a suggestion by Jules. [MG]
 * quota() now accepts 'me' as an argument. Suggested by Padraic. [MG]
 * remove() is now ANSI-aware. [MG]
 * money() now checks for an integer argument before checking for an object. Suggested by qa'toq. [MG]
   
Fixes:
 * Wildcard matches on ANSI'd strings sometimes failed. Reported by Duckwa and Paige. [MG]
 * Bug in matching code when a room tries to locate an exit. Reported by Sketch. [MG]
 * Help updates. [MG], [SW]
 * Crash bug in dealing with Pueblo markup. Reported by Mercutio. [SW]
 * Fix some issues in parsing flag/attribute/eval locks. Found by Padraic and Jules. [SW]
 * @[out]pageformat could sometimes receive the wrong alias in %2. Reported by Padraic. [MG]
 * align() didn't correctly apply ANSI to empty columns. Reported by Padraic. [MG]
 * Fix compile warning in player.c when sendmail is not enabled. Reported by Padraic. [MG]
 * Fix hardcode bug in ansi_strcmp, which affected the softcode splice() function. [MG]
 * @chan/what failed to report when Admin channels also had the Player priv. Reported by Padraic. [MG]
 * win32/config.h was lacking a definition for int16_t. Reported by Daniko. [SW]
 * DBREFLIST locks required the attrname be given in upper-case. Reported by Sketch. [MG]

& 1.8.4p5
Version 1.8.4 patchlevel 5                                 Jun 19,  2011

Major Changes:

 * The experimental --enable-ssl_slave option for configure allows persistant SSL connections that won't get booted when the mush restarts. Requires libevent v2.X. [SW]
 * info_slave, the sub-process used for resolving hostnames, now uses libevent if available. [SW]
 * Rewrite of large portions of notify.c. The main public function there, notify_anything(), now takes different arguments. notify_format() and notify() are unchanged. Should be largely unnoticable for players. [MG]

Commands:
 * @edit/quiet edits attributes, but doesn't spam you with the modified values, just gives you a count of modified attributes. Suggested by Padraic. [MG]
 * You can now have more than one command (with the action list enclosed in {curly braces}) in the rhs arg of @force/noeval. [MG]
 * @ps/debug <pid> will display extra information about a queue entry's evaluation environment. [SW]
 * @pemit now acts as if /silent was given when the executor and target are the same object, for consistency with other sound-producing commands and to fix an issue with @pemit/spoof. [SW]
 * @command now shows the failure message that can be set with restrict_command or @command/restrict. [SW]
 * @message now takes a /remit or /oemit switch, to make it work like those commands instead of @pemit. Also takes a /nospoof switch to make it like the @ns*emit versions. [MG]
 * @pemit/list/noisy now shows a confirmation message. [MG]

Powers:
 * can_dark power lets non-wizard players set themselves dark. Suggested by AnneLions. [GM]

Minor Changes:
 * ansi_string has been rewritten to be much faster for non-marked up strings, to take up considerably less memory, and has received general all-around improvements in speed. Rewrite is in preparation for 256 color and 24 bit color ansi. [GM]
 * ansi_string no longer optimizes markup. In some pathological cases, buffer_len will be hit much earlier than it used to be. Use ansi() with wisdom! [GM]
 * @edit no longer shows the full value of attributes which aren't edited, it just shows that they are unchanged. Suggested by Minion. [MG]
 * @mail now shows the dbref of the sender for mail from non-players. Suggested by Minion. [MG]
 * Fix a potential buffer overflow in prefix table code. [SW]
 * "enter <exit>" now works the same as "goto". Suggested by [GM]. [MG]
 * Tweaks to the system queue introduced in the last patchlevel. [SW]
 * @pemit now uses the same nospoof header as other commands. [MG]
 * When creating a minimal db, the MUSH now respects the read_remote_desc option, and may set @descs "nearby". Reported by Paige. [MG]
 * Exits now show accented names (via @nameaccent) in "look". Suggested by Cheetah. [MG]
 * @enter/@oenter/@aenter, @leave/@oleave/@aleave and @move/@omove/@oxmove/@amove get passed the moving object's original and/or new location as appropriate. Patch by Padraic.

Fixes:
 * Crashbug when players are in and homed to a room that is owned by a player being @nuked fixed. Reported by Kimiko. [GM]
 * qregs, %0-%9 and $0-$9 would occasionally smash each other. Reported by Cheetah@M*U*S*H. [GM]
 * No_Pay was implicit if executor is #1, but was _not_ implicit if Owner(executor) was #1. Caused some obscure queue cost bugs. Discovered by Padraic@M*U*S*H. [GM]
 * %$-subs didn't work inside @switch's default case. Patch by Covenent.
 * %0-9 were being overridden when using /inline/localize. Patch by Covenent.
 * You couldn't @chat on open channels. Reported by Padraic. [MG]
 * Win32 compile fixes by Daniel Powell. [MG]
 * The Open_Anywhere power didn't fully work as intended. Patch by Covenent.
 * regrab*() functions removed ansi. Reported by Covenent. [MG]
 * munge() didn't play nice with ansi. [MG]
 * @shutdown/reboot would hang unencrypted sockets for players with both SSL and normal connections. Reported by Padraic. [SW]
 * @chatformat sometimes received the player's name without accents by mistake. Reported by Sketch. [MG]
 * Bug in @wipe fixed by Padraic.
 * Objects couldn't be @tel'd to exits which weren't in their current location. Reported by Padraic.
 * Fixed an obscure bug in "say" when sound is propagated. From a report by Padraic@M*U*S*H. [MG]
 * Various help fixes. [MG], [SW]
 * Prevent persistant 'Attempt to write to error log before it was started!' error in netmush.log [MG]
 * Rooms could not locate objects by name. Reported by Sketch. [MG]
 * Players using Pueblo who are not set ANSI will no longer see colors. [MG]
 * The <inside> arg to tel() didn't work. Fixed by Padraic.
 * 'make clean' in game/txt no longer deletes the configure-generated compose.sh file. Suggested by Padraic. [SW]
 * The new q-register code wasn't passing registers on to new commands queued by @wait, @verb and @mapsql. [SW]
 * Crash bug in unused code to reset hash tables fixed. Reported by Trinisi. [SW]

Functions:
 * Restrictions for the beep() function can now be modified with @function. Suggested by Paige. [MG]
 * Functions that take #lambda anonymous attributes also understand a new #apply/<function name> shorthand for calling a single function. [SW]
 * ldelete() now takes an osep. [MG]
 * allof()/strallof() can now have mutli-char output separators, and null oseps. Reported by Padraic. [MG]
 * benchmark() warns when results are thrown off by hitting the FIL. Reported by Padraic. [SW]
 * New render() function which returns a string rendered as html, without markup, etc. Useful for bots or storing data in SQL. [MG]

& 1.8.4p4
Version 1.8.4 patchlevel 4                                 May 05,  2011

Major changes:
 * Q-registers are no longer limited to single characters. setq(name,joe) and r(name) or %q<name>! Limited by max_named_qregs. [GM]
 * Ident lookup and associated config options have been removed. Between lack of people running ident servers, NAT, and issues in the code, it rarely got results. [SW].

Hardcode:
 * global_eval_context has been removed. The BQUE, EVAL_CONTEXT and PE_Info structs have been removed, replaced with MQUE and NEW_PE_INFO. Shouldn't affect players, but will affect hardcode hacks. See HACKING.184 for more info. [MG]
 * Q-registers are now kept in a PE_REGS stack. See HACKING.184 for more information. This will be used for other registers. [GM]
 * Regexp information ($1, $<foo>) are now kept in the PE_REGS stack. [GM]
 * Faster regexps in many cases when there is no markup. [GM]
 * Switch, iter, and env (%0-%9) information are now kept in PE_REGS stack. switch, iter, @switch and @dol are no longer limited, but new queue entries only keep the last 50 @switch/@dols. [GM]
 * Renamed some variables in COMMAND() definitions for consistency/clarity. See HACKING.184 for more info. [MG]
 * Assorted Windows fixes. [SW]
 * Clean up code using vsnprintf() to remove #ifdefs. [SW]
 * String trees are now fully reference counted with no undeletable entries. [SW]

Minor changes:
 * Because switch() and @switch now store capture data, it can change the nesting of $0-$9/$<foo> in rare cases. [GM]
 * All @o* messages are now heard by rooms even when they're empty. Makes room @listens and similar things work right. Suggested by Padraic. [MG]
 * @zemit and zemit() will now show the executor the message, if he's in a room on the right zone. Suggested by Paige. [MG]

Locks:
 * objid locks are now turned into =-locks by the lock parser. The clearing of references to deleted objects makes objid locks extraneous. [SW]
 * Internal changes to validation of 'name^string' locks to use perfect hash tables to validate the name. [SW]
 * Locks worth better with escaped special characters. Patch by Covenent.
 
Commands:
 * @switch and @switch/regexp set $0-$9 for glob or pattern captures. [GM]
 * @notify/setq can alter Q-registers of a semaphore queue entry before dequeueing it. [GM]
 * 'teach' now takes a /list switch, which lets it run an action list instead of a single command. [MG]
 * @force, @switch and @hook/override now all take an /inline switch, which can be further modified with /clearregs, /localize and /nobreak to run their actionlists without queueing (replaces /inplace). @include also takes those three switches. See the help for more info. [MG]
 * @retry, which causes a queue entry to restart from the beginning. Useful for coding loops without the queue delay. [GM]
   
Substitutions:
 * $<name> for accessing regexp substitutions can now have evaluation inside the <>s: $<%qa>. [GM]
 * %q<foo> can access named Q-registers. %q<%qa> can work as a q-register dereference. [GM]
 * New %= substitution, which evaluates to the dbref/attribute currently being evaluated. Useful for coding things which loop. [MG]

Attributes:
 * Branch attributes now show the 'branch' attribute flag in lflags(). [MG]
 * no_inherit and no_clone weren't propagated down attribute trees as stated in the help, but now are. [MG]
 * The debug and no_debug attribute flags now affect attributes which are queued (via $-commands, @trigger, etc) as well as ufun()'d. Suggested by Wiggles. [MG]
 
Functions:
 * switch() sets $0-$9 for glob captures.
 * setq(), regmatch(), strmatch() and sql() accept q-register names of more than one character. [GM]
 * unsetq() now accepts patterns of q-register names. [GM]
 * listq() lists q-registers available to r(), optionally limited to those matching a pattern. [GM]
 * elock() now only requires that you can see the lock you're trying to test. Suggested by Sketch@M*U*S*H. [MG]
 * Changes to scan(): Returned value now always returns the object which would run the $-command (even if it's actually set on a parent). scan() can also take a 3rd argument, to limit which objects are checked. Based on a patch by Covenent. [MG]   

Fixes:
 * isword(ansi(r,foo)) would return 0. isword now removes markup before checking. Ditto for isdbref, isnum, isint, isobjid. [GM]
 * round() would sometimes return a number with a decimal point but no digits after it, like "5.". Reported by Minion. [MG]
 * sortby() and foreach() now use call_ufun in the hardcode, fixing a number of minor bugs. [MG]
 * rand(-X, -Y) where -X > -Y was broken. [SW]
 * Fix a couple of minor memory leaks. [SW]
 * Possible crashbug in switch(), @switch, iter() and @dolist fixed. [MG]
 * Fix crash when reading a database with an invalid lock key. Reported by Covenant. [SW]
 * Some fixes to the test suite by Sketch.
 * Help fixes by misskaly, Wiggles and others. [MG]
 * warn_interval set to 0 would cause the MUSH to hang. Reported by Nymeria @ Blood of Dragons.
 * It was sometimes possible for a player to view config options he shouldn't have. Reported by qa'toq. [MG]
 * Possible crashbug in @name reported by Wiggles. [MG]
 * Object matching (a la locate()) with an exit as the looker didn't work correctly. Reported by Covenent. [MG]
 * Panic database dumps weren't always loading correctly. Reported by [MG], fixed by [SW].
 * A missing mail or chat database caused failures in mush startup. Reported by Nveid. [SW]
 * Various fixes to update-cnf.pl by Minion.
 * Setting or clearing the MONITOR flag on rooms caused duplicate messages. Reported by Minion. [SW]
 * @mapsql/notify would sometimes run the "@notify me" before the triggered attributes. Reported by Mercutio. [MG]
 * Combined channels would generate duplicate connection/disconnection messages to players connected multiple times. [SW]

& 1.8.4p3
Version 1.8.4 patchlevel 3                                 Mar 18,  2011

Events:
 * Event system added. Certain things can now trigger events using @config event_handler. See "help events" and "help event <type>". [GM]
 * dump events: dump`5min, dump`1min, dump`complete.
 * object events: object`create, object`destroy, object`move, object`rename, object`kill.
 * sql events: sql`connect, sql`disconnect.
 * signal events: signal`usr1, signal`usr2.
 * player events: player`create, player`fail, player`connect, player`disconnect, player`inactivity.
 * socket events: socket`connect, socket`disconnect
 * database events: db`dbck, db`purge, db`wcheck
 * Periodic system events like warnings checks and db consistency checks are now handled by a timed queue and integrated with softcode events. Local hackers: This involves changes to local.c. If you have no changes in local.c, just delete the file. Otherwise, see HACKING.184 for more info. [SW]

Commands:
 * @hook/override/inplace - You can now run softcode with the same priority as hardcode! [GM]
 * @lock (and all lock keys) now accepts NAME^<pattern> for matching against an object's name. [GM]
 * @mapsql passes row results to attributes. Suggested by Mercutio. [GM]
 * @dig now takes an optional garbage dbref argument to specify the new dbref. Suggested by Paige. [GM]
 * The help command now does some auto-expansion of topics. For example, 'help @chan ad2' will be expanded to match 'help @channel admin2'. [MG]
 * @force/inplace, @switch/inplace and @select/inplace now run their commands without queueing new events. These are limited by the @include limit. [GM]
 * @hide without a switch now toggles hide status, rather than defaulting to @hide/on. [MG]
 * @log now takes a /recall switch for showing wizards the most recent activity in a log file. [SW]
 * @lemit and @zemit both have /noisy and /silent switches to suppress/show confirmation messages. With no switch, silent_pemit determines whether the message is shown. Suggested by Paige for consistancy. [MG]
   
Attributes:
 * New no_debug flag, which prevents debug info being shown for an attribute when the object is set DEBUG. [MG]
   
Config:
 * New @config option chan_title_len controls the length of @channel/title's. Suggested by Paige. [MG]

Locks:
 * New @lock/pay, controls who can "give" an object pennies or "buy" items from an object. Based on patch by Covenent. [MG]

Functions:
 * lockfilter() lets you filter a list of dbrefs using a lock key. [GM]
 * align() now has '$' (nofill) as an option. Ideal for rightmost columns. Suggested by Minion. [GM]
 * dig() now takes an optional garbage dbref argument to specify the new dbref. Suggested by Paige. [GM]
 * convutctime() and convtime(<time>, utc) to convert a timestring to # of seconds since UTC. Patch by Minion.
 * powers() with no arguments now returns a list of powers, similar to lflags() with no args. [MG]
 * trim() can now trim multiple characters. [MG] [GM]
 * In some cases, privs are no longer needed to use locate(). [MG]
 * cmogrifier(), returns the mogrifier object for a channel. Suggested by Trinsec, patch by Minion.

Minor Changes:
 * The Can_Nspemit @power has been renamed to Can_Spoof, to better reflect its uses. Can_Nspemit is still an alias. [MG]
 * Considerable improvement in the speed of functions that sort case-insensitively, particularly using 'm' sort (Now default). [GM]
 * Combined fun_setinter, fun_setdiff and fun_setunion into fun_setmanip. [GM]
 * For hardcoders: list2arr and list2arr_ansi now take a third argument on whether to include empty items. [GM]
 * page and @mail will report to you if your recipient(s) cannot reply to you. Suggested by Paige. [GM]
 * The debug attribute flag now shows more debug info. [MG]
 * @oemit now does better object matching, can match names with spaces when enclosed in double quotes, and, when given a <room> but no matching objects, shows the message to everyone in the room, instead of noone. From a bug reported by Paige. [MG]
 * Paranoid objects now see nospoof messages for their emits. [MG]
 * ANSI is now ignored when checking the length of channel titles. Suggested by Paige. [MG]
 * @decompile with a <prefix> now shows cmds for setting attribute flags. @decompile/tf still omits cmds for attr flags. [MG]
 * @mail <msg-lists> which don't specify a folder now act on your current folder, instead of Folder 0. Suggested by Paige, patch by Minion.
 * @dig, @open and @name now set exit aliases into the @alias attribute, instead of including them in the exit name. Also, @name can now set/clear the @alias of players/exits while changing the name. See help @name for details. Suggested by Minion. [MG]
 * The logging code has been rewritten to make extending it with further log files easier. [SW]
 * When used by a non-player, @search and related functions now search from the perspective of the object's owner. Suggested by Covenent. [MG]
 * The LASTPAGED attribute now stores objids instead of names, allowing you to repage even when the target changes their name. [MG]
 * When zwho() or @chzone fail because you don't pass the @lock/zone, zone failure verbs are triggered (as per 'help failure'). Based on a patch by Covenent. [MG]
 * sub() can now take more than two arguments. Suggested by Paige. [MG]
 * In the hardcode, disconnected players in the DESC struct are shown as -1 instead of 0, to avoid conflicts with #0. Based on patch by Paige. [MG]
 * It was sometimes possible to "buy" items from yourself. [MG]

Fixes:
 * Fixing list type autodetect. [GM]
 * Help fixes by Daniel Powell, AnneLions, Minion and others. [MG]
 * Connect/disconnect messages for combined channels incorrectly showed NOSPOOF data. Reported by Sketch. [MG]
 * The delimiter between combined channel names in @chatformat is now '|' instead of ' | ', as documented. Reported by Trinsec. [MG]
 * ansi(h,) now returns absolutely nothing, instead of an ansi-highlighted nothing. Fixes a few minor/obscure bugs. [MG]
 * @edit sometimes displayed a success message even when it failed. [MG]
 * @cpattr/@mvattr would sometimes copy attribute flags, even when the attribute value couldn't be copied. [MG]
 * Bug in attribute comparisons added in p2 could cause attributes to not be found at times. [MG]
 * sortby()s results would sometimes be reversed by mistake. [GM]
 * Minor bugfix in @include. [MG]
 * round() sometimes returned numbers with more decimal digits than desired. 
 * The '*' option in locate() didn't actually include all match types. [MG]
 * @include incorrectly refunded the queue_cost, giving people free pennies. Reported by Covenent. [MG]
 * lnum() didn't handle negative <step>s well. Reported by Minion. [MG]
 * comp()s results was sometimes negated. Reported by Covenent. [MG]

& 1.8.4p2
Version 1.8.4 patchlevel 2                                 Dec 06,  2010

Major Changes:
 * Wildcard matcher completely rewritten to avoid hangs and to provide ansi-aware capturing. [GM]
 * connection_fail_limit now lets you limit the # of connection fails in a 10 minute time by any given IP. [GM]

Minor Changes:
 * update-cnf.pl perl script now handles optional config lines, by placing A # OPTIONAL above them. This is for message translation. [GM]
 * Config options can now be marked as optional. If they don't exist, Penn will not complain in the log. [MG]
 * Player names with spaces no longer need to be in given in quotes for @name. Suggested by Minion. [MG]
 * @decompile no longer shows flags which can't be set by players, like GOING and CONNECTED. [MG]
 * %il substitution as preparation to get rid of ##. [GM]
 * hardcode: call_attrib is now a wrapper around call_ufun. [GM]
 * The %i<n> substitution, and itext()/inum()/ilev() functions, now work for @dolist as well as iter(). [MG]
 * iter() context (itext(), inum(), etc) is no longer propagated through ufuns. [MG]
 * @hook/overrides on huh_command are now matched against "huh_command" and "huh_command <input>". From a suggestion by Mercutio. [MG]
 * Various help fixes.
 * @list and list() can now show only built-in or only local commands or functions. Suggested by Trelane@M*U*S*H. [MG]
 * Mortals can now use @search to find any objects they can examine. Suggested by Paige. [MG]
 * @function names can start with numbers again. Requested by Mercutio. [MG]
 * @include and @break now work when entered directly from a client. [MG]
 * The Drop and Give @locks now trigger verb <name>_LOCK`FAILURE attributes when you fail to pass them, as described in 'help failure'. Suggested by Cas@BeforeTheDarkness. [MG]
 * Set several attributes used internally AF_NOCOPY so they won't be included in @decompile output. Suggested by Paige. [GM]
 * The help for the chat system (@channel) has been rewritten. [MG]
 * autodetect_list now returns 'm' sort for unknown list types instead of alphanum, so sorting on strings will now treat numbers in them as separate comparisons by default. [GM]
 * setunion(), setdiff(), setinter() now autodetect lists in all cases where no sort type is provided instead of just some cases. [GM]
 * The pipe (|) character is no longer valid in channel names. [MG]

Functions:
 * ibreak(), for breaking out of an iter() loop. [Rhost] [MG]
 * New stext() function and %$N sub, equivilent of #$ in @switch, switch*(), and reswitch*(), but can be used in nested switches/on user input. [MG]
 * New slev() function, returns the current nesting depth of switches. [MG]
 * maillist() returns a list of @mail messages matching a range, as per @mail/list. Suggested by AnneLions. [MG]
 * New sorttype, lattr, sorts a list of attribute names. [MG]

Commands:
 * @channel/combine and @channel/uncombine let you combine spammy connect messages for channels into one line. [SW] [GM]
 * @grep now accepts /wild and /regexp switches, for wildcard/globbing and regular expression greps (a la wildgrep() and regrep()). Also /nocase for case-insensitive greps. Suggested by Paige. [MG]
 * @attribute now allows limiting attribute values through /enum and /limit switches. [GM]
 * @ps <pid> shows info for a single queue entry. Suggested by Paige. [MG]
   
Fixes:
 * Off-by-one bug in 'm' sort when using embedded numbers fixed. [GM]
 * Debug output was sometimes sent to the wrong executor. [GM]
 * A crashbug in @search was fixed. Reported by Paige. [GM]
 * A crashbug in lpids() was fixed. Reported by Mercutio. Fixed by Javelin.
 * @search elock class failed to report invalid lock strings. Fixed. [GM]
 * @cpattr and @mvattr could break attribute trees. Reported by Sketch. [MG]
 * benchmark() calculated the average incorrectly. Reported by Cheetah. [DC]
 * map(), iter(), mix() and step() are ansi-aware, now. Using any of the list functions without ansi should also be considerably faster. [GM]
 * "look <container>'s <object>" incorrectly stopped working in p1 when <object>'s desc was set "nearby". Reported by Yuriko@M*U*SH. [MG]
 * Attribute names are now sorted better with regard to attribute trees, hopefully fixing the recurring bug of @wipe leaving branch attributes when removing a root attr for good. [MG]

& 1.8.4p1
Version 1.8.4 patchlevel 1                                 Sep 05,  2010

Major Changes:
 * You can now do the equivilent of @command/add, @hook, @function and @attribute/access from alias.cnf and restrict.cnf, to add/configure commands, functions and standard attributes. Suggested by Paige. [MG]
 * Exits now use @alias for alternate names. The old style of including aliases directly in names is still supported, but deprecated in new construction. Suggested by [MG]. [SW]

Minor Changes:
 * @power now reports when you try and set a power which is already set (or clear one which isn't set), similar to @set. Suggested by Paige. [MG]
 * Sorting methods now take - as a prefix to sort type in order to sort in descending order. Suggested by Minion. [GM]
 * The matching code no longer matches players who aren't nearby with "*playername" when MAT_NEAR is given, more in line with other checks. (This has virtually no impact for most players.) [MG]
 * The internal pe_info (which manages the function invocation limit, among other things) is now managed per-queue, not per-command argument. [MG]
 * @chan/decompile now uses "*name" for players, and dbrefs for other objects, when printing "@chan/on" statements. [MG]
 * cpu_limit now works on Cygwin (though not quite as well as on unix). A slightly higher limit may be needed than other platforms. [MG]
 * The output from say, pose, semipose and @emit is now passed through the SPEECHMOD attribute before being outputted. Suggested by Paige, based on MUX and TinyMUSH. [MG]
 * @config/list now accepts wildcard patterns to match against option names. Suggested by Trinsec. [MG]
 * The dreaded <Output flushed> message should show up a lot less frequently on spammy debug output and the like. By popular demand. [SW]
 * Added support for MSSP (Mud Server Status Protocol), based on patches by Javelin and Teal. See mush.cnf for details. [MG]
 * The script for updating config files is smarter about adding new alias lines. [SW]
 * @search now only charges for elock searches which use eval or indirect locks.
 * Added @mail/unread, to mark mail you've already read as new, and @mail/status to change read/cleared/tagged status for messages. Suggested by qa'toq. [MG]

Commands:
 * Add /preserve switch to @chzone and @chzoneall, like @chown/preserve.
 * Rooms/exits must now have an @COST attribute in order to be given pennies. Use @cost <ancestor>=%0 to enable giving to all rooms/exits. [MG]
 * with/room can now check for commands in the Master Room or your ZMR, and with can check for commands on your ZMT. [MG]
 * @sitelock/register <host> now sets the access rules for <host> to be "!create register", rather than "!create". Suggested by Trinsec. [MG]
   
Functions:
 * remit() now works like @remit/list. Suggested by Minion. [MG]
 * rand() now accepts negative arguments again. [MG]
 * lcon() can now take a second argument to make it behave like lthings() or l[v]players(), or makes it return only puppets/listening objects, for MUX/Rhost compatability. Suggested by Bane. [MG]
 * open() can now open rooms remotely. Suggested by Minion. [MG]
 * reswitch() and co now perform $-replacements for subexpressions. [MG]

Fixes:
 * Help fixes.
 * @search's output can now include garbage objects, like lsearch(). Reported by Minion. [MG]
 * The command parser incorrectly expanded the names of disabled built-in commands prior to $-command matching. Reported by Mercutio. [MG]
 * benchmark()'s average would be thrown off when the CPU limit was exceeded during evaluation. Reported by Amberyl. [MG]
 * Fix a few bugs in handling of command locks. [SW]
 * Garbage objects could be matched by dbref. Reported by Paige. [MG]
 * No longer complain about reboot.db not being present when we're not doing a @shutdown/reboot anyway. Reported by Paige. [MG]
 * The Telnet escape code was not properly escaped when sent literally to Pueblo-aware clients. [MG]
 * namelist() did not accept names in quotes. Reported by Amberyl. [MG]
 * @attrib/access/retroactive could remove the 'root' flag from attribute trees, making nasty things happen. Reported by Cooee. [MG]
 * Fix fn() to check that the first arugment is actually the name of a built-in function. Reported by Time and Cheetah. [DC]
 * Nested @asserts/@breaks with no '=' would loop unintentionally. Reported by Minion. [MG]
 * Fixed a couple of small bugs in give/@cost. [MG]
 * You can now always look at remote objects whose descs are not set nearby, and can never look at remote objects with nearby descs. [MG]
 * The chatdb didn't load correctly with invalid objects on channels. [MG]
 * Fixed a crashbug in @boot on Windows. Reported by Daniel Powell. [MG]
 * %q-registers did not carry over into @includes correctly. Reported by Reaver. [MG]
 * Double-free in follow command fixed. Reported by Anya@ST:DW. [MG]
 * locate() sometimes returned #-2 when two objects matched, even if only one of them was the preferred type. Reported by Minion. [MG]


& 1.8.4p0
Version 1.8.4 patchlevel 0                                 May 09,  2010

Major Changes:
 * Commands can now be restricted with an @lock-style lock in restrict.cnf and @command/restrict, allowing more complex restrictions. [MG]

Minor Changes:
 * @shutdown/reboot logs who was responsible. Suggested by Kitai. [SW]
 * Rewrite of help @lock to improve clarity, by Sketch.
 * New NO_LOG flag to disable command logging on a per-object basis. Based on code by Teal. [SW]
 * mindb+maxdb classes for lsearch/@search no longer reset to default values when > db_top or < 0 is given: Instead treated as an integer comparison. [GM]
 * @open can now open exits in remote locations, as well as your current location. Suggested by Bane. [MG]
 * New OPEN_OK flag allows anyone to open exits in a room, and @lock/open to restrict who can. Based on patch by ranmir@M*U*S*H. [MG]
 * Master Room exits and ZMR exits now run the "goto" command, and @ealias and @lalias run the "enter"/"leave" commands, so @hooks get run, command restrictions checked, etc. [MG]
 * New @lock/from and @lock/receive locks, to control who can give to an object, and what objects can be given to them, respectively. From a suggestion by Nammyung@M*U*S*H, based on locks on ElendorMUSH. [MG]
 * Changed the restrictions for valid @function names to match what was reported by valid(). [MG]

Commands:
 * New @include <obj>/<attr> command, which inserts <attr> into the current action list. Patch by Javelin.
 * @scan can now take multiple switches at the same time. [MG]
 * @version now reports the SVN revision of the current version, when available. Suggested by Paige. [MG]
 * @clone can take a garbage dbref for the new object, the same as @create. Suggested by Dan. [MG]
 * 'look' now supports more english-matching (look this foo's 1st bar). [MG]
 * You can now look at objects on the other side of transparent exits, with "look [toward] <exit>'s <object>". Suggested by Trinsec. [MG]
 * All wizards can now use @command/add. Suggested by qa'toq. [MG]
 * function_alias in alias.cnf now creates a proper alias, not a clone, of functions. @function/alias added, which does the same in-game. [MG]
 * New @command/clone and @function/clone commands, which create copies of a command/function which initially work the same as, but are independant of, the originals. Based on suggestion by Bane. [MG]
 * Added a comment line to the beginning of @decompile's output showing the object name and dbref. [MG]
   
Functions:
 * Added strfirstof() and strallof(), which return the first arg/all args which are non-empty strings. [MG]
 * Added reglattr[p](), regxattr[p]() and regnattr[p](), regexp variants of lattr[p](), xattr[p]() and nattr[p](). Suggested by Trinsec. [MG]
 * The *emit() functions, and cbufferadd(), are now disabled when function_side_effects are off. Suggested by Cheetah. [MG]
 * round() now takes an optional third argument to 0-pad the results if needed. Suggested by Trinsec. [SW]
 * Many functions (particularly ones which take only numbers, dbrefs or attribute names as arguments) now ignore ANSI in their arguments, rather than throwing an error. [MG]
 * nattr()'s <attribute pattern> now defaults to *, not **, the same as lattr() and other attribute functions. [MG]
 * clone() can now take a <new name> and <dbref>, as per @clone. [MG]
 * cwho() now takes an optional 3rd argument to omit gagged objects. Suggested by Trinsec. [MG]

Attributes:
 * @outpageformat lets you alter how you view pages that you send.

Fixes:
 * isprint() bug in ord() fixed. [GM]
 * Possible crashbug in @destroy fixed. Reported by Dan. [MG]
 * Minor bug in benchmark() fixed. [MG]
 * channels(<object>) was incorrectly sorted for channel names containing ansi. Reported by Trelane. [MG]
 * Help fixes by Teal and others. [MG]
 * Minor updates to some README files. [MG]
 * Some typos and translation errors fixed by Stoko.
 * namelist() now ignores null items. Reported by Minion. [MG]
 * The matching code would always perform absolute (dbref) matches, even when it wasn't told to. [MG]
 * Improvements to the match flags used by many pieces of code, hopefully fixing a number of minor bugs. [MG]
 * Paranoid dumps no longer treat ANSI tags as invalid characters in attrs. Reported by Trelane. [MG]
 * The /silent switch for @lemit didn't work. [MG]
 * @decompile/db showed '@create <dbref>' for THINGs, not '@create <name>', and @decomp/name could break. Reported by Paige. [MG]
 * Crash bug in locks fixed. Reported by Tanaku. [SW]

& 1.8.5p7
Version 1.8.5 patchlevel 7                                 Mar 16, 2015

Fixes:
 * Bytes received by connections weren't being properly recorded for things like SESSION and recv().
 * Fix some highly unlikely crash bugs/memory leaks in atr_tab.c [MG]
 * @attribute/delete now deletes all aliases for the deleted attr, too. [MG]
 * Help fixes. [MG]
 * SOCKSET didn't always send the corret lineendings. [MG]
 * unsetq() and @include/clearregs were unpredictable, and hopefully now function more reliably. Reported by spork, Mercutio and others. [MG]
 * Remove compile warning when info_slave isn't used. [MG]
 * %X now always returns the capitalized version of %x, even when the returned value contains ANSI. [MG]
 * Fixed a few niggly bugs in @include, registers() and similar things making too many or too few registers available at the wrong time. From a report by Paige. [MG]
 * lit(%) returned %) instead of %. Reported by Ashen-Shugar. [MG]
 * PCRE's jit engine causes crashes when passed certain malicious regular expressions. Disable it for all public-facing uses of REs. Reported by Ashen-Shugar. [SW]
 * align() would sometimes show extra column separators when columns were merged. [MG]
 * @lock/interact was wrongly checked when paging a player with an @pageformat set. Reported by Odin. [MG]
 * Channels you had both @chan/gagged and @chan/combined would still show connect messages. Reported by Paige. [MG]
 * Fix a memory leak in @dolist/inline when used with @break. From a report by spork. [MG]
 * @chan/decompile <hidden channel> by a mortal didn't give an error message. Reported by Paige. [MG]
 * It was impossible to remove a thing from a channel which had been restricted so only players could join. Reported by Paige. [MG]
 * Players with an @pageformat which eval'd to an empty string wouldn't know they were being paged. Reported by Ashen-Shugar. [MG]
 * Fix crash in named q-registers. Reported by Qon@M*U*S*H. [DC]
 * Enabling the log_commands config option while a LOG`CMD event was set would cause endless queueing, until the event handler was halted as a runaway object. Reported by spork. [MG]
 * Fix a potential overflow problem in the code that computes queue load averages for @ps. [SW]
 * @motd/down and @motd/full are actually shown now. [MG]
 * Properly negotiate telnet with clients who spit out telnet codes instantly upon connection like MUSHclient. Reported by Mercutio and AND. [MG]
 * Improved configure support for NetBSD. [SW]
 * Fix a compile error on non-Windows, non-BSD, non-Linux OSes. [SW]

Hardcode:
 * Improvements to networking code; robustness on errors and portability. [SW] 

Functions:
 * Added two new column modifiers to wrap(), x and X, to allow truncation of fields instead of wrapping. Suggested by Qon, spork and others. [MG]

Minor changes:
 * @attribute/delete now displays the info for an attribute, as per @attrib <attr>, prior to deleting it. [MG]
 * The *div*() and *mod*() math functions now take an unlimited number of args, instead of exactly 2 args. Suggested by Mercutio, patch by Luke.
 * A SUSPECT player changing their name to the same thing doesn't trigger an alert. Suggested by Rince. [SW]
 * valid(attrvalue, <value>, <name>) checks if &<name> obj=<value> is valid. For @attrib/enum and /limit. [MG]
 * Added @flag/decompile and @attribute/decompile, to decompile each table to copy to another game. Suggested by spork. [MG]  
 * Newly set player passwords are salted to be more resistant to cracking via rainbow tables by somebody with a copy of the database. You still shouldn't be re-using a password for anything important, of course. Existing passwords aren't automatically updated. [SW]
 * Added /clearregs to @trigger. Suggested by Volund. [MG]
 * @motd with no args now acts like @motd/list, instead of clearing the MotD. Use @motd/clear to clear the current one. Suggested by Bodin. [MG]
 * @command can now be used by non-players. From a gripe of Kitai's. [MG]
 * Update some configure macros to the latest versions. [SW]

& 1.8.5p6
Version 1.8.5 patchlevel 6                                 Jul 29, 2014

Hardcode:
 * Removed an old debugging variable to reduce memory usage. Suggested by spork. [MG]
 * ssl_slave now gets passed its settings via a pipe, instead of on the command line. [SW]
 * Rewritten the telnet handler, to make it more manageable/modifiable, instead of it being a huge bunch of nested switch()es. [MG]
 * Update the SFMT random number generator to 1.4.1. [SW]
 * Built in and persistant uses of regular expressions are JIT compiled if the host's PCRE version supports it, for faster matching.
 * Better support for BSD systems. 

Functions:
 * valid() can now test for valid channel names. Suggested by Volund. [MG]
 * valid() now takes an optional <target> argument for some categories, to see if <string> is a valid name for <target>. [MG]
 * tan(90,d) now reports an error instead of a really big number. Suggested by Peppel. [SW]
 * More math functions report errors. [SW]
 * Added reglmatch[all][i]() functions, regexp versions of match[all](). [MG]
 * isdaylight() now accepts time and timezone arguments. [SW]
 * convtime() takes timezones besides just UTC. [SW]
 * foreach() is now ansi-aware. Reported by Ashen-Shugar. [MG]

Minor changes:
 * @channel/gag no longer persists across a full @shutdown. Suggested by Trinsec. [MG]
 * 'give' now gives more informative error messages when you try and give pennies to someone who has the maximum, or take pennies from someone who is broke. [MG]
 * The message shown when you need to run 'make update' is now slightly clearer about what to do and why. By Rince.
 * Removed some 20 year old Sun OS workaround code. Suggested by Fraibert.
 * Slightly less confusing error message for @chan/buffer suggested by Sketch.
 * 'HELP ENTRIES' is generated on the fly, and shows the total number of pages. Suggested by [MG] and Trinsec. [SW]
 * @success/@osuccess/@asuccess now get the old location of the moving object in %0. Suggested by Riorgan. [SW]
 * @mail/review with no args now lists all mail you've sent to everyone. Suggested by Paige. [MG]
 * @mail/review now shows the recipient in the message list, instead of the sender. This is slightly more useful, since the person using the command is always the sender. [MG]
 * @mail/status now lets you twiddle the 'urgent' status of messages. From a suggestion by Paige. [MG]
 * You can now always see a channel if you've been joined to it and can speak on it, even if you don't pass its @clock/see. Suggested by Rince. [MG]
 * 'page foo=' now produces an error, instead of paging nothing. Suggested by Paige. [MG]
 * 'make localized' now ignores charset when building translation files, which stops it throwing errors unnecessarily. [MG]
 * Use a more robust configure check for timezone data files. [SW]
 * Added a /spoof switch to @mapsql, to spoof the enactor a la @trigger/spoof. Suggested by Mercutio. [MG]
 * Improved error reporting when info_slave or ssl_slave exits unexpectedly. [SW]
 * hasflag(<player>, connected) now returns 1 if the caller can see that the player is online, instead of always returning 0 for mortal callers. Most recently suggested by Odin@M*U*S*H. [MG]

Fixes:
 * Windows compile fixes by ChaosMageX.
 * Fix a crash when expanding the flagset size. Reported by spork. [DC]
 * @attribute/access incorrectly cleared an @attribute/limit on the same attr. Reported by Ton Kyrion. [MG]
 * Help/translation fixes by spork, Riorgan and others. [MG]
 * The 'give', 'take' and 'empty' commands displayed the wrong object names when mogrifiers were used. Reported by Riorgan. [MG]
 * Fix crash in ssl_slave when a connection drops in the middle of hostname lookup.
 * Crashbug in SQL fixed. Reported by Mercutio. [MG]
 * @mapsql/colnames cleared q-registers in the first (colnames) action list queued. Reported by Mercutio. [MG]
 * @channel/join would give an 'ambiguous' error, even if you couldn't see the other potentially-matching channels. Reported by Mercutio. [MG]
 * Penn negotiated charset as iso-8859-1 (latin1) even if the MUSH was running using a different charset. Reported by Tyler. [MG]
 * Better support for mixing IPv4 and IPv6 connections. FreeBSD and NetBSD should not need the --disable-ipv6 option to configure any more. [SW]
 * Fixed an obscure buffer-overwrite bug in the channel system. Reported by Volund@M*U*S*H/Roll@Multiverse Crisis MUSH. [MG]

& 1.8.5p5
Version 1.8.5 patchlevel 5                                 Nov 20, 2013

Commands:
 * Added @moniker, to allow colored names. See 'help monikers' for more. Requested by Mikoto Misaka. Idea from [MUX]. [MG]
 * After a year of deprecation, @emit/room has been removed as an alias for @lemit. [MG]
 * @chan/list now takes /on and /off switches, to filter the channels shown, and a /quiet switch to give a less verbose output. From a suggestion by Fraibert. [MG]
 * @trigger now takes a /spoof switch, which preserves the enactor. [MG]
 * New @hook/extend, which allows adding new functionality to built-in commands via softcode, while preserving the original command. [MG] [Rhost]

Major changes:
 * Regexp $-commands can now used name captures. They can be accessed via r(<name>, args). Suggested by Mercutio. [MG]

Hardcode:
 * A number of changes have been made to accomodate monikers. Notably, a lot of calls to the Name() macro now use the AName() macro. See the HACKING.185 file for more info. [MG]
 * wild_match_case_r(), regexp_match_case_r(), pe_regs_set_rx_context() and pe_regs_set_rx_context_ansi() now take an extra argument, a PE_REGS* flag to determine how matching subpatterns are stored in pe_regs. [MG]
 * add_flag_generic() now returns an enum, and takes an additional final pointer arg, where the new flag will be stored. add_flag() and add_power() pass this pointer as NULL. [MG]
 * Improve heuristics used for resizing the flagcache hash table. [DC]
 * Update hashing functions used by various hash table implementations. [DC]

Fixes:
 * Commands which take multiple right-hand-side arguments could only have 8191-length arguments, instead of the usual 8192. Reported by Jules. [MG]
 * It was possible to return non-printable characters from an SQL database, which could cause undefined weirdness. Reported by spork. [MG]
 * Many things which listed attributes from a parent, like lattrp() or examine/parent, didn't respect no_inherit fully. [MG]
 * Minor crashbug in @boot fixed. Reported by thomaswdyoung. [MG]
 * @grep now ignores ansi when looking for a value. Suggested by Mouvar. [MG]
 * colors() now complains when the color is 'n', 'd' or 'D', since they have no actual color value. Reported by spork. [MG]
 * Buffer overflow bug in ansi() fixed. Reported by tsen. [MG]
 * Flag corruption issue due to incorrect flagset refcounts fixed. [DC]
 * When a player was nuked, any @mail they had filed into another folder would be retained, and visible to a new player created later with the same dbref. Reported by Valkyrie. [MG]
 * Crashbug in @message. Reported by Yuriko. [MG]
 * linsert(,1,foo) now returns "foo", like it always used to, instead of returning an empty list. [MG]
 * SSL connections which had not yet logged into a player weren't always fully cleaned up. Patch by Fraibert.
 * channels() could include an extra delimiter in some cases. Reported by Mouvar. [MG]
 * Translations weren't working in the chat system. Reported by Riorgan. [MG]

Minor changes:
 * strreplace() now works harder to keep existing ANSI intact, when you replace an un-ansi'd string into an ansi'd one. [MG]
 * colors(...,xterm256) can now return colors 0 to 15, to avoid confusion when converting xterm -> hex -> xterm. Reported by Trinsec. [MG]
 * New substitution, %k, returns the enactor's monikered name. [MUX] [MG]
 * Help fixes and tweaks. [MG]
 * PennMUSH can now read MUX-style passwords, to make moving dbs from MUX to Penn less painful. Requested by Muse. [MG]
 * Commands are no longer queued for HALTed non-players. (Since they'd be dropped from the queue anyway, rather than being run, it saves us jumping through a series of hoops for no good reason.) From a report by Muse and Ashen-Shugar. [MG]
 * The connect-screen WHO now shows moniker'd (ansi'd) names, if so configured. Requested by Trinsec. [MG]
 * @mapsql and mapsql()'s attributes now receives named arguments. That is, '@mapsql me/foo=SELECT bar FROM table' receives the value of the 'bar' field as both %1 and [r(bar,args)]. [MG]
 * Wizards can now give players names with spaces, even when the player_name_spaces option is off. Suggested by Paige. [MG]
 * Removed the last traces of the 'events' help-style command. Noone ever uses it, and we removed the helpfiles for it ages ago when the Event System was added, anyway. [MG]
 * Updated the README for adding help-style commands, with clearer examples. Requested by AnnePearn. [MG]
 * Per-player mail limits can be set with @mailquota, to override the mail_limit @config option selectively. Suggested by Ricochet. [MG]
 * Attempting to create a character (at the login screen or via @pcreate) is now specific about whether the name is already in use or invalid, rather than leaving you guessing. [MG]
 * Likewise, when failing to connect, the login screen tells you whether there is no such player, or whether the password is wrong. [MG]
 * beep() now returns out of range, instead of permission denied, when given an arg which is not between 1 and 5. [MG]
 * When an evaluation @search hits the CPU limit, it will now tell you which object it failed on, to make it easier for you to continue with a partial search. [MG]
 * Players are now warned when setting an unanchored regexp $-command, as this is often an oversight which is problematic to track down later. [MG]
 * More effort now goes into checking whether an attribute contains a valid $-command when it's set, to avoid doing so unnecessarily during command matching; the latter happens a lot more often. [MG]
   
Functions:
 * delete(), replace() and insert() have been renamed to strdelete(), lreplace() and linsert(), respectively, for clarity and conformity. The original names remain as aliases. [MG]
 * moniker(<object>) returns an object's monikered name. [MUX] [MG]
 * mapsql() only stored 10 columns, instead of the advertised 30. Reported by Mercutio. [MG]
 * fn() now takes an <obj>/ prefix to its first arg, to evaluate the built-in function as <obj>. Useful when overriding side-effect functions. [MG]
 * r() now takes two arguments, allowing it to return the stack (%0-%9), itext() and stext() values, as well as q-registers(). [MG]
 * Mortals can now use playermem() and objmem() on their own objects. Suggested by Paige. [MG]
 * ljust() and rjust() now take an optional <trunc?> arg which, if true, causes strings already longer than <len> to be truncated. Suggested by many people over the years, most recently Rince and Quasar. [MG]

& 1.8.5p4
Version 1.8.5 patchlevel 4                                 Mar 17, 2013

Major changes:
 * The player_name_len @config option is now the maximum length of a player name, instead of the maximum length+1, because doing it that way was rather silly. You may wish to lower yours by 1 now to compensate. Suggested by Mercutio. [MG]
 * Having unescaped commas in the final arg of a function call is now deprecated, and will eventually become illegal. Any existing code which does this will spam you with a warning until you change it. [MG]
 * The stack (%0-%9) can now hold up to 30 arguments, with the additional 20 available through v(10) to v(29). $-commands, @functions and many built-in commands and functions (such as ufun(), @mapsql, etc) now make use of these args. [MG] [MUX] [Rhost]

Commands:
 * @dolist now accepts /inline and related switches, like @switch does. Suggested by Reaver. [MG]
 * @teleport/list teleports a list of objects to a single destination. Suggested by Nyssa, [MUX]. [MG]
 * @sockset and SOCKSET can now show/set PROMPT_NEWLINES. [MG]
 * @halt now takes a /noeval switch, and will always strip curly braces when run /noeval. [MG]
 * Added @mail/cstats, which shows the mail stats you see on connection. Patch by spork.
 * Added a new switch for @command/add, /rsnoparse, which stops the rightside arguments (after the '=') from being evaluated. Also clarified the help to show that /noparse only affects leftside args. Suggested by spork. [MG]
 * WHO, DOING and SESSION now take wildcard patterns for names, as well as a prefix. [MG]
 * New option for @sockset/SOCKSET, 'stripaccents', to strip accents for a single connection as per the NOACCENTS flag. [MG]

Functions:
 * lpids()' second argument has been altered slightly, to allow you to list the pids for one specific object only. Suggested by spork. [MG]
 * The "player" field in pidinfo() has been renamed to "executor", for clarity. "player" still works for backwards compatability. From a request by tsen. [MG]
 * stringsecs() can now handle the additional time periods that etime() can return (years, weeks). [MG]
 * colors(..., name) is much more efficient. [SW]
 * alias(object,) clears object's @alias. Suggested by spork. [MG]
 * v(<integer>) is no longer the same as get(me/<integer>). Instead, it always the <integer>th stack entry. [MG] [Rhost] [MUX]
 * It's now documented that replace() can alter multiple words at once. Reported by Jules. [MG]
 * Some terminfo() information can now be retrieved by mortals on other players' connections. Suggested by spork. [MG]
 * Added a new option to colors() to include ansi underline, invert and flash from the input in the output. [MG]
 * locate() takes a new flag, 's', which will only return objects controlled by the looker. Suggested by spork. [MG]
 * @@() now takes a huge number of arguments, instead of ignoring commas in the final arg, to stop it giving the 'unescaped comma' warning. Requested by everyone. [MG]
 * terminfo() now tells you whether a connection is having accents stripped, either via NOACCENTS or @sockset. [MG]

Minor changes:
 * ansi() now accepts a space-separated list of color codes, with later groups overriding earlier ones. Allows you to specify basic ANSI codes after XTERM color codes. Suggested by spork, [Rhost]. [MG]
 * Compiler warning fixed by ChaosMageX.
 * Help fixes by many, including spork, Wiggles and Bodin. [MG]
 * The tables mapping color names and RGB values are now generated by a script in utils/. [SW]
 * Converting from named colors to the nearest xterm or ansi equivalent is much more efficient. [SW]
 * Converting from extended colors to ansi colors is smarter. Based on work by Padraic. [SW]
 * Email registration no longer pretends to work with really!old!addresses. [SW]
 * Better error reporting in logs and event hooks on failed email registration. Suggested by Padriac. [SW]
 * @decompile <exit> now reports the exit's source room. Suggested by telandra2. [MG]
 * You now only need to control an object to change its zone, or to use it as a zone. Previously, ownership was required. Suggested by Cheetah. [MG]
 * The hardcode now always ANSIs a string (such as an object name or help topic), even if the enactor isn't set ANSI. Fixes puppets, etc. [MG]
 * When clients negotiate charset via telnet, US-ASCII and ASCII are now presented as options. If the client picks one of them, that connection will have accents stripped (as per the NOACCENTS flag). [MG]
 * New attribute flag, quiet, suppresses the usual confirmation message when an attribute's value or flags are changed. Suggested by Trinsec, bribed by qa'toq. [MG]

Fixes:
 * %c contained the evaluated input (the same as %u), instead of the unevaluated input. Reported by Ingwaz. [MG]
 * repeat() could write partial ANSI tags, causing buffer overflows. From a report by Ashen-Shugar. [MG]
 * dbcks didn't reset corrupt exit's source room. Patch by Padriac.
 * lmath(and,) returned 1 instead of 0. Reported by Padriac. [SW].
 * Mixing old-style ansi colors and xterm colors was broken. [MG]
 * Players who couldn't see xterm colors would sometimes get a highlighted foreground color by mistake. [MG]
 * colors(<old-style-ansi>, hex) and colors(*, 16color) were broken. Reported by Kimiko. [MG]
 * ANSI highlight would sometimes bleed when xterm colors were downgraded to the basic 16-color ANSI palette. Reported by Kimiko. [MG]
 * @entrances didn't correctly report the source of an exit. Reported by spork. [MG]
 * Fix a crashbug in @command/delete. [MG]
 * Fix database corruption on @flag/add [SW]
 * Attempting to @mail someone without permission failed silently. Reported by Kimiko. [MG]
 * Players connecting dark with 'cd' were hidden even if they shouldn't have been. Patch by thomaswdyoung.
 * Fixed a bug in colors(*,16color) with no ansi. [MG]
 
Hardcode:
 * The Builder() macro, which is unused in Penn but exists for backwards compatability, used command_check_byname(), which spammed people who could not build with "Permission denied." errors. It is now spam-free. By spork.

& 1.8.5p3
Version 1.8.5 patchlevel 3                                 Aug 23, 2012

Fixes:
 * Fix a crash bug in new color code. Discovered by ChaosMageX, fixed by Intrevis and [SW].

Functions:
 * name() with no arguments is now an error. It should always have been, but previously returned nothing for backwards compatability. If you still have code that relies on that behaviour, you are extremely lazy and should be ashamed of yourself. [MG]

& 1.8.5p2
Version 1.8.5 patchlevel 2                                 Aug 18, 2012

Hardcode:
 * render_string has been modified to work with multiple output formatters, so it can display the appropriate color syntax for the client. [GM]
 * Tweak the networking code to try to reduce output latency/queue size. [SW]

Major changes:
 * 256 Color support. Using 24 bit internally for representation and downscaling to the client's possible output values. Use SOCKSET colorstyle=xterm256 to see 256 color support, with ansi(+colorname/+colorname,...) or ansi(#hexcode/#hexcode) for extended color support, or @set me=xterm256. [GM] [MG]
 * New SOCKSET socket command for changing socket options. Replaces the @sockset command added in p1 for mortals, and can be used at the login screen. Suggested by Sketch. [MG]
 * @sockset is now @sockset <desc>[=<opt>,<value>[,...]], to query current options or set options for any descriptor. [MG]
 * The old @doing command has now been removed, and replaced with the normal standard-attribute command (@doing <object>[=<message>]). [MG]

Commands:
 * look now takes an /opaque switch, which hides contents listings. Suggested by Wiggles. [MG]
 * @break and @assert now take a /queued switch, which causes the new <action list> to be queued instead of run immediately, and an /inline switch which gives default behaviour. For Rhost compatability. [MG]
 * Two completely separate, but equally stupid, bugs made @nsprompt show nospoof info just like @prompt. [MG]
 * @open, open(), @dig, dig() accept specific garbage dbrefs to use for the exits they make. [SW]

Functions:
 * colors() returns a list of all known color names known by PennMUSH, and info about a particular color. [GM]
 * valid() has two new categories, for validating color names and color code sequences for ansi(). [MG]
 * etime() formats elapsed times using the same rules as in WHO. [SW]

Minor changes:
 * The meaning of the COLOR flag has been restored. ANSI flag once again means only highlight is supported, while COLOR means all ANSI 8 colors (8*2 including highlight), flash, invert, etc are supported. [GM]
 * Charset negotiation didn't work on MSVC, and now forces iso-8859-1 when compiled that way instead. Reported by Daniel Powell. [MG]
 * @config/set and @config/save now log to the wizard_log. Suggested by Israphel. [MG]
 * The ICLOC attribute, which was set on newly created players but never used in any way, is no longer set. Suggested by Paige. [MG]
 * @destroy'ing, @undestroy'ing, and the actual destruction of players is now logged. Suggested by Padraic. [MG]
 * Translation fixes by Stoko.
 * round(4.5,0) behaved differently on Penn than it did on MUX, and inconsistantly with rounding to more places on Penn. [SW]
 * The 'On for' and 'Idle' time fields in WHO are smarter and won't overflow their space. Suggested by Ari and Paige. [SW]
 * Add a few new test cases. Requested by Sketch. [MG]
 * It's now possible to clear/reset a prompt with @prompt <player>. [MG]
 * New Pick_Dbref @power for specifying specific garbage dbrefs to use in @create and friends. [SW]

Fixes:
 * Reordered some checks in tz.c to compile on more distributions. Problem reported by Zen@M*U*SH. [MG]
 * Setting an exit Transparent didn't cause its destination's desc to get shown as it should have. [MG]
 * It became impossible in p1 to give a delimiter to wrap() without also specifying a first line width. wrap(%0,%1,,%2) will now use the normal <width> arg for first line width, the same as wrap(%0,%1) does. Reported by Kitai. [MG]
 * Free PCRE-allocated memory with pcre_free() instead of free(). Reported by ChaosMageX@M*U*S*H. [DC]            
 * Fix some potential memory leaks in timezone file reading code. [SW]
 * Off-by-one error in the helpfile index code. [MG]
 * Improve docmentation of ip_addr config option. [SW]
 * Fix an edge case in ansi_string_replace that could cause an overflow. Reported by Ton Kyrion@M*U*S*H. [DC]
 * Fix a memory leak in LOGOUT. [SW]

& 1.8.5p1
Version 1.8.5 patchlevel 1                                 May 15, 2012

Hardcode:
 * The local_data_clone() function now receives an additional argument, which specifies whether @clone/preserve was used. You'll need to either update the definition of local_data_clone in src/local.c from the one in src/local.dst or, if you've made no changes to src/local.c, just remove src/local.c and it'll be rebuilt automatically. [MG]
 * The orator variable (defined in game.c), for tracking the last object which made sound, has been deprecated, and may soon be removed; don't use it. Just pass the correct dbrefs to the notify*() functions if something talks. [MG]
 * Several of the notify_*() family of functions, and the do_*emit() functions now take an extra arg, for properly tracking both the executor and the speaker when spoofing (@pemit/spoof, etc). [MG]

Deprecation:
 * @emit/room and @doing/header have been deprecated. Use @lemit and @poll, respectively, instead. [MG]

Major changes:
 * Built-in attributes are now stored in the database. This means that @attribute no longer needs to be in an @startup, as it will persist across reboots and shutdowns. The attribute_alias option in .cnf files is now deprecated as a result. [MG]
 * The database now uses a new versioning scheme (alongside the old one, for backwards compatability), using incrementing integers instead of bitwise flags. Ideas by [GM] and Covenent. [MG]

Minor changes:
 * Logged messages now have events in the LOG tree. Suggested by Padraic. [SW]
 * Objects belonging to destroyed players now get chowned to a configurable player (probate_judge in mush.cnf) instead of God. [SW]
 * Commands involving movement now check the enactor is a player/thing, instead of just relying on the command's restriction. [MG]
 * @switch, switch(), @[in]filter and attribute @locks (foo:bar) now do lte/gte wildcard matches on <=foo and >=foo patterns. Inspired by Wiggles. [MG]
 * New channel mogrifier, MOGRIFY`NOBUFFER, can be used to exclude certain @chats from the channel's recall buffer. Suggested by Wiggles. [MG]
 * Nospoof players now see the nospoof header on @cemits, making @nscemit actually have some use. Report by rimnar@M*U*S*H. [MG]
 * The login screen WHO can now be overridden using the who_file config option, which can be set as the path to a textfile or an obj/attr, like connect_file et al. From suggestions by Paige, Trelane and Mercutio. [MG]
 * Talek's chunk attribute storage system, which pages attribute contents to and from disk as needed, is now optional by popular request. Controlled via options.h [SW]
 * New lock, @lock/dropin, controls who can drop objects into that location. [SW]
 * @ps now shows a running average of the number of queue entries executed per second. [SW]
 * Try to discriminate between ssl_slave and other sources of connections to the local unix socket. [SW]
 * Repeating the PUEBOCLIENT socket command now causes PennMUSH to re-send the 'start parsing HTML' codes, for when Pueblo-enabled clients hiccough and show raw HTML. [MG]
 * The DESTINATION attribute for variable exits now receives the exit name/alias typed by the player as %0 when moving, to allow different destinations based on the exit alias used to move. It also has access to %c, %u, and other %-subs available when moving, Suggested by Javelin and [GM]. [MG]
 * Translation updates and messages fixes by Stoko.
 * Help fixes by Todd@M*U*S*H, Steve Varley, Wiggles and others. [MG]
 * @message now takes a /silent and /noisy switch, the same as @pemit, with the default controlled by the silent_pemit @config option. message() is now silent, like pemit(). Suggested by Padraic. [MG]
 * The MUSH can now negotiate its character set with clients. There's still only one charset available, but now the client can know exactly what it's receiving. Suggested by Sketch. [MG] Make sure your MUSH is running in the right charset; see http://tinyurl.com/penn-charset for more information.
 * Additional test suite tests for setunion/setdiff/setinter() by Sketch.

Fixes:
 * When regexp matching an ansi'd string, named captures weren't set at all. For non-ansi'd strings, non-named (numeric) captures were sometimes overwritten with the values of named captures. Reported by Sketch. [MG]
 * The configure script incorrectly reported that ssl_slave was unavailable when told to disable it via --disable-ssl_slave. Reported by Cheetah. [MG]
 * Sound from an AUDIBLE wagon object used to propagate into other wagon objects in the same location with an @listen of *. It now does so again.  Reported by Xeero and Padraic. [MG]
 * Sound will now also propagate through two @listens, instead of just one, as it used to. Reported by Mac@M*U*S*H. [MG]
 * Loading a reboot db is more robust. Inspired by Padraic. [SW]
 * scan() couldn't be used by rooms. Reported by Padraic. [MG]
 * Possible crashbug in the queue triggered by events reported by Rince@Wing Commander: New Horizon. [MG]
 * @list attribute would show duplicates for aliases. [MG]
 * insert(,foo,-1) no longer appends an extra delimiter. [MG]
 * @function/clone didn't work correctly, and could potentially cause a crash. [MG]
 * @clone didn't respect Many_Attribs. [MG]
 * Making a connection to a ssl port on a game not using ssl_slave could hang the mush. Reported by Minion. [SW]
 * @cemit and friends would notify you twice if you cemited to a channel you weren't on. Reported by spork. [MG]
 * regrep() could try to read uninitialized memory. [SW]
 * Fix a possible DOS from a local attacker. [SW]
 * Fix a couple of possible memory leaks. [MG]
 * ordinal(12) now returns twelfth, not twelveth. Patch by Minion.
 * trunc() now ignores ANSI. Reported by Sketch. [MG]
 * Evaluation @locks didn't receive %0-%9 args, even when they should. Reported by Zen@M*U*S*H. [MG]
 * @message/spoof now tracks both the object using @message and the object being spoofed, allowing for more accurate priv checks when evaluating the format messages. Reported by Mercutio. [MG]
 * When spoofing (@pemit/spoof, etc), any errors for failed locks or bad object names incorrectly went to the object being spoofed, not the object doing the spoofing. [MG]
 * @lemit incorrectly ignored an = and anything after it in its arg. [MG]
 * wrap(%0,strlen(%0)) would incorrectly wrap the string onto two lines. Reported by Padraic. [MG]

Commands:
 * @edit/regexp[/all][/nocase], command version of regedit[all][i](). Suggested by Minion. [MG]
 * The @sql command no longer uses UNIMPLEMENTED_COMMAND when SQL support is not compiled into the MUSH. Instead, it just reports that no SQL db is available, like @mapsql does. [MG]
 * @slave, for restarting the info_slave and ssl_slave daemons from within the game. [SW]
 * @sockset <option>=<value>, for setting options on your descriptor.

Functions:
 * version() now reports svn revision/date where available. Patch by Padraic.
 * ldelete(), replace(), elements() and extract() now accept negative position arguments, to count backwards from the end of the list, similar to insert(). Suggested by Minion. [MG]
 * replace() now takes an optional output separator. [MG]
 * regmatch() now returns an error for invalid regexps, whether you're storing subpattern matches or not. Reported by Sketch. [MG]
 * time(), timefmt() and convsecs() can use symbolic timezones (US/Pacific, EST, etc.) if the host server has a time zone database installed. [SW]
 * playermem() and objmem() are smarter about calculating space being used by atributes [SW]
 * rnum() has been deprecated in favor of locate(). [SW]
 * step() no longer pads the final call with empty arguments, allowing you to use %+ or registers() to differentiate empty and missing args. [MG]
 * e() and exp() are now the same function internally, with e(), exp() and exp(1) all being equivilent. Suggested by Ari. [MG]
 * When wrap() hyphenates a word, the hyphen will now share the ANSI of the first character of the newline. [MG]
   
& 1.8.5p0
Version 1.8.5 patchlevel 0                                 Feb 12, 2012

Major changes:
 * The PCRE library is now required to build Penn, instead of falling back to an old, buggy version formerly bundled with the MUSH. [SW] Daniko assisted greatly with Windows changes and documentation.
 * The OpenSSL library is now required to build Penn. Again, Daniko has provided instructions for installing on Windows. [SW]
 * A new command prefix, "}", enables debug for a single execution of the command  - }think foo, }+who, etc. See 'help }' for more info. Suggested by Wiggles and [GM]. [MG]

Minor changes:
 * Added a new event, OBJECT`FLAG, triggered when a flag/power with the "event" restriction is set or cleared. Suggested by [SW]. [MG]
 * Expanded help on lock types and @powers. [MG]
 * @startups are now processed in db order (#0, #1, etc) on reboot instead of giving priority to player objects. [MG]
 * @startups (and local_startup() in local.c) are now triggered slightly later, ensuring that the db is fully loaded, and that the connected player list is loaded on @shutdown/reboot. Suggested by Padraic. [MG]
 * Switch names that are defined but not used by any commands are warned about on startup, and several unused ones have been removed from the master list. [SW]
 * Tweak utils/mkcmds.pl for the above change and to remove references to generating the obsolete patches.h. [SW]
 * Tweak the parameters of the skip list used to store memcheck counts to save some memory. [SW]
 * Bring the scheme scripts in utils up to date with current versions of chicken scheme (The implementation of the language they're written for.) [SW]
 * The test harness code strips trailing whitespace before attempting to match against expected results, making it easier to use bounded regexps. [SW]
 * @destination (for variable exits) is now a standard attribute, and has a helpfile. [MG]
 * Sound is now propagated through audible variable exits, and exits @linked to 'home'. Suggested by Mercutio. [SW]
 * The internal QUEUE attribute is no longer used to track the number of action lists an object has queued; the objdata system is used instead. [SW]
 * isobjid() now requires a full object id (with :ctime), and will return 0 for simple dbrefs, or objids of destroyed/invalid objects. isdbref() still matches both dbrefs and objids. Suggested by Covenent. [MG]
 * @entrances and entrances() now use the same internal routines as @search, and have similar (and saner) privs. From a suggestion by Sketch. [MG]
 * Connection messages that are evaluated from an attribute instead of read from a file get the dbref of the connected player as %1, as long as they're ones shown post-connection (motd_file, etc.) [SW]
 * Passwords are, thanks to OpenSSL digest routines, now stored in a less error prone, more secure, flexible and extendable format. Existing player passwords will be upgraded automatically on login. [SW]
 * New script in utils/ for manipulating player passwords in an offline database. Useful if you forget God's password. [SW]
 * The my_vsnprintf function in the hardcode has been renamed to mush_vsnprintf to avoid a conflict with MySQL. Reported by Balerion @ Blood of Dragons. [MG]
 * The enactor (%#) for the PLAYER`DISCONNECT event is now more useful, instead of always being set to the dbref of the player disconnecting (%0). Suggested by Padraic. [MG]
 * The SOCKET`LOGINFAIL event now gets passed the name that was entered as %5 when no matching player is found. Suggested by Daniel Powell. [MG]

Commands:
 * Added @mail/review for reading mail you've sent, and @mail/retract for deleting unread mail that you sent. Idea from MUX. Patch by Minion.
 * @hook/list now shows error messages if you don't have permission to use it, or if a command has no hooks, instead of failing silently. Suggested by Padraic. [MG]
 * Wizards can now @pcreate players with restricted names, as well as being able to rename existing players to forbidden names. Suggested by Nymeria @ Blood of Dragons. [MG]

Functions:
 * Functions that take a sort type argument now accept 'mtime' for sorting based on object's modification time. Patch by Minion.
 * New registers() function, like listq() but returns all kinds of registers (q-registers, %0-%9 args, iter/switch context, regexp captures). Also takes an output separator arg. Suggested by Wiggles. [MG]
 * digest(list) returns all message digest algorithms the server supports. [SW]
 * sha0() has been deprecated in favor of digest(). [SW]

Fixes:
 * lit() didn't properly handle '\'s. Reported by Wiggles. [MG]
 * listq() incorrectly returned all registers (including %0-%9, %i0, etc), not just %q-registers. Reported by Wiggles. [MG]
 * The mud_url code didn't always work correctly in Firefox because http headers weren't sent. [MG]
 * %0 and %1 arguments weren't properly passed through verb attributes after a change in p8. Reported by Padraic. [MG]
 * Fix really stupid copy-and-paste error in magic sorts on strings with ANSI, which broke setinter() and friends. Reported by Minion. [MG]
 * Help fixes by Wiggles, Mouvar and others. [MG]
 * Memory leak in ldelete() fixed. [MG]
 * Fix a crashbug reported by Minion. [MG]
 * Sorting functions now ignore ANSI when sorting a string as a number or dbref. From report by Mouvar. [MG]
 * strreplace() was broken for overly long length arguments. Reported by Ashen-Shugar.  [SW]
 * Compile errors on Windows with OpenSSL. Reported by Daniko.
 * @uptime could report negative times for the first dump, purge, etc after a game was started. Reported by Cooee. [MG]
 * override/inplace hooks from .cnf files didn't work correctly. [MG]
 * The portmsg announcer daemon was broken. Reported by Minion. [SW]
 * A change in p8 broke the sending of the Pueblo hello string in some cases. Reported by Mercutio. [MG]
 * Fix crash bug in @sitelock/remove [SW]
 * ssl_slave would drop connections if it couldn't resolve a valid hostname for the connecting IP address. [SW]
 * Non-matching regexp captures ($0, $<foo>, etc) sometimes had the value of the previous matching capture. From a report by Sketch. [MG]


& 1.8.6p2
Version 1.8.6 patchlevel 2                                 Dec 19, 2017

Fixes:
 * Fix compilation errors with OpenSSL 1.1. [SW]
 * Fix overflow bug in mapsql(). [MG]
 * elements() would very rarely give an extra delimiter. Reported by Ashen-Shugar. [1108-MG]
 * Missing null termination in 'buy' fixed by CLDawes. [1128]
 * Fix an off-by-one error in switch handling code that could cause a crash on startup. [SW]
 * Fix an issue with table() not fitting maximum number of columns in a line. Reported by Degraine. [1119-SW].
 * Fix an issue where writes to a socket sometimes shut down the connection needlessly. [1136-SW]
 * Disallow '=' to be used in passwords. Causes problems when changing passwords later. Reported by Volund, PR by Qon.

Major changes:
 * Supports client charset negotiation of UTF-8. This means the mush can send and recieve UTF-8, but still uses latin-1 internally. Unicode characters that aren't part of latin-1 are not supported. Yet. [SW]

Minor changes:
 * New @lock/chown controls who can @chown a CHOWN_OK object. Suggested by Frakir. [1127-MG]
 * The 'buy' command now pays the vendor, rather than the money disappearing into a black hole. Suggested by moniker, patch by CLDawes. [1128]
 * Help changes by Xperta, Trinsec, Elwyndas and others. [MG]
 * MySQL Stored Procedures should now work without causing 'Out of sync' errors. Patch by Mercutio. [1100]
 * Make log rotation more robust. [SW]
 * fraction() now takes a second arg; fraction(1.5,true) returns "1 1/2", rather than "3/2". [MG]
 * hasattrval() now returns 0 for attributes containing a single space when the empty_attrs config option is false. [MG]
 * fold() now passes the number of times <attr> has been called as %2. Suggested by Shaenyl. [MG]
 * Attempt to speed up database saves and loads a bit. [SW]
 * Improvements to SSL certificate checking. The ssl_ca_file config option should now be set to /etc/ssl/certs/ca-certificates.crt unless you've customized it, and the new ssl_ca_dir option to /etc/ssl/certs. [SW]

Hardcode:
 * Use the much lighter weight and higher quality PCG random number generator. [SW]
 * Use a better seed for the RNG on Windows. [SW]
 * mkcmds.pl uses a better way to generate temporary files. [SW]	
 * Use clang-format instead of GNU indent to format source code. [SW]
 * Use poll(2) instead of select(2) for the main game event loop. [SW]
 * Slave procceses use prctl(2) on Linux to be notified of the mush exiting instead of checking periodically. [SW]

& 1.8.6p1
Version 1.8.6 patchlevel 1                                 Mar 29, 2017

Major changes:
 * Added some aliases for the MUX com system, including the addcom, delcom, comtitle, comlist and @clist commands. Enabled in mush.cnf. See 'help muxcomsys' for details. Requested by many people over the years. [MG]
 * Move all remaining build-time settings out of options.h into mush.cnf and remove options.h. [SW]
 * rjust(foobar,3,,1) previously returned "bar"; it now returns "foo", like the analogous functions on MUX and Rhost do. We won't be changing it again. Honest. [1092-MG]

Fixes:
 * @clone'ing an old exit which had the alias built into the name incorrectly created a clone with no aliases. Reported by Qon. [MG]
 * Fix compile errors in portmsg.c. Reported by mcgiwer. [SW]
 * Disable SSLv2 support. [SW]
 * Fixed a memory leak in @listens. [MG]
 * Minor align() fixes when merging multiple columns. [MG]
 * repeat() would sometimes fill the buffer with very large numbers of repetitions. Reported by Ashen-Shugar. [MG]
 * SOCKET`CONNECT event caused a crash because cque expected a player to always be enactor. [GM]
 * 'help entries' was broken. Reported by Viila@M*U*S*H. [MG]
 * @if incorrectly evaluated both its action list arguments prior to queueing one of them. Reported by Qon and Ashen-Shugar. [1076-MG]
 * The @mailquota standard attribute was missing from some dbs, for some unknown reason. It will be automatically be added back in when you first update to this version; if you aren't using the @mail system, you can @attribute/delete it once and it'll stay gone. Reported by Kimojuno. [1077-MG]
 * Messages - such as an exit's own @osuccess - could be propagated through an audible exit when they shouldn't be. [1081-MG]
 * Fix a crash if a particular file descriptor is -1. [SW]
 * Fix a potential crash in @stats/tables [SW]
 * controls(<obj>, <victim>/<attr>) would return 1 even if <obj> didn't control <victim>. [MG]
 * Although json(object) would correctly return {}, an empty JSON object, other JSON functions would throw an error and say it was invalid. [MG]
 * Fixed channel_send() incorrectly setting speaker to NOTHING for non-spoofed chat messages when adding text to the channel buffer. PR by Qon.
 * extract(<list>) incorrectly returned the 2nd element of <list>, instead of the 1st. Reported by Jules@M*U*S*H. [MG]
 * Several places which checked for unsigned integers didn't ignore Tiny_Math, but should have. Reported by Kitten, debugged by Ashen-Shugar. [MG]
 * Paranoid dumps didn't use the latest db flags. [SW]
 * Although they can't be destroyed directly, it was still possible to destroy some important objects like the player_start room by nuking their owner, with nasty consequences. Reported by Sistene@M*U*S*H. [MG]
 * regrab(), reglmatch() and related functions didn't work if the <regexp> contained ansi. From a report by Riorgan@M*U*S*H. [MG]

Minor changes:
 * PLAYER`CREATE event now passes the registered email if the player was created using 'register' at the login screen. PR by Qon.
 * moniker() now returns accented names, for Rhost/MUX compatability. Reported by Qon. [1063-MG]
 * Help fixes by Qon and others. [MG]
 * The makefile warns if gperf is not installed but needed to regenerate some source files. Based on an idea by [TK].
 * Work torwards supporting Windows via MSYS2. [SW]
 * New option for align(), # stops a colsep being added after a column. Suggested by Ashen-Shugar. [MG]
 * If you own an object and are in its DEBUGFORWARDLIST, you'll now only get the debug output once. Suggested by Qon. [1059-MG]
 * Tweaks to 'help <wildcard>'s error messages, and the help for said syntax. Suggested by Wiggles. [1084-MG]
 * The "monikers" config option now takes a list of words, rather than a bitflag - less confusing and more user-friendly. [1089-MG]
 * @chownall now takes /things, /rooms and /exits switches, to limit the types of objects chowned. [MG,Rhost]
 * @chown <obj>/<attr>=<owner> acts as an alias for @atrchown, for Rhost compatability. [MG]
 * @grep/parent checks inherited attributes too. [MG,Rhost]
 * Penn now understands XTERM when reading raw ansi tags. It essentially never does this, though. Requested by spork. [975-MG]
 * Players that are See_All, Royaty or Wizard can see Hidden-connect messages on any channel. PR by Qon.
 * Players hidden on a channel with @chan/hide will not show connect messages to players unless they are see_all or roy/wiz. PR by Qon.
 * Hidden-connects/disconnects only show on @chan/recall and crecall() if you are see_all, roy or wizard, except for your own messages. PR by Qon.
 * DARK-connect/disconnect/etc messages are no longer announced over channels. Dark and Hidden are two different things. PR by Qon.
 * The Pueblo_Send power has been renamed Send_OOB, to reflect its new use for other, non-Pueblo-related, out of band messages. Pueblo_Send remains as an alias. (The hardcode macro checking for the power, Can_Pueblo_Send, has also changed to Can_Send_OOB.) [1041-MG]
 * Mortals can now use oob() on themselves, and those with the Send_OOB power can use it to send to anyone. Suggested by Qon and Sketch. [1041-MG]
 * Remove a duplicate message when @chzone'ing a priv'd player. [MG]
 * @hooks now always have named registers for left-side args, even if the command isn't eqsplit (see 'help @hook7'). [MG] 
 * Make SHA-0 dependency optional to support OpenSSL 1.1. [SW]
 * Change the default hash for player passwords to SHA-512 from SHA-1. [SW]
 * The default @poll message, "Doing", can now be translated. [MG]
 * Clean up some of the shell scripts used in the build and startup processes. [SW]

Functions:
 * Added setsymdiff() [SW]
 * Added randextract(), a more powerful version of randword(). [MG,Rhost]
 * randword() is now more ansi-aware. [MG]
 * pgrep(), like grep() but also checks parents. [MG,Rhost]
 * Added json_query(), for getting various information about JSON data. [MG]
 * A number of functions are now more ANSI-friendly, including first(), last(), rest(), fold(), filter(), grab(). Report by Qon. [1048-MG]
 * splice() no longer strips ANSI. [1045-MG]

Documentation:
 * Improve documentation for required packages in some Linux distributions.
 * Document how to get Penn running on the Windows 10 Bash For Ubuntu On Windows project.
 
Hardcode:
 * safe_atr_value() now takes a second arg, for memory tracking (mem_check), and the returned value must be freed with mush_free() instead of just free(). [MG]
 * ChanTitle(), CHAN_TITLE_LEN, and the "title" member of the channel struct - used for @channel/desc - have been renamed to ChanDesc, CHAN_DESC_LEN and "desc", respectively. Now I won't confuse them as being relevant with @channel/title. Every. Single. Time. [MG]
 * etime_to_secs() now takes a third, boolean argument, default_minutes. If true, purely numerical values are treated as a number of minutes, not seconds. This allows using the function for parsing time-related config options instead of having a separate implimentation. [MG]

& 1.8.6p0
Version 1.8.6 patchlevel 0                                 Dec 25, 2015

NOTE: When updating from an earlier version of PennMUSH, you'll need to run 'make update' and './config.status' in the toplevel PennMUSH directory prior to running 'make'.

Major changes:
 * Hosted on Github. Thanks, Google. [DC]

Functions:
 * element() is now an alias for match(). Suggested by Wiggles. [985-TK]
 * Added json(), for creating valid JSON-encoded data. [MG]
 * Added oob(), for sending out-of-band messages via the General MUD Communication Protocol (GMCP) telnet option. Requested by Qon. [MG]
 * registers() only listed registers whose values were strings, not ints. [MG]
 * filter() and filterbool() can now be passed additional arguments, for Rhost compatability. Requested by Volund. [1019-MG] [Rhost]
 * valid() can now validate timezones, locktypes and lockkeys. Suggested by Volund. [1021,1025-MG]
 * convtime() now returns #-1, instead of -1, on error. This change is -backwards incompatible-, but necessary as -1 is a potentially valid output for convtime(). Suggested by KimikoMuffin. [1010-MG]
 * convsecs() can now accept negative inputs when Extended convtime() is available. Suggested by Volund. [1010-MG]
 * avg() is now an alias for mean(). [1023-TK] [Rhost]
 * textsearch() allows searching the contents of helpfiles. [MG]
 * speak() no longer has the odd TinyMUSH behaviour of ': foo' being a semipose; speakpenn() is now an exact alias. [1034-MG]
 * timefmt() and isdaylight() can now take a negative number of seconds for times prior to 1970 when Extended Convtime is available. [MG]
 * colors(...,auto) returns colors in the same style as their input. Suggested by Kimiko. [MG]
 * rjust(str,X,,1) truncated the end of the string, instead of the start. [MG]
 * Minor json() bug and documentation fixes. [MG]
 * wordpos() is now ansi-aware. [MG]
 * More markup-awareness in a number of list functions. [MG]

Commands:
 * The 'kill' and 'slay' commands have been removed. [1033-TK]
 * Remove ancient @channel foo=on behavior. Reported by Paige. [870-TK]
 * @logwipe can do more than just erasing a log file. [SW]
 * @hooks now have a number of named registers (available through r(<name>,args)) with each of the hooked command's arguments. [MG]
 * Added @if and @skip. [MG] [Rhost] [MUX]
 * help/search <pattern> lets you search within helpfiles. [MG] [Rhost]
 * @newpassword now takes a generate switch, which creates a random password ala email_register and shows it to the executor. [Qon]

Minor changes:
 * The 'HAVEN' flag can now only be set on players. [1033-TK]
 * Added a few more date formats to getdate.template for convtime(). Suggested by Volund and Mercutio. [1020-MG]
 * Most PennMUSH helpfiles are no longer hard-wrapped at 78 characters; noone connects from clients that can't wrap any more. [1030-MG]
 * Other minor help fixes. [MG]
 * Attempting to run an empty SQL query via any command/function now gives a better error/return value. Reported by Qon. [MG]
 * Added some tests for json(), and more tests for ljust()/rjust(). [MG]
 * Guests can no longer @channel/recall channels they aren't on. [MG]
 * The hardcode no longer strictly enforces permissions for @wall, @rwall or @wizwall; anyone who can passes the normal command restriction can now use them. [MG]
 * Add references to 'help channel functions' to various channel function help entries. By Qon.
   
Hardcode:
 * Clean up some more remnants of the previous configure package's naming convention in favor of autoconf style ones. [SW]
 * OpenBSD compilation fixes. [SW]
 * Support authorization of ssl_slave forwarded connections on NetBSD, OpenBSD. [SW]
 * Remove old FAM-based file monitoring code, due to bitrot and FAM's last release being 2003. [SW]
 * Add git revision, if present, to @version & version(). [994-TK]
 * Log files that grow over a user-specified size can now be rotated or trimmed down. [SW]
 * game/restart is now auto-generated during 'make update'. [928-TK]
 * Fixed a memory leak in @switch. [MG]
 * A bug in @lock allowed invalid lock names to be used. [MG]
 * Added support for the General MUD Communication Protocol (GMCP). See http://www.gammon.com.au/gmcp for more info. Requested by Qon. [MG]
 * Choosing what scheme is used in compressing attribute text in-game is now a run-time option set in mush.cnf, not options.h [SW]
 * Minor fixes and resource cleanups reported by Qon. [MG]
 * An off-by-one error led to passwords occassionally being hashed incorrectly and needing to be reset. Reported by Glass. [MG]
 * Old-style raw ANSI codes (from old dbs, SQL, etc) was sometimes mistakenly stripped when sent to a client. Found and fixed by Qon. [1050]
 * Some @mail selectors incorrectly selected all mail in the current folder. Found and fixed by Qon. [1055]
& changes
& 1.8.7p0
Version 1.8.7 patchlevel 0 Aug 10 2018

This is a list of changes in this patchlevel which are probably of
interest to players. More information about new commands and functions
can probably be gotten via 'help <name of whatever>'. 'help credits'
lists the [initials] of developers and porters that are used in the list 
of changes.

Information about changes in prior releases can be found under
help topics named for each release (e.g. 'help 1.8.7p0').
A list of the patchlevels associated with each release can
be read in 'help patchlevels'.


Major Changes:

* Support websocket connections. See https://github.com/grapenut/websockclient for a sample in-browser client. [Grapenut, 1007]
* Change attributes from being stored in sorted linked lists to sorted arrays; results in faster lookups and less memory usage. [SW]
* Penn now comes with the Sqlite3 database engine bundled with it, and uses it internally in a few ways:

* 3 different tables for looking up color names are combined into a single table.
* Per-object auxilliary data keys (objdata) are handled in sql.
* Player names and alias lists are handled in sql, making some operations on them simpler.
* Suggests alternatives for unknown function names, flags, powers and help entries, and a softcode interface to the suggestion engine.
* @entrances and entrances() no longer scan the entire database.
* Help files are stored in a database, with an expanded help/search that supports full text search. See [1mHELP SEARCHING[0m for details.
* Optional enhanced connection logging. See the file [1mgame/CONNLOG.md[0m for details.
* A number of new softcode functions and expanded functions, listed below.

Minor Changes:

* Message translation support now defaults to off. Run configure with [1m--enable-nls[0m to turn it on if needed. [SW]
* Shrink the [1mNEW_PE_INFO[0m struct, for signficant memory savings in softcode that queues lots of commands. [SW]
* Add more test cases to the softcode test suite. [SW]
* log_forces in mushcnf.dst now defaults to no. You probably only want this on if you’re debugging. [MG]
* The connect screen now respects SOCKSET options. [MG]
* @chan/what now displays channel locks. [MT, 1208]

Softcode:

* Support all of Rhost’s [1mcolors()[0m key arguments (Except n). [SW, 1112]
* Functions that work on integers (Like [1mdiv()[0m or [1mband()[0m) now use 64-bit values instead of 32-bit. [SW]
* Added [1misjson()[0m
* [1mjson_query()[0m get and exists can follow paths into objects instead of taking a single key/index. Suggested by qa’toq. [SW]
* [1mjson_mod()[0m for modifying complex JSON objects. [SW]
* [1mjson_query(str, unescape)[0m handles unicode escape sequences.
* [1mjson(string, foo)[0m escapes non-ascii characters.
* [1mclone()[0m now takes an optional fourth argument to act like [1m@clone/preserve[0m [797]
* New ‘me’ and ‘inventory’ flags for [1mscan()[0m give finer control of what to scan. [MG]
* [1morflags()[0m, [1morlflags()[0m, [1mandflags()[0m, [1mandlflags()[0m, and the power versions no longer return errors on unknown flags/powers. They instead treat the unknown one as if it wasn’t set. Suggested by Qon. [1180].
* [1mtimecalc()[0m and [1msecscalc()[0m for adding/subtracting intervals from times.
* [1m@suggest[0m and [1msuggest()[0m for user-defined spellchecking. Loads [1m/usr/share/dict/words[0m or another configurable wordlist by default.
* [1mconnlog()[0m and [1mconnrecord()[0m for interfacing with enhanced connection logs.
* [1msoundex()[0m and [1msoundslike()[0m now support a second phonetic hash algorithm besides soundex.
* Side-effect version of [1mlink()[0m now returns 1 on success, 0 or #-1 on failure. [MT]
* [1mowner()[0m now accepts two optional arguments, allowing ownership to be changed as in [1m@chown[0m and [1m@atrchown[0m. [MT]
* If compiled with libcurl support, adds [1m@http[0m for interacting with RESTFul web APIs. [SW]
* [1mstripaccents()[0m supports a second, smarter, transliteration algorithm.
* If compiled with ICU support, adds [1mlcstr2()[0m and [1mucstr2()[0m with proper support for characters like the German eszett (ß) that map to a different number of characters in different cases.
* [1m@chatformat[0m now receives a new arg, [1m%6[0m, which defaults to “says” but may be replaced by the speechtext mogrifier. Inspired by Bodin. [MG]
* [1metimefmt()[0m supports [1m$w[0m and [1m$y[0m formats for weeks and years. [SW, 804]

Fixes:

* A bunch of color names weren’t mapping correctly to Xterm color codes. [SW]
* [1m@grep/iprint[0m hilites the matching text in the same case it appears in the attribute body. [SW, 1120]
* [1m@mail[0m wasn’t updating a player’s MAILCURF attribute correctly. [CLDawes, 1131]
* Connecting with a web browser to a mush without a [1mmud_url[0m config option set caused an infinite refresh loop. Reported by grapenut. [1149]
* Make sure [1msigrecv_ack()[0m won’t hang the mush if it somehow gets called at the wrong time. Also fix a file descriptor leak in the signal handling code. [SW]
* Pass [1mpe_info[0m into IDLE and HAVEN attributes from the page command. [MG]
* The x and X options to [1malign()[0m now always truncate to the column width, rather than incorrectly truncating at a space. Reported by Qon. [MG, 1178]
* [1mjson_query()[0m didn’t understand an action of ‘type’ as documented. [SW]
* [1m@clone[0m without /preserve wasn’t stripping privileged flags and such. [1190,SW]
* [1m@chown/preserve[0m was resetting wiz-bit despite it’s help file indicating otherwise. [1187] PR by Qon.
* [1mscan()[0m now determines if objects will be included based on whether the caller can examine them, rather than if [1mscan()[0m’s [1m<looker>[0m can examine them. [MG]
* Fixed some bugs regarding when [1msetq()[0m will and won’t let you set the values of named registers when you’ve hit the limit. [MG, 1179]
* [1msqlescape()[0m when using a sqlite3 connection no longer also requires MySQL.
* A number of issues in the handling UTF-8 text sent by clients have been fixed, as well as improvements in UTF-8 handling in general. [SW]
* Fix an off-by-one error in command switch initialization code. [SW]
* [1m@mail[0m without a message list respects the current folder instead of using folder 0. [77]
* [1mufun()[0m, [1mulocal()[0m, etc. could get confused by ansi (markup) in the attribute name. Strip markup first. [MT]
* Fix a long-standing bug where input sent right after a SSL connection could get lost. [SW]

Documentation:

* Changelogs and other documentation use markup. [SW, 1140]
* Start trying to clean up and revise ancient documentation. [1095]
* Help fixes and improvements. [MG, SW, MT]
* Help files are now in UTF-8.

OS Specific:

BSDs in general:

* [1minfo_slave[0m and [1mssl_slave[0m use [1mkqueue()[0m to efficiently be notified of parent mush crashes.

OpenBSD:

* netmush and slave processes use [1mpledge(2)[0m to limit their privileges. [SW]

Windows:

* Use Windows crypto library functions for base64 conversion and digest hashing instead of OpenSSL. [SW]
& 1.7.3p14
Version 1.7.3 patchlevel 14                    January 29, 2001

Major Changes:
      * Commands and functions can now be aliased to other names
        in mush.cnf, so you can provide translated command names
        as well as the english one, etc. Suggested at various times
        by Krad@M*U*S*H and David@M*U*S*H. New file aliases.cnf
        in game/ is created to put these command_alias and function_alias
        directives (as well as reserve_alias). [SW]
Minor Changes:
      * smalloc and bigram compression options are no longer supported. [SW]
      * Internal improvements to @search/lsearch, which are now more
        consistent with one another. [SW]
      * mush.cnf options that refer to dbrefs now understand #<number> as 
        well as just <number>. They are also formatted as dbrefs in @config 
        and config(). [SW]
      * Much longer game/names.cnf file contributed by Kyieren@M*U*S*H.
      * New internal function notify_format() to replace notify+tprintf
        more safely. [SW]
      * Tweaks to network activity timeout code. [SW]
      * @stat and lstats no longer needs to scan the entire database. [SW]
Commands:
      * @switch and @select can now take a /notify switch, like @dolist.
      * Players may @chown by dbref, but they must still be carrying
        the object if it's a thing. Suggested by Kyieren@M*U*S*H.
      * @clone can now clone rooms. Suggested by Kyieren@M*U*S*H.
      * @verb's matching of the <actor> argument has been relaxed so
        non-privileged objects can use it on remote actors, if the normal
        permission checks succeed. This makes @verb much more useful for zones
        and master room objects. [SW]
Attributes:
      * @forwardlist [2.2,SW]
Functions:
      * itemize() takes a list "a b c" and produces "a, b, and c" and 
        similar tricks. Also callable as elist() for Rhost compatibility.
      * ilev() returns the current iter nesting level. [Rhost,SW]
Fixes:
      * When indexing help files, ones that aren't in the right format
        weren't being properly closed. Report by Nammyung@M*U*S*H. [SW]
      * We're much more forgiving about help files that start with
        blank lines now.
      * Help updates by Kyieren@M*U*S*H, [SW]
      * Games w/o MAIL_ALIAS couldn't load maildbs that had mail aliases.
        Reported by Nymeria. [SW]
      * max_pennies had a limit of 10,000 in conf.c, even though it
        has always defaulted to 100,000. Reported by Intrevis@M*U*S*H.
      * src/filecopy.c didn't include hdrs/log.h. Fixed by Noltar@Korongil.
      * MacOS portability fixes. [DW]
      * vsnprintf used in place of vsprintf everywhere when available. [SW]
      * Cleanup of @atrlock code. [SW]
      * '#' without any trailing numbers was treated as #0 when used as a 
         dbref. [SW]
      * Added explicit checking for lower-case letters in good_atr_name(). [SW]
      * Trying to set an attribute with a bad name now gives a better 
        error message. [SW] 
      * Fix to potential overflow bug in revwords. [SW]
      * Fix to potential overflow bug in @grep. [SW]
      * Configure checks for snprintf. Systems unfortunate enough not to
        have this (Solaris 2.5.1, for example) are stuck with sprintf.
        Report by Broncalo@DuneIII.
      * CHARGES were decremented whenever an A-attribute would be 
        executed, *even if the attribute wasn't set on the object*.
        Reported by Kyieren@M*U*S*H.

& 1.7.3p13
Version 1.7.3 patchlevel 13                    January 9, 2001

Major Changes:
      * Semaphores may use attributes other than SEMAPHORE. These 
        "named semaphores" make it easier to have multiple semaphores
        waiting on the same object. [SW]
      * New attribute flag AF_NODUMP prevents attributes from being
        dumped to the db. It applies to QUEUE, SEMAPHORE, and attributes
        used as named SEMAPHORES. [SW]
Commands:
      * @wait/until can be used to put commands on the wait queue until
        some absolute time (in secs) is reached. [SW]
      * @cpattr/noflagcopy copies attribute data without flags.
        Same for @mvattr. Suggested by Noltar@Korongil.
Functions:
      * foreach() takes start and end arguments like TM3/MUX2. [3,SW]
      * locate() has a new option to force matching the preferred type, 
        and an undocumented option to eliminate ambiguous matching is now
        documented. [SW] 
Minor Changes:
      * Experimental support for translating 8-bit accented characters to HTML
        entities for Pueblo. [SW]
      * Objects without a @lock/zone that are used as zones are noticed and 
        warned about during dbcks. [SW]
      * Some people prefer that +channel "foo now cause you to say "foo 
        on the channel, instead of stripping the initial quote. Now
        it's a mush.cnf option (chat_strip_quote). Suggested by Dave Milford.
      * isint() now ignores tiny_math, so isint(foo) will always return 0. [SW] 
Fixes:
      * Hopefully fixed a problem with puppets doing look for non-Pueblo
        players with Pueblo support turned on. The line after the look
        could appear to come from the puppet even if it didn't. [SW]
      * If you disabled a command with a one-character token (like say),
        then running the command with the token ("hi!) would fail, but 
        wouldn't return the right thing for $command matching. Now it
        returns the canoncalized raw command (SAY hi!) so you can trap
        it in softcode. Reported by Mackenzie@SWGT Mush  
      * General linting [SW]
      * Help fixes by Rince@M*U*S*H.
      * make customize doesn't try to link mkindx any more. And README and
        os2/Makefile don't refer to it either. By Bobby Bailey (Chil@M*U*S*H).
      * The internal tprintf() function is safer. [SW]
      * Crash bug in @edit fixed, and @edit code is cleaned up. [SW] 
      * max_pennies documented in mush.cnf. Noted by Oriens@Alexandria
      * cmdlocal.dst now includes cmds.h. Reported by David@M*U*S*H.


& 1.7.3p12
Version 1.7.3 patchlevel 12                    January 4, 2001

Locks:
      * A new @lock/chzone, set on a ZMO, controls who may @chzone
        objects to the ZMO. This can simplify multi-player building
        using ZMOs. Suggested by David@M*U*S*H
Commands:
      * @wcheck/me checks all of a player's objects for them.
Functions:
      * cflags() function gets channel flags.
      * ctitle() gets channel title for an object. Suggested by Luke@M*U*S*H.
      * strinsert() function does insert() on strings. Suggested by
        Reagan@M*U*S*H. [SW]
      * channels() on an object you can't examine now shows you channels 
        that you have in common with it. Suggested by Trispis@M*U*S*H
Minor changes:
      * Runaway objects are now logged, along with the command that
        pushed them over the edge. Suggested by Trispis@M*U*S*H.
      * All instances of fprintf(stderr,...) after logging is started
        are now handled through do_rawlog(LT_ERR,...). By David@M*U*S*H.
      * @atrchown works more reasonably. [SW]
      * @lock/link on an unlinked exit restricts who may link it.
      * Everyone (even mortals) sees object names at the top of
        their descriptions when they look at them. Suggested by Jeff
        Ferrell most recently.
      * New reserve_alias mush.cnf directive makes run-time command
        alias reservation possible. Suggested by Jeff Ferrell.
      * Mortals may use @command to get info about commands. Suggested by
        Chili@M*U*S*H.
      * Messages logged during help file indexing distinguish indexing
        of admin topics. Suggested by mith@M*U*S*H
Fixes:
      * Help fixes by [SW], Jeff Ferrell, mith@M*U*S*H, Mirth@AtheneuMUSH.
      * Help update to @cpattr based on behavior noted by Noltar@Korongil.
      * cwho and @chan/who behave better with hidden (@hide) players.
        Reported by Reagan@M*U*S*H.
      * MUSHes with no @functions crashed on @list calls due to a 
        problem with the hashtable code. Reported by Whiskey. [SW]
      * A bug in handling of errors under debug in process_expression
        was reported by Reagan@M*U*S*H. [SW]
      * Rare memory leak in process_expression fixed. [SW] 
      * Inconsistencies in the handling of destroyed objects/players
        and their locations fixed. [SW]
      * The QUEUE attribute was not properly cleared on restart
        for non-player objects. It was buggy in other ways, too. [SW]
      * The AF_SAFE attribute flag couldn't be reset. Reported by
        Pegasus@StarQuest.
      * @teleporting into garbage could cause crashes. Reported by Howie
      * The help_command and ahelp_command directives now look for
        whitespace generally, not spaces specifically. 
        Suggested by Krad@M*U*S*H
      * SIGHUP once again re-reads the config file. [SW]
      * If an exit @created an object, that object would be inside the exit 
        until the next dbck. Now it is created in the exit's source room. [SW]
      * Turning the lowest possible integer number into a string could 
        result in garbage output. [SW]
      * Solaris needed arpa/nameser.h before resolv.h in mysocket.c

& 1.7.3p11
Version 1.7.3 patchlevel 11                    December 4, 2000

Minor changes:
      * Added 'comsys' as help alias for 'chat'. Suggested by David@M*U*S*H
      * New win32 project files and MSVC build instructions by Jenny Lind.
Fixes:
      * Improved test for non-broken getdate and getnameinfo.
      * Loading panic dumps does better on chatdb. By Maverick@M*U*S*H
      * You may leave a channel even if you're the wrong type
        to get onto it. Suggested by Cheetah@M*U*S*H.
      * Typo in the win32 strcasecmp code fixed [NJG]
      * stddev's algorithm improved. [TAP]
      * If the go command is restricted, other commands produce spurious
        errors during the exit-matching phase of command parsing.
        Reported by Jamie@M*U*S*H

& 1.7.3p10
Version 1.7.3 patchlevel 10                    November 20, 2000

Major Changes:
      * Improved detection of errors saving the game. If any problems 
        are encountered, the save is aborted, and online admins notified so
        they can fix the problem before finding out about it too late. [SW] 
Flags:
      * The INHERIT flag has been renamed TRUST, which better describes
        its function. INHERIT remains as an alias.
Commands:
      * @chan now takes /ungag, /unhide, and /unmute as well as the
        usual @chan/gag <channel>=no. By David@M*U*S*H.
Minor Changes:
      * money() called on a no_pay player returns the value of
        MAX_PENNIES to ease softcode checks. Suggested by Oriens@Alexandria.
      * Removed help and &help entries from the distributed pennmush.nws
        because people will generally want to override them anyway
        and we shouldn't introduce problems. Suggested by Jeff Heinen.
      * safe_str and friends optimize trivial 0 and 1 letter strings. [SW]
      * A version of word-based compression that's almost 8-bit clean
        is now included. [SW]
      * We now use stricmp and friends for strcasecmp and friends on
        Win32, rather than roll our own. [SW]
Fixes:
      * @mail aliases couldn't be used by players who didn't have
        permissions to see the alias members, which is wrong.
        Fixed now. Report by Grinna@M*U*S*H.
      * lnum(1) and lnum(0,0) were broken. Report by Jeff Ferrell 
      * Help updates. [SW]
      * @set obj/notanattribute=flag now returns a 'No such attribute' error.
        Reported by David@M*U*S*H. [SW]
      * Help file indexing tries to detect files that aren't in the right 
        format. [SW]
      * function restrictions were checking the wrong object. [SW] 
      * objmem and playermem counted eval-locks and atr-locks incorrectly. 
        Reported by Javin@DynamixMUSH. [SW]
      * Fixes to win32 NT_TCP stuff. [NJG]
      * Rare memory leak in do_page fixed by David@M*U*S*H. 

& 1.7.3p9
Version 1.7.3 patchlevel 9                    November 20, 2000

Major Changes:
      * Help files and their associated commands are now defined with
        the 'help_command' (or 'ahelp_command') directive 
        in mush.cnf. So you can translate the help to french and
        add an "aidez-moi" command if you like. [SW]
      * Help file indexes are now kept in memory and built by the
        server. The mkindx program is no longer used. [SW]
      * Added restrict_function and @function/restrict, like the versions 
        for commands. [SW]
      * User @functions can now override built-in functions, if you
        @function/delete the built-in first. You can also @function/restore
        the built-in back. [SW]
Attributes:
      * @[oa]zenter and @[oa]zleave on ZMOs are triggered when someone
        enters or leaves a given zone. Motion between rooms in the same
        zone doesn't trigger these. "Zone" is based on the mover's
        absolute room (outermost container) so that entering and leaving
        an unzoned object in a zoned room doesn't trigger these either.
        Suggested by Michael Kurtz.
Commands:
      * New /silent switch for @teleport without @[o|a|ox]tport msgs.
Minor Changes:
      * Still less allocation involved in outputting text to connections. [SW]
      * @scan has better output when multiple attribs match. [SW]
      * Added internal absolute_room function for use by fun_room
        and move.c and wiz.c, etc.
      * MEM_CHECK now uses a sorted linked list and is faster. [SW]
Fixes:
      * References to kill_timer removed from win32 sections. [SW]
      * conf.c reports error via logging routines, not fprintf. [SW]
      * Assorted minor bug and warning fixes. [SW]
      * Fix to example in help regedit by Amberyl.
      * @wait and other timing functions were broken under win32.
        Fixed now. [LdW]


& 1.7.3p8
Version 1.7.3 patchlevel 8                    November 12, 2000

Major Changes:
      * Objects' names are stored in a string tree like attributes, so
        we don't have hundreds of copies of 'West <W>;west;w' and such
        taking up memory. Attribute name "hash table" is now a strtree. [SW]
      * We no longer use alarm() to know when to run stuff on the queue. [SW]
      * @shutdown/reboot is now supported on Windows builds. This is
        slightly experimental. By Revian.
Minor Changes:
      * %qa-%qz now operate as global registers like %q0-%q9. 
        Suggested by Trispis@M*U*S*H and probably others.
      * Hashtable lookups are faster (collision chains are sorted) [SW]
      * @uptime/mortal suppresses the extra process information [SW]
      * Wizard @uptime prints better process information on linux. [SW]
      * @listen, @filter and @infilter respect the REGEXP and CASE attribute 
        flags.  Suggested by Maestro@M*U*S*H [SW]
      * Having many @waits or semaphores is more efficient, because we
        sort those queues by time and we stop looking sooner. [SW]
      * User-defined lock names must follow the same rules as attribute 
        names. The name part of attrib and eval locks have to also. [SW]
      * @chan/title's confirmation message is nicer. [SW]
      * Minor optimizations related to strcpy() and malloc() overhead. [SW]
      * safe_format uses vsnprintf if your system has it. By Luke@M*U*S*H.
      * replace_string is safer. By Luke@M*U*S*H.
Fixes:
      * iter() is smarter about quitting when the function invocation
        limit is reached or the buffer is filled. [TAP]
      * lnum() has been greatly sped up. [TAP]
      * RWHO references removed from game/mushcnf.dst, game/restart,
        etc. by mith@M*U*S*H.
      * Fix to help filter by Revian.
      * COMPRESSION_TYPE 0 didn't compile. Report by David@M*U*S*H.
      * Clarification of @lock/teleport in help @elock by Envinyatar@M*U*S*H
      * Compiling w/o MAIL_ALIASES didn't declare load_maliases.
        Reported by Envinyatar@M*U*S*H
      * clone() was stomping %0-%9. Report by Revian.
      * @dol with an empty list now does the right thing (nothing)
        instead of running the command once. Report by Linda Naughton [SW]
      * spname cleanup by mith@M*U*S*H.
      * Fixed a bug in @function function-name [SW]
      * make update should finally handle CHAT_TOKEN_ALIAS right.
        It's also smarter with mush.cnf
      * isword() on a null string now returns 0. Suggested by Ashen-Shugar.
      * channels(object) returns a better error when object isn't matched.
        Suggested by Trispis.
      * Fix to help rand() to reflect actual error return value. Reported
        by Philip Mak.
      * More translated strings noted by Krad.
      * Problems with encrypt()'s logic fixed by Ashen-Shugar. [Rhost]
      * Other encrypt() sillyness fixed by Brazil.
      * Potential crashers around DEBUG and other buffer overruns
        have been fixed. Report by Tajan and Rimnar. [SW]
      * notify_anything allocates less memory. [SW]
      * Fixed mistagged memcheck "restart.descriptor". 
      * MacOS portability changes. Should build on MacOS X public beta
        (Darwin) systems nearly straightaway. [DW]
      * Restart script test for already-running MUSH condensed to one
        line. Suggested most recently by Cory Albrecht.
      * Serious crash bug in page fixed. Reported by Revian.
      * Win32 bugs fixed by Luke@M*U*S*H: problems with dumping
        compression suffixes, problems with @uptime
      * MUSH no longer crashes if a player alias is > 32 chars in length.
        It truncates names that are too long instead. By Luke@M*U*S*H.
      * We don't check AF_PRIVATE attributes for $/^commands on children.
        By Luke@M*U*S*H.
      * Under win32, the MUSH would often start ignoring commands from
        players after the first 98 per connection. Fixed by Revian.
        
& 1.7.3p7
Version 1.7.3 patchlevel 7                    October 12, 2000

Functions:
      * filterbool(), for TM3 compatibility. Like filter(),
        but tests for any true value, not just 1. [3,SW]
      * case(), for TM3 compatibility, and caseall().  Like switch() 
        and switchall(), but does an exact match, not wildcard. [3,SW]
      * valid() takes more categories. [SW]
      * localize(), for TM3 compatibility. Like a cross between
        s() and ulocal(). [3,SW]
Commands:
      * @break, for Rhost compatibility. Stops processing the
        current action list. [Rhost,SW]
      * @enable and @disable can be used on any boolean config option. [SW]
      * @function/enable and @function/disable for built-ins
      * @function function-name reports some information on the function,
        like @command command-name.
Flags:
      * New attribute flag 'safe' prevents accidental modification.
        Suggested by Stephen Viscido. [TAP]
Minor Changes:
      * The daytime config option is no more. Do a few @searches in
        its honor. [SW]
      * lsearch() permission is controlled by @search, and entrances()
        by @entrances, for consistency with other functions that have
        a corresponding command. [SW]
      * The number of reboots is tracked, and the restarts() function
        added, for TM3 compatibility. [3,SW]
      * Rearranged some compile flags to suit systems that have
        /usr/local/include/ident.h. By Luiz Claudio Duarte.
      * More strings marked for translation. By Krad@M*U*S*H
      * :, [, ], (, and ) are no longer legal in attribute names
        due to ambiguities and security issues. [TAP,SW]
      * Ranges in @search, lsearch() and @find can be either #dbrefs or 
        (for backwards compatibility), integers. Inspired by ElendorMUSH. [SW]
      * Broadcast messages in bsd.c replaced with GAME prefix.
        Suggested by Krad@M*U*S*H.
Fixes:
      * Fixed a bug in filter() where it only looked
        at the first character of the evaluated attribute. [SW]
      * Some more noise from info_slave was removed. [SW]
      * do_pcreate and do_chownall now live in game.h and not
        externs.h. Reported by Maestro@M*U*S*H.
      * Clean-up of atr_add calls in void context. [TAP]
      * IPv6 buglet fixed. Report by Vexon@M*U*S*H. [SW]
      * @config/set can no longer be used to set options in the files   
        and messages categories, as this has icky consequences. [SW]
      * Fixed a logic bug in letters_to_privs where not all the letters 
        were being turned into privs properly. Report by Bolt@M*U*S*H [SW]
      * Fix to isint() so that isint(1a) is 0. [SW]
      * Added safe_boolean internal function, and fixed a hang bug
        in edit() reported by Walker@M*U*S*H. [SW]
      * Fixed problems in panic dumps/reads of maildb and chatdb. [SW]
      * @edit is a bit more efficient. [SW]
      * Assorted lock structures are allocated in big chunks like 
        attribute structures, to save malloc overhead. [SW]
      * User-defined lock names are stored in the attribute name tree. [SW]
      * Various help fixes [SW, Javelin]
      * LASTLOGOUT time now forces two-digit day for convtime niceness. [SW]
      * Very large malias names or member lists could cause buffer 
        overruns. [SW]
      * Buffer overrun fix, fix to str_chr. [TAP]
      * tprintfs removed from DEBUG output so DEBUG doesn't mess up
        messages in ^-commands anymore. [TAP]

& 1.7.3p6
Version 1.7.3 patchlevel 6                    September 20, 2000

Minor Changes:
      * Translation files are now archived separately on the ftp site.
      * A variety of options.h settings have been removed.
        EXTENDED_ANSI, DUMP_EMPTY_ATTRS, DUMP_LESS_GARBAGE and the *_LOCK 
        defines are totally gone. [SW]
        OLD_NEWLINES, DELETE_ATTRS and VISIBLE_EMPTY_ATTRS have been 
        moved out of options.h as they're special-purpose. [SW]
      * More common function error messages were made into variables 
        rather than being hardcoded in as string literals. [SW]
      * If a player is set HALT, their queued commands will not run.
      * Speedup in process_expression. [TAP].
Functions:
      * The regedit(?:all)?i? family of functions, like perl's s///. [SW]
      * Case-insenstive versions of regrab() and regraball(). [SW]
      * etimefmt(), which is to timestring() as timefmt() is to time(). [SW]
Fixes:
      * Error messages that were already variables are now translated. [SW]
      * Fixes to various metaconfig rules. [SW]
      * Open_Anywhere and Link_Anywhere were sharing the same
        bitmask. Fixed. [SW]
      * You can escape : in $command patterns that are being regexp-
        matched now. [SW]
      * Rewrites of the regexp functions so that, say, regrab() and
        regraball() point to the same actual code, using called_as to 
        know when to stop. They also use PCRE's match optimizing 
        pcre_study() function when appropriate. [SW]
      * Buglets in game/restart and game/mushcnf.dst fixed.
        Reported by Krad and Nymeria at M*U*S*H.
      * page_aliases directive in mush.cnf works now. Report by Nymeria.
      * Same for float_precision. Report by Oleo@M*U*S*H.
      * mushtype.h now included in compress.c. [DW]
      * Less noise in log/netmush.log from failed ident queries.
      * More strings marked for translation.
      * Fixes to problems with @search reported by Oleo@M*U*S*H. 
      * Weird evaluation of functions in softcoded commands fixed. [TAP]
      * Cleanup of typos here and there by Padraic@M*U*S*H.


& 1.7.3p5
Version 1.7.3 patchlevel 5                    September 7, 2000

Minor Changes:
      * FLOATING_POINT is no longer an option (it's always on). [SW]
      * EXTENDED_ANSI defaults to enabled. [SW]
Attributes:
      * @receive/@oreceive/@areceive triggered on the recipient
        after a get or give, so you've got access to who caused
        you to acquire the object and the object's dbref now.
      * @give/@ogive/@agive triggered on the giver with object's
        dbref in %0. Suggested by Oriens@Alexandria. 
Fixes:
      * Fixes for systems with broken or incomplete IPv6 support. [SW]
      * Uses of index() changed to strchr() for consistency. [SW]
      * Much removal of duplicate function prototypes and rearranging
        of headers.  hdrs/globals.h is now hdrs/case.h. hdrs/intrface.h is 
        no more, and hdrs/boolexp.h, hdrs/log.h were added. [SW]
      * @search supports "quoted player names".
      * We no longer report failed connect to ident servers in the log.

& 1.7.3p4
Version 1.7.3 patchlevel 4                    August 8, 2000

Major Changes:
      * Internationalization:
        * Support for international time formats via LC_TIME locale [SW]
        * Support for message translation
        * Support for locale-sensitive ordering of strings (LC_COLLATE) [SW]
        To take advantage of the new features, you should have your
        LANG environment variable set to an appropriate locale 
        before you 'make install' (which will cause the right message
        catalog to be compiled), and you should see the section 
        in game/restart for setting it there (which will actually cause
        the server to use it).
      * IPv6 support [SW]
Commands:
      * @dolist/delim and @map/delim [SW]
      * @stats/tables [SW]
      * SESSION command displays session statistics (experimental) [SW]
Functions:
      * uldefault(), like udefault but saves registers like ulocal() [SW]
      * switchall(), for Tiny compatibility. [SW]
      * cemit() with an option to act like @cemit/noisy [SW]
      * vmin() and vmax(), for returning the min and max of each pair in two
        vectors. [SW]
      * utctime(), convutcsecs() for UTC/GMT time instead of server-local. [SW]
      * convtime() uses getdate() if present, along with a variety of templates
      * that it can accept. [SW]
      * timefmt() - like the strftime() C function. [SW]
      * pcreate() side effect function suggested by Adamas and Padraic@M*U*S*H
      * starttime() now returns the first startup time, and 
        restarttime() returns the time of the last @shutdown/reboot [SW]
Minor Changes:
      * +help is mentioned in help help. Suggested by Trispis@M*U*S*H.
      * include directive for config files, with an example moving all
        the restrict_command's to another file. [SW]
      * make indent runs expand, then indent, because indent doesn't seem to
        handle tabs very well. [SW]
      * index-files.pl sorts patchlevels correctly. Patch by Jeff
        Heinen.
      * LASTLOGOUT attribute records logout time, like LAST, but not
        visual. Suggested by Oriens@Alexandria, and others.
      * Internal cleanup by David@M*U*S*H. New @config category 'messages',
        no more OBJECT_ENDOWMENT or OBJECT_DEPOSIT macros, etc.
      * Internal functions safe_integer(), safe_number(), and safe_dbref()
        to replace safe_str(unparse_FOO(data), buff, bp) calls  [SW]
      * You can now @trigger an attribute containing a $command or
        ^listen and it'll work (skipping the $...: or ^...: parts).
        So you can now do this:
         &DO_WHO obj=$who *: @pemit %#=[u(who,%0)]
         &DO_+WHO obj=$+who *: @tr me/do_who=%0
        (But you can do this much more efficiently with regexp...)
Fixes:
      * table() is less CPU-intensive in extreme cases. [SW]
      * Hopefully, Configure now determines pagesize on FreeBSD.
        Method suggested by Matt Harris.
      * CHAT_TOKEN_ALIAS comment clarification by Oleo@M*U*S*H.
      * pcre regexp engine updated to version 3.4.
      * Typo in @chan/who fixed by Vexon@M*U*S*H.
      * @attribute/access won't modify AF_INTERNAL attributes now.
      * Additional win32 portability fixes. [NJG]
      * con() was buggy in a bad way. Fixed now.
      * Configure -d should now work on linux systems that don't have
        crypt libraries. Reports by mith and Inek@M*U*S*H.
      * Fix to Z_TEL on things.
      * Help fix to @lock5 by Datron@SW2.
Languages:
      * Swedish and Hungarian translations for most strings are
        included in this patchlevel.


& 1.7.3p3
Version 1.7.3 patchlevel 3                    July 12, 2000

Major Changes:
      * Restrictions to the 7-bit ascii charset have largely been removed
        except in attribute names, to help international users. [SW]
      * If available, we now use setlocale to support international
        charsets (and eventually other conventions, though this should
        be considered experimental). If you set your LC_CTYPE environment
        variable to, say, 'fr_FR', french-accented characters should work.
        Wide (multibyte) charsets are not supported.
Minor Changes:
      * Internal cleanup of page/whisper code by David@M*U*S*H.
      * New mush.cnf directive, page_aliases, for showing alias of
        paging player. Supported by code by David@M*U*S*H.
        Requested by many. A contrib version by Flame dates to 1996.
      * @chat on a non-existant channel returns an error message. [SW]
      * Two new CRYPT_SYSTEM options. One checks both SHS and crypt(3)
        for passwords, and saves them back using SHS. The other does 
        the same for plaintext passwords. These should encourage folks
        who currently use crypt(3) to make a painless move to SHS. [SW]
Commands:
      * @remit can take /silent and /noisy switches now. Suggested by
        Philip Mak.
      * @lemit and @emit can take /silent switch. [SW]
      * @config/set can set configuration parameters at runtime. [SW]
Functions:
      * The set algebra functions can be given a sort order for output. [SW]
Fixes:
      * CHAT_TOKEN_ALIAS could get defined w/o a character value.
        Added a better explanation of CHAT_TOKEN_ALIAS in options.h.dist.
        and fixed utils/update.pl to handle commented defines that take 
        values a bit better. Report by Nymeria@M*U*S*H.
      * You can no longer initiate following a disconnected player.
        Report by Dave@Galactic.
      * CHANGES for 1.7.1 and 1.7.0 were missing. Back now.
      * Typo in options.h.dist corrected. Report by Padraic@M*U*S*H.
      * Small Configure portability improvements.
      * Better handling of cases where the maildb has messages from
        dbrefs that are out of range (due to truncating a db to remove
        corruption, for example). Suggested by Ashen-Shugar.
      * We now check for sitelocked sites before asking info_slave to
        do ident lookups.
      * Many help clarifications. [SW]
      * linux Configure can use nm to find symbols, finally.
      * help locate() now includes the z flag.


& 1.7.3p2
Version 1.7.3 patchlevel 2                    June 3, 2000

Commands:
      * New @sitelock options to control access to god, wizards, admin
        by site. [SW]
      * @force can now take /noeval [SW]

Functions:
      * squish() can take a second argument to squish non-spaces. [SW]
      * div(), floordiv(), modulo(), and remainder(), a set of functions
        jointly adopted by MUSH and MUX servers for compatibility. [TAP]
      * @@() and null() functions suggested by [LdW].

Minor Changes:
      * @uptime now shows initial restart time, not just time since
        last reboot.
      * Each player now has a limit to the number of @mail messages
        in their inbox (folder 0), configurable in mush.cnf.
        Suggested by Edwin@M*U*S*H.

Fixes:
      * More linting and improved indenting [SW]
      * PARANOID works right for broadcast messages (like @cemit) now
        too. Report by Vexon@M*U*S*H.
      * You can no longer follow what you can't see.
      * CHAT_TOKEN_ALIAS info appears in options.h now. Report by 
        Rhysem@M*U*S*H.
      * Mac portability changes. [DW]
      * Disconnected players don't follow any more. Suggested by Don Burks.
      * Various fixes to better resist crashing due to attacks involving
        overwhelming connections. 
      * @mail/stats for all was broken. Fixed now.
      * Clearer message after failed @pemit. Suggested by Rince@M*U*S*H
      * Destroyed things stop following/leading. Report by Ashen-Shugar.
      * follow didn't properly set up the followers as enactors.
        We no longer short-circuit process_command. Report by Moe@Chicago.

& 1.7.3p1
Version 1.7.3 patchlevel 1                    May 18, 2000

Commands:
      * @oemit now takes a list of players. Adapted from patch by Philip Mak.

Minor Changes:
      * Reconnecting is less spammy - we don't show motds again
        to players already connected. Suggested by Trispis@M*U*S*H.

Fixes:
      * Configure problem that resulted in weird compile failures on
        bind/accept in src/bsd.c fixed.
      * Further linting. [SW]
      * FreeBSD getrlimit problem diagnosed by [SW] is worked around.
      * Couldn't compile w/o FLOATING_POINTS defined. Fixed.
      * Fixed a few dependencies in the Makefiles to insure that
        hdrs/patches.h and hdrs/switches.h are rebuilt properly.
      * Indentation cleanup.
      * We now recognize egcs as if it were gcc 2, and set ccflags
        accordingly.
      * Increased size of some hash tables for performance. [SW]
      * Help fixes. [SW]
      * flags(obj/attrib) behaved badly unless attrib was CAPITALIZED.
        Fixed now. Reported by Vexon@M*U*S*H.

& 1.7.3p0
Version 1.7.3 patchlevel 0                    April 20, 2000

Major Changes:
      * If you create a 'patches' subdirectory and keep any user-contrib
        patches you apply in there, and if the patches are properly 
        formatted, i.e., they include these lines:
              # Patch name:
              # Patch version:
        your MUSH's @version and INFO output will report them.
        In addition to being helpful for you, this will help the
        developers when you send us a bug report including your 
        @version. [TN]
      * As @cemit doesn't override @chan/gag and allows 
        NOSPOOF notification, it basically now operates just like
        @pemit/list (you can protect yourself from spoofing, and you can
        silence it). Accordingly, the cemit power is no longer 
        necessary. It's now a runtime option.
      * @malias (@mailing lists) by Daniel Peters.
      * Attribute names are now stored in a single string tree,
        so we don't have thousands of copies of the string
        "FINGER_NOTE", etc., taking up memory. [TAP]
      * As a consequence of the attribute name tree, the STARTUP flag 
        is no longer needed, and will be automatically removed from
        dbs.
      * Attributes are now inserted in alphabetical order, which
        speeds lookup. [TAP]
      * Panic dumps now dump the maildb and chatdb, appended to the
        end of PANIC.db. The MUSH handles breaking them up on restart.
      * New link_anywhere power allows @link'ing to any destination.
      * Mortals may create VARIABLE exits. At the time the destination 
        is computed, the exit is check to see if it has permission to
        link there (i.e., the exit controls the destination or the
        exit is link_anywhere or the destination is link_ok).
        To keep old code from breaking, all existing variable exits are 
        given the link_anywhere power at first db read in this patch.
        Suggested by David@M*U*S*H.
      * The follow command is implemented!
      * Nested iter is now useful. The itext(n) function returns
        the value of ## for the nth innermost iteraction, where
        0 is the most inner, and inum(n) does the same for #@. [TN]
      * New regexp library, pcre, now allows perl 5.005 compatible
        regular expressions! Suggested by [SW].
      * Objects are now limited in the number of attributes that may
        be set on them. This prevents a DoS attack. Suggested by
        Ashen-Shugar.
      * Some more english-style matching (look my 2nd box). [TN]

Functions:
      * config() returns a list of config option names. 
        config(<option>) returns the value of a config option.
        (e.g. config(money_singular))
      * sort() now accepts an output delimiter, a la iter().
        Suggested by Jason Newquist.
      * channels() now accepts a delimiter. Suggested by Trispis@M*U*S*H.
      * money(<integer>) returns the name of the money, either singular
        or plural, depending on <integer>. Suggested by Trispis@M*U*S*H.
      * timestring() with a pad flag of 2 forces 2 digit numbers.
        Suggested by Trispis@M*U*S*H.
      * fmod() function returns floating point remainder on division.
        Written by Michael Thole.
      * brackets() function returns bracket counts for its unparsed
        argument. Handy for debugging. By Jason Wilcox.
      * edit() can take multiple find-replace pairs. By Chili@M*U*S*H.
      * clock() function by Ari@SpaceMUSH and Chili@M*U*S*H.
      * flags() function can show attribute flags as well. 
        Suggested by Kami@SW2
      * mailstats(), mailfstats(), and maildstats() added by Kami@SW2
      * nattr() (aka attrcnt()) returns number of attributes on 
        an object. Suggested by Ashen-Shugar.
      * map() and foreach() now provide the element's position
        through %1. [LdW]
      * spellnum() function spells out numbers in words. [LdW]
      * wrap() for server-based line wrapping. Adapted from code by [LdW]
      * lmath() function lets you do math on delimited lists, and makes
        it easy to emulate Tiny's ladd/lsub/etc. [SW]
      * bitwise math functions. [SW]
      * mean(), median(), and stddev() functions. [SW]
      * bound() function for bounding numbers. [SW]
      * regrab(), regraball(), and regrep() regular expression 
        versions of grab/graball/grep. [SW]
      * controls() can now be used if you control either the <obj> or
        the <victim>. [RLM] suggested this in July 1998, but we were
        too boneheaded at the time to agree on it.

Commands:
      * teach <command> shows others in your room the (unparsed)
        command that you want to demonstrate, and then causes you
        to execute it. Suggested by Reed Riner.
      * /preserve switch for @clone and @chown to preserve privbits.
        By Kurt Fitzner.
      * rpage and rwho have been removed.
      * @nameformat on a room allows you to specify how the room's
        name should be displayed to those inside it when they look.
      * An optional second token for chat (in addition to +) can
        be set if you'd like + and = (or whatever) to both work.
        Patch by Kami@SW2.
      * @scan returns the matched attribute name as well as object.
        Suggested by many, including Thi@M*U*S*H.
      * ; waves is treated as :waves, instead of as ;waves.
        Suggested by Sandi Fallon, for tiny compatibility.
      * cv command at connect screen forces a !DARK connect.
        Suggested by David@M*U*S*H.
      * with obj=command tries a $command on a specific object. [TN]
      * @mailsignature finally implemented.
      * @chan/join and @chan/leave are aliases for @chan/on and @chan/off,
        respectively. Suggested by [LdW]
      * @chan/decomp/brief decompiles a channel without listing players.

Flags:
      * LISTEN_PARENT flag causes the object to inherit ^listens
        from its parent. By Kurt Fitzner.
      * Internal ACCESSED flag removed.
      * PARANOID player toggle replaces the old paranoid_nospoof
        configuration directive, and allows per-player setting of
        nospoof format. Suggested by Trispis@M*U*S*H

Minor Changes:
      * New lock @lock/command controls who may use $commands on an
        object. @lock/listen controls ^patterns, @lock/use controls both.
        Patch by Kurt Fitzner.
      * The max_obj_val and max_wiz_obj_val configuration options
        have been removed, as they're rarely used. You can change them
        in hdrs/conf.h (search for ENDOWMENT).
      * src/connect.c is no longer distributed. It wasn't ever used
        for anything anyway.
      * @fixdb command removed.
      * @config/functions and commands can show listings in lowercase.
      * match_list changed to try to match player aliases. Allows
        "look <alias>" for a player in the same room. Reported by Corum.
      * See_All players can now see/check AF_WIZARD attributes
        (but AF_MDARK still requires that you be roy/wiz).
        Suggested by Balazs Gasparin.
      * VERBOSE PUPPETs relay to their owners even if the owner's
        in the same room. Dedicated to Julianna@ATS.
      * You may now @dest objects that you control via a zone,
        as you could have done so indirectly before anyway.
        Reported by [LdW]
      * Sending the MUSH process an INT signal now causes graceful
        shutdown (not panic dump). Sending a USR2 signal causes
        a normal dump. As before, HUP causes config reload and
        TERM causes a panic dump. [TAP]
      * @chan/list shows your gag status. Suggested by Matt@M*U*S*H
      * When chatting, we only match partial channel names against
        channels you're actually on. Suggested by Matt@M*U*S*H
      * By default you can no longer speak to a channel you're not
        on. This is configurable per-channel with the new "open"
        priv. Suggested by Akiko@M*U*S*H.
      * If you can't go through an exit because it's linked to
        garbage or its variable destination is invalid, we no longer
        process the SUCC and DROP message set on the exit.
      * The Inherit() macro no longer includes a Wizard test -- we
        don't need it anymore as we protect Wiz objects in controls().
      * getrandom has been replaced by get_random_long, with a better
        algorithm and interface. Suggested by Stephen Dennis. [TAP]
      * Win32 compilers now get the __cdecl hint so they can compile
        using __fastcall which can greatly increase speed. Patch by
        Stephen Dennis.
      * For WIN32, use GetSystemTime instead of timeGetSystemTime.
        Patch by Stephen Dennis.
      * For WIN32, use a combination of wsadata.iMaxSockets and
        options.max_logins to pick a reasonable number of available file
        descriptors. Patch by Stephen Dennis.
      * Default dump messages now call it a 'save', not a 'dump',
        to avoid newbie confusion. Suggested by Vedui.
      * You're notified if you set an attribute/flag on a quiet object
        that you don't own. Patch by Kurt Fitzner.
      * @decomp now comments its "No attributes found" message so as
        not to break scripts.  Report by Kurt Fitzner.
      * More Mac tweaking. [DW]
      * \ and % are no longer valid in attribute names. Suggested by Ali Abdin
      * Cleanup to logging code. We now try to do almost all of it through
        log.c functions for better encapsulation. Patch by David@M*U*S*H.
      * New @lock/examine to restrict who may examine visual objects.
        Suggested by [LdW]
      * Examining objects now shows channels they're on, if any.
        Suggested by Big Spoon@M*U*S*H.
      * Channel-hidden players are now marked in @chan/who for those
        who are allowed to see them.
      * @uptime shows more upcoming events, and shows them to mortals.
        Suggested by Kyieren@M*U*S*H.
      * @chzone obj works like @chzone obj=none. Suggested by Mystery8@M*U*S*H
      * Player creation is now announced to MONITOR players. Suggested
        by Paul@M*U*S*H.
      * Poll message kept across @shutdown/reboot. Suggested by [SW].
      * The military_time directive is removed from mush.cnf. It only
        affected the way time was shown in @idle/@haven/@away messages
        anyway. Reported by Angelus@M*U*S*H.

Fixes:
      * help for lnum() and dig() improved. Leo@ATS TrekMUSH
      * help for @charges improved. Suggested by Scott Weber
      * @mvattr a/b=a/b would clear the attribute. No longer.
        Reported by Octavian@M*U*S*H
      * type(obj) would log a "WEIRD OBJECT" message if obj was 
        a garbage object. Reported by RLM. [TAP]
      * Bug in deciding when to take a penny for queued commands fixed
        by Stephen Dennis.
      * Portability fixes for gcc 2.95.2 and other compilers who require
        that function pointers in prototypes include the function args. 
        Reported by Gepht.
      * @chan/decomp should include the channel description, too. 
        Report by David@M*U*S*H.
      * Two other ways to be inside an object inside yourself reported by
        Ashen-Shugar, and one by Rhysem@M*U*S*H.
      * Small memory leak when doing @cpattr of a standard attribute to a
        non-standard attribute is fixed.
      * Help clarification for pemit() suggested by Falor@M*U*S*H.
      * Help parents and @search3 fixed. Suggested by rodregis@M*U*S*H.
      * Tport_anything didn't allow teleporting things to exits. 
        Noted by Vexon@M*U*S*H.
      * Z_TEL flag works on ZMO's as promised now. Report by [SW].
      * Potential crash in moveit fixed. Report by Howie@NF TrekMush
      * @cemit now does the checks that @chat does, in regard to being
        of the right type, allowed to speak, on the channel, etc.
        Suggested by Oleo@M*U*S*H.
      * getstring_noalloc was doing an fgetc into a char variable,
        instead of an int, so wasn't 8-bit clean. Report by Slava.

& 1.7.2p35
Version 1.7.2 patchlevel 35                        January 27, 2001

Fixes:
      * Fixed a bug in filter introduced in p34. Report by Jason Rhodes.
      * Help for sort() now indicates that 'n' sorts integers. Report by
        Dave Milford.


& 1.7.2p34
Version 1.7.2 patchlevel 34                        October 2, 2000

Fixes:
      * filter now looks at the whole result, not just the first
        character, when checking if the filter function returned '1'. [SW]
      * raw_input and raw_input_at are now unsigned char *, so
        they build right on HP/UX and similar. Report by Jeff Hildebrand


& 1.7.2p33
Version 1.7.2 patchlevel 33                        August 17, 2000

Fixes (backported from 1.7.3p4):
      * Bug in con() patched.
      * Bug in deciding when to take a penny for queued commands fixed
        by Stephen Dennis.
      * Configure portability fixes
      * Better handling of cases where the maildb has messages from
        dbrefs that are out of range (due to truncating a db to remove
        corruption, for example). Suggested by Ashen-Shugar.
      * Various fixes to better resist crashing due to attacks involving
        overwhelming connections. 
      * @mvattr a/b=a/b would clear the attribute. No longer.
        Reported by Octavian@M*U*S*H
      * type(obj) would log a "WEIRD OBJECT" message if obj was 
        a garbage object. Reported by RLM. [TAP]
      * Small memory leak when doing @cpattr of a standard attribute to a
        non-standard attribute is fixed.
      * Tport_anything didn't allow teleporting things to exits. 
        Noted by Vexon@M*U*S*H.
      * Z_TEL flag works on ZMO's as promised now. Report by [SW].
      * Potential crash in moveit fixed. Report by Howie@NF TrekMush
      * getstring_noalloc was doing an fgetc into a char variable,
        instead of an int, so wasn't 8-bit clean. Report by Slava.

& 1.7.2p32
Version 1.7.2 patchlevel 32                        April 17, 2000

Fixes:
      * @cpattr from a non-standard attribute to a standard one
        didn't preserve the AF_STATIC flag, and a subsequent atr_clr
        could cause a crash.

& 1.7.2p31
Version 1.7.2 patchlevel 31                        April 9, 2000

Minor Changes:
      * The SAY_TOKEN now applies to channels. That is, +public "Hi!
        will not result in a doubled initial quote any more.
        Suggested by Tyler Spivey.
Fixes:
      * Uninitialized negate_perms in the monitor flag table.
        Report by Concordia@Beyond the Fire.
      * Updates to help changes to match CHANGES.
      * Another way to end up in an object in your inventory has been 
        fixed. Report by Lensman.
      * Unused ancient ccflags cruft removed from hints files.
      * Considerable linting and cleanup. [SW]
      * MacOS portability improvements. [DW]
      * You may reset your @alias to itself in different case.
        Suggested by Bolt.

& 1.7.2p30
Version 1.7.2 patchlevel 30                        March 14, 2000

Major Changes:
      * New US export rules allow us to include shs.c and funcrypt.c
        in the Penn distribution! Yay!
      * Code is included in bsd.c for Windows NT users that uses
        NT's native i/o instead of the bsd socket layer for
        much improved performance. If you want it, edit src/bsd.c
        and uncomment the define at the top. [NJG]
Minor Changes:
      * New eplayer, eroom, eexit, eobject classes for searches,
        like Tiny. By Rhysem.
      * @sitelock/access.cnf can now use regexp patterns. By Raevnos.
      * The Exits() macro is replaced with Source(), Home(), etc.
        where sensible. By Maverick@M*U*S*H.
      * Example of bzip2 compression defines in mushcnf.dst by David@M*U*S*H.
      * shs.c can now be configured to reverse endianness, so you
        can more easily use win32 dbs on unix (or vice versa) without
        password hassles. This is in mush.cnf. [NJG]
      * JUMP_OK no longer allows anyone to @tel an exit into your room.
        You must control the destination or have the open_anywhere 
        power in order to do this now. Report by rodregis.
Fixes:
      * Calling do_log with LT_TRACE resulted in no logging. Report by David.
      * MacOS (and general) portability improvements, suggested by [DW]
      * help for before(), after() notes case-sensitivity. By Audumla.
      * hasflag() didn't work with MONITOR. Report by Mystery8.
      * A little more linting. [NJG]
      * Fixed help reference to 'global functions'. Report by Falor.
      * Some gmalloc fixes around missing newlines. Report by Raevnos
      * Improvements to help switch(). Report by Omozali.
      * Buffer overflow in @wall fixed. Report by rodregis.
      * Fixed (I think) the FreeBSD/Linux problem of not finding
        sigchld/sigcld and similar ilk. Hints for FreeBSD are back.
      * Crash bug in @link fixed. Report by Howie@New Frontier TrekMUSH

& 1.7.2p29
Version 1.7.2 patchlevel 29                        January 23, 2000

Fixes:
      * src/sig.c didn't include config.h. As a result, some systems
        with sigaction that didn't keep signal handlers installed
        (some linuxes) would crash very quickly on the second SIGALRM.

& 1.7.2p28
Version 1.7.2 patchlevel 28                        January 14, 2000

Minor Changes:
      * New 'deny_silent' option for access.cnf sites.
        Turns off logging of denied connection/creation/guest/register
        from a site, to prevent logfile spamming by twinks.
        Reported by Kludge-BC.
      * TFPREFIX attribute, if set, is used in place of FugueEdit>
        in @decomp/tf. [SW]
      * @grep/print no longer requires you to be set ANSI. Suggested 
        by Philip Mak.
      * Improved reporting of function invocation limit. [TAP]
      * /noeval switch added to think command.
      * Changes to enhance portability to Mac 68k platform and others
        that need < 32k of local data per function. [DW]
      * Objects are only considered to be listening if they're
        connected players, puppets, have an @listen set, or
        are things/rooms with MONITOR flags. Previously, things/rooms
        with ^patterns in attributes were considered listeners, even if
        they weren't MONITOR. Suggested by Luke.
Fixes:
      * gmalloc.c updated from 1987 version to 1995 version. By Gepht.
      * help corrections for shl and shr by Vexon@M*U*S*H.
      * help corrections for @clock by Krad@M*U*S*H.
      * RLIMIT_NOFILE bug fixed by Susan Thorne.
      * Eliminated variables named 'new' to promote easier C++
        compiles. Suggested by Gepht.
      * Compiling with CSRI_TRACE works again. [TAP]
      * signal stuff broken out to src/sig.c to allow link w/info_slave.
      * strcasecmp and friends prototyped better in externs.h. [DW]
      * Overzealous test for inherit flag on zoned objects corrected
        by Nveid.
      * Clearing an @attribute'd attribute's value on some object
        and later manipulating the attribute could corrupt the
        @attribute table in some cases. Fix suggested by Kami@SW2.
      * Nested pemits could truncate one another. Reported by Alierak.
      * Channel messages didn't correctly set %#. Reported by Saberwind.
      * info_slave used ident even if use_ident was off in the 
        mush.cnf file. Reported by Rhysem.

& 1.7.2p27
Version 1.7.2 patchlevel 27                        September 22, 1999

Minor Changes:
      * Added Raevnos's sitelock/name patch to allow removing names
        with @sitelock/name !<name> and to fix a display bug.
      * bsd.c, info_slave.c, and player.c now deal in IP addresses as well
        as hostnames (which can be spoofed), providing more reliable logging
        and access control. IP addresses are stored in the LASTIP attrib
        on players, as per LASTSITE. Suggested by David@M*U*S*H.
      * Hidden connections are announced as per DARK ones. Suggested 
        by Julianna@ATS.
      * New /noisy switch to @cemit prepends <Channel> to message.
        Suggested by Spork@M*U*S*H.
Fixes:
      * help vmul() incorrectly defined the dot product (which vdot() does).
        Reported by [SW].
      * Typo fixed in help @set3. Reported by Logain@ATS
      * Typo fixed in help @emit. Reported by Rhysem@M*U*S*H.
      * Various help fixes by mith, Big Spoon, and Krad@M*U*S*H.
      * @function now works for mortals as the help indicates. Report by mith.
      * @log/wipe should be @logwipe in comments in mushcnf.dst. 
        Report by Spork@M*U*S*H.
      * Object names are now limited to 256 characters. Fixes some
        buffer overflow issues.

& 1.7.2p26
Version 1.7.2 patchlevel 26                        July 18, 1999

Minor changes:
      * @verb didn't save stack args before dealing with the WHAT/OWHAT
        msgs, as TinyMUSH does. Changed to emulate TinyMUSH.
        Reported by Angel. [SW]
Fixes:
      * The noeval-eqsplit fix cause weirdness with attribute setting by
        directly connected players when specifying the obj by function.
        Fixed. Reported by Julienna@ATS.
      * Wizards couldn't modify atrlock'd attribs without breaking the 
        lock first. [SW]
      * @find by Wizards showed all garbage objects. Reported by mith.


& 1.7.2p25
Version 1.7.2 patchlevel 25                        July 10, 1999

Minor changes:
      * New 'nofixed' command restriction, by popular demand.
      * CONFIGURATION messages in netmush.log shortened to CONFIG.
        Suggested by mith.
      * Attributes with the Wizard flag can no longer by created/modified
        by any non-wizard, even that attribute's owner. Reported by
        Kurt Fitzner.
      * @pcreate now shows the dbref of created player. Suggested by
        Oderus.
      * When you receive an @mail message, you're now told the number.
        Suggested by Rak@M*U*S*H, among others.
      * The @toad command has been removed. The security issues it
        presents, though not unsolvable, aren't worth solving just to
        provide Wizards with a humiliating alternative to @newpassword.
Fixes: 
      * %q0-%q9 were not preserved during evaluation of player-message
        attributes (DESC, SUCC, DROP, etc.) Reported by Geoff Gerrietts
      * Added some hints from FreeBSD. Suggested by Lord Argon of mux.net.
      * Better Configure handling of library paths. 
      * 'nogagged' wasn't working correctly in restrict_command. Fixed.
      * @search on rooms sometimes reported a null room. Reported by mith.
      * Nearly all source files now include conf.h (which includes options.h), 
        and do so before any other PennMUSH header file except config.h 
        and copyrite.h.  Suggested by Joel Ricketts.
      * Fixed a few comparisons of <= db_top. Reported by Kurt Fitzner.
      * @oemit <obj>=<message> was emitting to the enactor's location,
        rather than to <obj>'s location, as it should have been. Fixed that
        and fixed help oemit() which documented this wrong behavior.
        Reported by Kurt Fitzner.
      * An 8-bit-unclean construction in bsd.c fixed by Christoper/Chicago.
      * p/noeval <message> (repaging) eval'd message anyway.
      * Args to $commands that looked like functions were being eval'd
        even if not in brackets. Reported by [SW]. [TAP]
      * @lock/listen could cause weird pose corruption. Reported by
        David@M*U*S*H. [SW]
      * Clarification of wiz_noenter in mush.cnf suggested by 
        Interloper@M*U*S*H.
      * Bug in orflags/andflags could cause weird results with toggles.
        Like nospoof players tested positive for 'J'. Reported by Saberwind.
      * Bug in make customize fixed. Reported by Saberwind.
      * References to a PASSWORD attribute removed from help. Reported by
        Saberwind.
      * Fixed db_top bug in search/lsearch reported by Saberwind.
      * @halt code was screwy. Reported by Krad@M*U*S*H
      * Wizards could grant @powers to God. Reported by Saberwind.
      * delete() with negative position arg could crash. Reported by
        Ashen-Shugar.
      * @clone of an exit while inside an object could have unpredictable
        effects. Reported by Andy@RobotechMUSH
      * Typo in help aposs() fixed. Reported by Philip Mak.
      * @hide now defaults to @hide/on. Reported by Saberwind.
      * ldelete() added help list functions. Reported by Rak@M*U*S*H
      * @attribute/rename didn't update the attribute's name quite right.
        Reported by mith.
      * @clone by a room didn't properly set the cloned object's location.
        Reported by Philip Mak.

& 1.7.2p24
Version 1.7.2 patchlevel 24                        April 5, 1999

Fixes:
      * @search/lsearch didn't behave right when given an upper range
        argument of exactly the highest dbref in the db. Reported by
        [SW].
      * Unlinked and HOME-linked exits were mishandled during dbcks, 
        just like variably-linked ones in pl23. Reported by [SW].
      * Help fixes. [TAP]

        
& 1.7.2p23
Version 1.7.2 patchlevel 23                        April 2, 1999

Fixes:
      * The NoLeave() macro was misdefined, but also not used (whew).
        Now it's defined right and used.
      * Giving a / without a switch to commands caused unpredictable
        behavior. Fixed. Report by Broncalo@Dune III.
      * Variable-linked exits were mishandled during dbcks, resulting in
        them being relinked to their source rooms.
      * @grep/iprint showed the hilighted matches in the same case as 
        the pattern was given, rather than the case there were in the
        attribute. Reported by Philip Mak.
      * The LAST attribute was set differently when players created and
        when the later connected. The latter case wasn't appropriately
        prepending single-digit dates with a 0, which fouls up convtime()
        calls on LAST. Noted by [SW].


& 1.7.2p22
Version 1.7.2 patchlevel 22                        March 19, 1999

Minor changes:
      * More extensive macro cleanup, based on a patch by David@M*U*S*H
      * Notable for your own code: Inherit() is now Inheritable(),
        DarkLegal() checks if something's ok to be invisible when it's DARK,
        Destroyed() is now IsGarbage(), and some other new helpful macros
        can be found in hdrs/dbdefs.h
      * Objects now store their creation cost, not their 'value' (which
        used to be cost/5 - 1, and had relevance for sacrificing, a now
        obsolete concept). There is no longer a limit on how much you
        can spend to create an object, and it's all refunded when the
        object is recycled. Reported by David@M*U*S*H.

Fixes:
      * Two memory leaks and one unbalanced mem_check fixed. [SW]
      * @oemit <room>/<object> was broken in many ways. 
        Reported by [SW].
      * Help @drop/@odrop/@adrop updated to mention use on exits.
        Suggested by Stewart Evans.
      * God using @logwipe and giving the wrong password crashed the MUSH.
        [SW]
      * search() was behaving as lsearchr() not lsearch(). Noted by
        KMoon.
      * Bad range arguments for @search and lsearch() now give an
        error message and don't charge the player. [SW].
      * Help @search3 had a typo. Fixed by Halatir@M*U*S*H.
      * Restricting the 'goto' command now also restricts movement
        through exits. Suggested by Christopher Poff.
      * Objects and rooms now notify their contents when they start/stop 
        listening. Report by [RLM].
      * Error in help for @channel referring to @config. Krad@M*U*S*H


& 1.7.2p21
Version 1.7.2 patchlevel 21                   February 16, 1999

Minor changes:
      * The restart script now tries to determine its own directory,
        so it may not require editing to set GAMEDIR any more.
        Idea by David@M*U*S*H.
      * Various @find/@search/@entrances commands charged you the
        FIND_COST even if you didn't have permission to run the command.
        We don't do that any more. Report by Jonathan Booth.
      * $command and ^listen pattern matching is now case-insensitive
        even when the attrib is set REGEXP, unless the attrib is set
        CASE. In the past, glob matching was case-insensitive and
        regexp matching was case-sensitive, which cause problems if
        you tried to regexp match a disabled standard command.
        Now you've got full flexibility. This may break any current
        regexp-based $command or ^listen matching that relies on
        case sensitivity (set those attributes CASE). We now also
        have a new insensitive regmatch function: regmatchi()
        Report by Jonathan Booth.

Fixes:
      * Anyone could @chan/priv channels, even if they didn't pass
        the modlock. Report by David@M*U*S*H.
      * DARK disconnects are now shown correctly on chat channels.
        Really this time. :) Report by Broncalo@Dune III
      * help for CONNECTED flag updated. Report by matcat@M*U*S*H
      * Using @kick within a user-defined command could crash the MUSH.
        Reported by Kludge-BC. [TAP]


& 1.7.2p20
Version 1.7.2 patchlevel 20                   January 26, 1999

Minor changes:
      * Many expression replaced with macros by David@M*U*S*H.
Fixes:
      * @mail/silent/urgent didn't set the message urgent. 
        Patch by Halatir@M*U*S*H.
      * You could get free coins by repeatedly killing your objects.
        Reported by Max@M*U*S*H. [TAP]
      * You could rename a channel to a name already in use.
        Reported by David@M*U*S*H.


& 1.7.2p19
Version 1.7.2 patchlevel 19                   December 2, 1998

Minor changes:
      * The main select() polling loop now times out every second,
        so we will reliably call local_timer() and handle alarms
        every second. Suggested by [NJG].
      * 'make' now performs a make in game/txt, assuring that help
        indices are rebuilt after a patch. Suggested by Broncalo@Dune III.

Fixes:
      * Crash in using @cpattr with standard attribs fixed.
        Reported by Atuarre@ATS.


& 1.7.2p18
Version 1.7.2 patchlevel 18                   November 25, 1998

Minor changes:
      * Guest players don't receive a paycheck any more. Suggested by
        Kyieren@M*U*S*H
      * look_helper() internal function now uses privtabs. As an
        epiphenomenon, @set obj/attr=locked is now synonymous to
        @atrlock obj/attr=on. Suggested by [SW].

Fixes:
      * Win32 compile fixes. [NJG]
      * DARK disconnects are now shown correctly on chat channels.
        Report by Broncalo@Dune III
      * Quiet players no longer see 'Title set.' messages when
        using @chan/title. Patch by Halatir@M*U*S*H.
      * @cpattr/@mvattr now copy attribute flags. Report by Jon Booth.
      * Some compiler warnings fixed by Atuarre.
      * The 1 and 5 minute dump warning messages weren't being used.
      * When matching regexp's, later parenthesized subexpressions 
        weren't correctly assigned to %-vars when earlier ones 
        were empty. Report by Geoff Gerrietts. [TAP]
      * Some messages as a result of looking at a room were being
        placed onto the wrong queue, so remote viewers (@listen *,
        @pemit/remit to somewhere) would get things out of order.
        Reported by David@M*U*S*H. 
      * Help added for functions() and fixed for timestring(). 
        Report by Geoff Gerrietts.
      * soundex() misbehavior for very short words fixed.
        Report by kmoon.
      * @attribute/access acted as if it were always /retroactive. [SW]
      * Changes of flags on a standard attribute were lost across
        restarts. Reported by [SW].
      * lcstr, ucstr, capstr, and encrypt and decrypt in the 
        "real" funcrypt.c are now ansi-aware. The former 3 preserve
        ansi formatting, while the latter two strip it. You must download
        a new version of funcrypt.c from ftp.pennmush.org (USA/Canada)
        or export.pennmush.org -- it is not patched herein. 
        Reported by Ashen-Shugar.


& 1.7.2p17
Version 1.7.2 patchlevel 17                   November 11, 1998

Minor changes:
      * Newly created players now have a default uselock of =me.
      * Number of available file descriptors is printed in startup log.
        Suggested by Doogie@ATS Trekmush.
      * The @chat/@cemit commands can no longer be used by gagged players.

Fixes:
      * Adding functions in funlocal.c shouldn't produce compiler warnings.
        Patch by Halatir@M*U*S*H
      * log(0) or ln(0) could crash non-IEEE compliant math libraries.
        Reported by Drakwil and Talos at SNW.
      * csrimalloc wouldn't compile with glibc. Fix by Mike Selewski.
      * Order of checks for number of file descriptors changed to
        do better on POSIX and hybrid systems like FreeBSD. Suggested by
        Doogie@ATS Trekmush.


& 1.7.2p16
Version 1.7.2 patchlevel 16                   October 17, 1998

Fixes:
      * table() could be used to crash the MUSH. Report by Ashen-Shugar. [TAP]
      * whisper/list didn't work. Report by Kamala@ATS TrekMUSH, via
        Mikey@M*U*S*H 
      * andflags(player,C) checked for the (useless) CHOWN_OK flag
        rather than the COLOR flag. Its now been special-cased to
        check COLOR on players. This is a kludge, but probably worth it.
      * Top of admin WHO now lists 'Loc #' not 'Room #', as that's more
        accurate. Suggested by Saberwind.
      * @log/wipe returns as @logwipe. Its absence was reported by 
        Nveid@M*U*S*H.
      * Date in hdrs/version.h now y2k compliant.


& 1.7.2p15
Version 1.7.2 patchlevel 15                   September 7, 1998

Fixes:
      * @emits weren't propagated through AUDIBLE exits. Report by Nammyung.
      * Building w/o ROYALTY_FLAG defined works again. Report by Scott Weber.
      * When matching $ or ^ patterns with the REGEXP attribute flag set,
        a failed match would then be improperly checked for normal 
        matching as well. Reported by Jason Rhodes.
      * Attribute flags weren't listed in @decomp. Reported by
        Jonathan Booth.
      * Make customize never got updated to match the new mushcnf/restart
        system. Now it has. Reported by Manic@FinalFrontier
      * @edit now works on attribs starting with _. Reported by Jason Rhodes.
      * Help files should work better on Win32. Reported by Miphon. [TAP]


& 1.7.2p14
Version 1.7.2 patchlevel 14                   August 4, 1998

Minor Changes:
      * You may @parent to an object you control via ZMO, even if you
        don't own it. Patch by Halatir@M*U*S*H
      * In lsearch() and @search, you may refer to object types
        in either the singular (ROOM) or plural (ROOMS).
      * Most chat messages now include the name of the channel. 
        Suggested by Philip Mak.

Fixes:
      * Long @chat messages crashed the server. Reported first by Rusty
        and Siris@M*U*S*H. [TN]
      * Setting the ZONE flag on a non-zonelocked player should give
        a warning, and wasn't. Reported by Halatir@M*U*S*H
      * @@ was parsing its argument. No longer. [RLM]
      * The @config listing was weird w.r.t. compression. [TN]
      * @shutdown/reboot could cause a crash if a player had an
        OUTPUTPREFIX or OUTPUTSUFFIX set.
      * Hint to linux users about undefining I_MALLOC when using
        gmalloc. Reported by Kyle Forbes.
      * @shutdown/reboot now calls local_shutdown(). Reported by Kyle Forbes.
      * When loading a db in which an object with dbref n has attributes
        owned by players with dbrefs > n, the attribute ownership was
        reset to GOD. This should no longer happen unless the owner 
        really is invalid. Most recently noted by [SW].
      * Exits that have contents (corrupt!) are fixed up in dbck.
      * dbck is run whenever the db is loaded.
      * objeval() help fixed. Reported by Yeechi Chen.
      * Compiling without ROYALTY_FLAG defined was broken. Reported by
        Scott Weber.
      * Sufficiently tricky use of locks could cause a crash due to
        massive function invocation or recursion. Reported by Atuarre. [TN]


& 1.7.2p13
Version 1.7.2 patchlevel 13                   July 7, 1998

Minor changes:
      * @mail/file now shows the folder name of the destination folder
        as well as its number. Suggested by Julianna@ATS TrekMUSH

Fixes:
      * Problems with ANSI causing Pueblo to bleed have been identified
        and fixed!
      * Bug with cwho() fixed. Report by Tripsis@M*U*S*H. [TAP]
      * 'make diffs' in Makefile updated to use prcs and to produce
        diffs for patches without Index: lines which may confuse
        non-POSIX versions of patch.  
      * Fixed typo in options.h reported by Kyle Forbes.
      * Comments in src/services.c and src/filecopy.c are now C-style,
        not C++ style. Some compilers were puking on these, even though 
        WIN32 wasn't defined and the preprocessor should've ignored this 
        stuff. Go figure.
      * Side-effect functions like pemit() didn't obey the restrictions
        on the corresponding command (like @pemit), and setting attributes
        with @set could get around restrictions on ATTRIB_SET. 
        Reported by Scott Weber. [TAP]
      * Help for t() and elock() clarified by Octavian@M*U*S*H.
      * next() could be used on an object in a room that the player
        didn't control to get the room inventory. Reported by Octavian@M*U*S*H
      * hint/aux.sh has been renamed hints/a-u-x.sh. This means it won't
        be properly recommended by Configure on A/UX systems, but Win32
        programs often puke on files name 'aux.*' because they're braindead,
        and there are lots more Win32 users than A/UX users. Bummer.
      * When A was inside B, and @listen B=*, A would hear everything
        in B's room (good) except B's own speech (bad). Report by 
        Nemesis @ Beast Wars 2
      * help exits clarified by Nammyung@M*U*S*H
      * help comp() clarified by Halatir@M*U*S*H
      * @squota without a limit now shows the victim's quota in addition
        to asking what it should be set to. This more closely matches
        the old behavior of @squota without a limit being treated as
        @quota. Reported by Matt@M*U*S*H
      * @chan/what on a nonexistent channel didn't produce any
        feedback. Reported by Octavian@M*U*S*H.
      * Typo in help zone master rooms corrected. Report by Matt@M*U*S*H.


& 1.7.2p12
Version 1.7.2 patchlevel 12                   June 11, 1998

Fixes:
      * GAGGED players could pose/semipose. Reported by Jorhan@M*U*S*H. [TN]
      * convsecs() help clarified.
      * @decomp obj/attr didn't work if you couldn't examine the object
        even if the attribute was visible. Reported by Jonathan Booth.
      * make customize had a problem with the way it handled the
        hlp directory. It now creates a real hlp directory, but makes
        all the standard hlp files symlinks to the distributed ones.
        (It used to make the hlp/ directory a symlink, which did bad
        things with 'txt/Makefile'. Report by Gasparin Balazs.
      * help control rewritten to clarify the real algorithm.
        Suggested by [SW].
      * Configure is more flexible when determining if you're
        building under cygwin. Reported by Miphon.
      * zfun() worked, but gave an error message anyway. Fix by Rob@DuneIII
      * hdrs/regexp.h renamed to hdrs/myregexp.h to avoid conflict
        with standard regexp.h header file in cygwin.
      * Roy/see_all players could, under some circumstances, evaluate
        functions with wiz privileges. Reported by Atuarre. [TAP]


& 1.7.2p11
Version 1.7.2 patchlevel 11                   May 25, 1998

Changes:
      * The PennMUSH copyright notice has been changed, as the
        licensing terms for TinyMUD/TinyMUSH 2.0 have changed,
        and to update the TinyMUSH 2.2 part of the copyright and
        the PennMUSH part as well. 'help copyright' now gives the
        copyright, and it's in COPYRITE and hdrs/copyrite.h.
        The licensing terms are now shorter, but practically very similar.
 
Fixes:
      * Possible infinite loop (with disk-filling output!) in @dbck
        with certain types of DB corruption fixed.  Report by RLM and
        Arathorn@CDI.  [TAP]
      * @undest intermittent crash-bug fixed. Report by Arathorn. [TAP]
      * regmatch() crash-bug fixed. Report by Tavoan@ATS. [TAP]
      * Ansi bleeding problem fixed. Report by Atuarre@ATS. [TAP]
      * The embedded version of mkindx used by Win32 builds had a bug - 
        some global variables weren't getting properly reset.
        Fix by Stephane Thibault.
      * Help for @oxmove added. Report by Bray Roned@ATS.
      * isnum() was broken if tinymath was defined. Report by Daniel Peters.
      * portmsg needed MUSH_IP_ADDR, which is now runtime configured.
        It no longer does (see comment in portmsg.c if you need this
        functionality). Report by Daniel Peters.
      * Help for dig() and lnum() clarified by Andre Leopold.


& 1.7.2p10
Version 1.7.2 patchlevel 10                   April 24, 1998

Fixes:
      * MANIFEST updated to reflect the deletion of src/nmalloc.c


& 1.7.2p9
Version 1.7.2 patchlevel 9                    April 21, 1998

Fixes:
      * Myopic flag didn't work unless Pueblo support was on. Reported by
        Rhysem@M*U*S*H.
      * help debug referred to can_debug, a now-obsolete power.
        Reported by Rodimus Prime @ TF2005.
      * @chown to a Zone Master didn't work. The @chown code has been
        rewritten to be easier to read. Report by Trispis@M*U*S*H.
      * open_anywhere was mis-listed in help powers2. Report by Trispis.
      * nmalloc.c is removed, and Win32 compiles should be a bit easier.
      * Win32 build no longer limited to 64 sockets; 256 instead. [NJG]


& 1.7.2p8
Version 1.7.2 patchlevel 8                    April 2, 1998

Fixes: 
      * round() could crash on very big numbers on some systems.
        Reported by Atuarre@ATS.
      * Problem with exits getting a contents list in certain 
        conditions fixed. Reported by Atuarre@ATS. [TAP]
      * Problems with puppets and Pueblo fixed. Report by Mop-Boy.
      * mkindx problem with dos text files fixed. [NJG]
      * Order of include files in htab.c was wrong, caused compilation
        problems on SCO Openserver. Reported by Flame.
      * On Win32, the MUSH could quit without flushing its buffers. [NJG]
      * When inside of an object with @listen *, you didn't see things
        when the object did a 'look'. Reported by Vedui.
      * Warnings in rwho.c eliminated. [NJG]
      * More fooling around with mymalloc.h to help the Win32 compile.
        Suggested by NJG.
      * open_everywhere power get left off help powers list at some point.
        Reported by Steven@Champions.
      * Error message for joining a non-existant channel was different
        from that for joining a channel that exists but you can't
        see. Reported by Octavian@M*U*S*H.
      * get()'ing an attribute that isn't set now returns an error 
        message only if the default permissions don't allow you to 
        get it. This allows get(player/ALIAS) to always work, returning
        an empty string if the player has no ALIAS. [TAP].
      * base_room mush.cnf option got left out.
      * dbck didn't check for disconnected rooms correctly. Noted by
        Rhysem.


& 1.7.2p7
Version 1.7.2 patchlevel 7                    March 10, 1998

Fixes:
      * Typo fixed in pennflag.hlp. Report by Keith Howell.
      * Bug in mid() that could cause crashes on some OS's when using
        bad arguments fixed. Report by Yanek@DragonStarMUSH. [TAP]
      * @wait obj=command fails when tiny_math is defined. Report by Yanek.
      * With tiny_math defined and tiny_booleans not defined, 
        strings in booleans weren't being treated as 1. Report by Yanek.
      * @decompile now shows @powers, too. Report by Jonathan Booth.


& 1.7.2p6
Version 1.7.2 patchlevel 6                    March 8, 1998

Fixes:
      * src/mymalloc.c now includes config.h correctly. [NJG]
      * @zemit would change zones of objects while running.
        Report by Steve Sanderlin and Vedui.
      * Minor cosmetic bug in @config/list. Reported by Mike Wesson
      * @chown'ing an object to a Zone player doesn't reduce the Zone
        player's quota, but @chown'ing an object back from a Zone player
        should reduce yours (and didn't). Report by Vedui.


& 1.7.2p5
Version 1.7.2 patchlevel 5                    March 2, 1998

Fixes:
      * @cloning an object on a channel could crash the MUSH. Report by
        Mordak@ATS.
      * You couldn't add 2 objects with the same name to a channel.
        Report by Mordak@ATS.
      * Help for inc() fixed. Brian@M*U*S*H
      * On Win32, the text file indexes are now properly sorted,
        and things work ok if you don't have a text file defined. [NJG]
      * Wiz objects couldn't add players to channels. Report by Mike@M*U*S*H
      * Compile problem with fork and win32 fixed. [TAP]
      * You shouldn't get nospoof notification from your own emits. [TN]
      * You no longer get nospoof notification from every @chat, only
        from @cemit.
      * @lock obj=here or @lock obj=exit failed. Report by Luke@M*U*S*H
      * The MUSH announces where it's sending stderr when it starts up. [NJG]
      * If there was nothing on the queue, and no user activity,
        the MUSH could wait as long as 999 seconds before checking to
        see if it should do anything (like a dump, a shutdown, idling
        someone out, etc.) This has been changed to 5 seconds.
        Report by NJG.
      * Encryption buffer for SHS encryption was too small, could cause
        password problems. [NJG]


& 1.7.2p4
Version 1.7.2 patchlevel 4                    February 24, 1998

Fixes:
      * Fixed a few more compiler warnings under Win32. [NJG]
      * Output to a non-ANSI, non-COLOR player could cause crashes.
        Reported by Vedui.


& 1.7.2p3
Version 1.7.2 patchlevel 3                    February 22, 1998

Fixes
       * Fixed a slew of compiler warnings under Win32. [NJG]
       * Jonathan Booth Removed a few #ifdef EVENTS that lingered.
       * Room names weren't shown bold to people who had ANSI
         but not COLOR set. Report by Sylvia
       * Added help alias pueblo() for pueblo. Suggested by Vedui.
       * Fixed some problems with ansi() and tf reported by Vedui.
       * @readcache could cause crashes. First report by Mop-Boy.
       * src/tcl.c is now better located by Configure. [TN]


& 1.7.2p2
Version 1.7.2 patchlevel 2                    February 19, 1998

Fixes:
       * Reading of compressed dbs didn't work right. Report by Roger Christie
       * Fix to help to remove reference to @config/globals. Mordak@ATS.


& 1.7.2p1
Version 1.7.2 patchlevel 1                    February 18, 1998

Fixes:
       * max_dbref was limited to 256 by mistake. Report by Rhysem@M*U*S*H
       * restricted_building in mush.cnf didn't work. Does now.
         Report by Rhysem@M*U*S*H
       * memchecks for hash tables didn't work right. Report by [SW]


& 1.7.2p0
Version 1.7.2 patchlevel 0                    February 9, 1998

Major Changes:
       * Support for the Pueblo MUD client (http://www.chaco.com/pueblo)
         which allows the MUSH to send html to the client. This is
         runtime configurable with @enable/@disable and mush.cnf. [TN]
       * Regular expression support: the REGEXP attribute flag causes
         attributes to match $ and ^ patterns using regular expressions.
         regmatch() matches regular expressions. [2.2]
       * PennMUSH tarfile now unpacks itself in a pennmush/ directory,
         by popular request. pennmush/ is now the 'top-level' directory;
         patches should still be applied from within the pennmush/ directory.
       * More compile-time options are now run-time options:
          HASPOWER_RESTRICTED, SAFER_UFUN, DUMP_WARNINGS,
          INDEX_COMMAND, RULES_COMMAND, HATE_DEST (general command rename?),
          NOISY_WHISPER, POSSESSIVE_GET POSSGET_ON_DISCONNECTED,
          REALLY_SAFE, DESTROY_POSSESSIONS, NULL_EQ_ZERO,
          TINY22_BOOLEANS, TINY_TRIM_ORDER,
          ADEST_ATTRIB, AMAIL, PLAYER_LISTEN, PLAYER_NOAHEAR,
          ROOM_CONNECTS, ANSI_NAMES, COMMA_EXIT_LIST, COUNT_ALL,
          EXITS_CONNECT_ROOMS, WIZWALL_PREFIX, RWALL_PREFIX, WALL_PREFIX,
          NO_LINK_TO_OBJECT, QUEUE_PER_OWNER, WIZ_NOAENTER, USE_IDENT,
          MUSH_IP_ADDR, MAILER, ANSI_JUSTIFY, PLAYER_NAME_SPACES,
          NO_FORK, EVENTS, MILITARY_TIME, LOGIN_LIMIT, IDLE_TIMEOUT,
          RESTRICTED_BUILDING, FREE_OBJECTS, QUOTA, BUILDING_LIMIT,
          FLAGS_ON_EXAMINE, EX_PUBLIC_ATTRIBS, TINY_ATTRS, FULL_INVIS,
          SILENT_PEMIT, PLAYER_LOCATE, DO_GLOBALS, GLOBAL_CONNECTS,
          PARANOID_NOSPOOF, ACCESS_FILE, NAMES_FILE, OBJECT_COST,
          EXIT_COST, LINK_COST, ROOM_COST, QUEUE_COST, QUOTA_COST,
          FIND_COST, PAGE_COST, KILL_BASE_COST, KILL_MIN_COST, KILL_BONUS,
          QUEUE_LOSS, DBTOP_MAX, MAX_OBJECT_ENDOWMENT,
          MAX_WIZ_OBJECT_ENDOWMENT, MAX_PENNIES, MAX_DEPTH, MAX_PARENTS,
          PURGE_INTERVAL, DBCK_INTERVAL.
       * All the functions that used to be optional are now
         enabled. The increase in code size is negligible, and
         the decrase in options is a win. We'll probably add 
         some way to restrict function use in mush.cnf in the future.
       * The original MUSH chat system is no longer distributed or
         supported. The OBJECT_CHAT option is thus obsolete.
         If you've been using the old system, your db will automatically
         be converted to the new one, but you will need to recreate
         your channels and readd players to them.
       * ADD_NO_COMMAND_FLAG has been removed, as few people need
         to add NO_COMMAND en masse to all their rooms and players
         any more. Those that do can use MUSHcode for this.
       * The definitions of GOD, MAX_ARG, have been moved out of options.h, 
         because redefining these isn't really an option you want to exercise.
       * dune.h is no more. Raise a glass to it.
       * Non-standard attributes that are created by objects are set to 
         no_command by default. This improves security in many common cases, 
         but may require your object code to @set the attribute !no_command
         after it creates it, if the attribute is meant to contain
         a $command. Attributes set by players themselves (typed directly
         from a socket) still work as they used to, as do standard
         attributes (@va-@vz, for example). [TN]
       * Hash table code has been tightened up. [TN]
       * New option: tiny_math. Treat strings as 0 in math functions
         rather than errors. This is handy for Tinymush compatibility,
         even though it may make real errors harder to find.
         Suggested by Ashen Shugar.

Minor Changes:
       * idlesecs() now returns the number of seconds idle for the least
         idle connection of the player.
       * conn() now returns number of seconds connected for the longest
         connected connection of the player.
       * I wrote the COPYRITE file some time ago, but forgot to include
         it in the dist. Oops!
       * UFAIL/OUFAIL/AUFAIL is here. Suggested by Mike Affourtit.
       * controls() is now ok if you are See_All; you don't need to 
         actually control the object you're testing. Reported by RLM.
       * If you're allowing empty attributes, ICLOC is set to ""
         on newly created players, instead of " ", to permit testing
         with hasattrval. Suggested by Jonathan Booth. [TN]
       * Improvements to FPE handling on FreeBSD. By Jason Young.
       * New switch /noeval for @mail. Suggested by Mop Boy.
       * The "dbcomp" directive in mush.cnf has been removed.
         "compress_suffix" has been added. Databases are now specified
         without compression suffixes.
       * You are warned if you fail to define an option in the config file.
         Suggested by TN.
       * @config can now list config options in logical groups.
       * mail.c has been removed. extmail.c is used directly instead.

Fixes:
       * hasattr/get/xget/eval now are less likely to tell a player something
         they're not privileged to know about the existence of attributes. [TN]
       * The big_que function has been renamed parse_que. The parse_que
         function (which just called big_que) is gone.
       * FAQ updated, as well as other references to pennmush.tinymush.org.
       * Giving a negative argument to convsecs() would crash Win32.
         As there's no reason to ever do that, you now can't. 
         Reported by Javin@DynamixMUSH
       * dist2d and dist3d now return floating point numbers when
         FLOATING_POINTS is defined, as they said they would.
       * help for pi() now refers to it as 3.141593, which is what
         the function actually produces, due to rounding. Report by Vedui.
       * help for beep() notes that royalty can use it to. Report by Vedui.
       * Using a maildb that referred to db#s that didn't exist
         in the object db (e.g., replacing your object db with minimal.db
         without removing the maildb) would crash the server.
         Now the server fixes up invalid messages after loading maildb
         Report by TN.
       * Connect screen and other cached text files should now be
         automatically terminated with CRLF, so windows and other
         telnet programs will see them correctly. Report by many. [TN]
       * The separator in iter() is now parsed. Report by Ashen-Shugar.
       * match(foo,>) always returned 1; similar problems with matchall,
         grab, graball, strmatch, and elements. Report by Ashen-Shugar.
       * Objects listening for channel broadcasts with ^<chan> *: didn't
         work. Now they do.
       * When you disabled a command in order to override it in MUSHcode,
         calling the command with switches didn't work. 
         Reported by Ben Kenobi. Patch by Eyal Sagi and TN.
       * Calls to cut in utils/mkcmds.sh relied on "-f 2" working like
         "-f2". On at least Ultrix 4.4, it doesn't. Report by Cwilla.
       * Link strdup.o to info_slave because some systems need
         strdup! Report by Cwilla.
       * Some help file typos cleaned up by Ken Ray.
       * exit() used to work on non-rooms. Not anymore. Report by
         Trispis@MUSH101 
       * All header files now idempotent.
       * @tel me=home or @tel home now works in all cases where 'home'
         works. Report by Vedui.

& 1.7.1p3
Version 1.7.1 patchlevel 3                    January 12, 1998

Minor Changes:
       * A file called MANIFEST is now distributed. Configure uses this.
         Don't mess with it unless you know what you're doing.
       * An additional note for those upgrading from versions before
         1.7.0p9, describing an anomaly with player parents and how
         to handle it has been added to README. Report by Roger Christie.

Fixes:
       * controls() now requires that the function caller control
         the object named in the first argument. Suggested by TN.
       * Player parents were being cleared at every login.
         Fixed by Jonathan Booth.
       * effect should be affect in game/txt/newuser.txt. 
         Reported by Jason Young.
       * hints file for OS/2 now included. Suggestions by Sylvia.
       * FNDELAY changed to O_NDELAY in ident.c. Suggested by Sylvia.
       * Minor change to time_format_1 to make 64bit SGI happier.
         By Thaddeus Parkinson.
       * Help for inc()/dec() improved. Suggested by Jonathan Booth.


& 1.7.1p2
Version 1.7.1 patchlevel 2                    January 5, 1998

Fixes:
       * References to TinyMUSH in the .txt files are now PennMUSH.
         Reported by Corum.
       * It was possible to use @name to create players with the same
         name. Ick. Reported by Sylvia.
       * utils/mkcmds.sh now produces a preindented switchinc.c,
         to match the one that gets diffed in patches. [TAP]


& 1.7.1p1
Version 1.7.1 patchlevel 1                    December 29, 1997

Fixes:
        * table() now behaves with ANSI_JUSTIFY. Reported by Jonathan Booth.
        * ident.c was defining strdup; so was strutil.c. Now only
          strutil.c does. Reported by Matt Philips. [TAP]
        * Bug in restart script fixed. [TAP]
        * shs.h patched to autoconfigure endianness. Reported by TN.
        * shs.h fixed to be idempotent. [TAP]
        * shs.h is now distributed with PennMUSH. You still have to get
          shs.c from export.pennmush.org if you want it.
        * README now refers to lists.pennmush.org. [TN]
        * We no longer recommend setting use_dns to no on win32 systems.
          It seems to work fine as yes.


& 1.7.1p0
Version 1.7.1 patchlevel 0                    December 21, 1997

Major Changes:
        * It is no longer necessary to edit src/Makefile when building.
          RWHO is now integrated, and totally runtime configured in mush.cnf.
          IDENT is now configured from dune.h. The IDENT/ and RWHO/
          directories are no more.
        * The win32 build now requires the gnu-win32 package
          (available at XXX). It can be built either with MSVC++
          or the free win32 version of gcc included with gnu-win32.
          The build is better integrated into the distribution --
          the win32/ directory is no more. [TAP]
        * You can now build with one of 3 password-encryption schemes:
          None, Unix (des) crypt(3), and shs (requires getting shs from
          export.pennmush.org). This will be useful to folks who're using
          shs encryption on Win32 platforms and then move their db to
          a Unix platform -- they can just use shs under Unix and all's well.
          This is set as CRYPT_SYSTEM in options.h
        * @log/wipe used to require entering the game account password,
          but that's non-portable. Instead, a "log_wipe_passwd" is now
          specified in mush.cnf.
        * README rewritten [TAP]

Minor Changes:
        * @lock/drop on a room now controls who can drop things in the room.
        * "configure" (lower-case 'c'), a wrapper for Configure that used
          to be included is no longer. Few used it, and it can screw up
          win32 systems that aren't case-sensitive.

Fixes:
	* blind_page was written as blindpage in game/mushcnf.dst.
          Reported by Raevnos@ShadowMist.
	* udefault() was broken. Reported by John Hutchinson
        * Some lintwork in csrimalloc.c, to get rid of signed/unsigned
          warnings and others.
        * help @list fixed to show the correct @config switches.
          Reported by Leo@ATS TrekMUSH
        * @chan/gag now works correctly. Report by Vedui.
        * Help for remove() updated. Reported by Vedui@Robotech.
        * hasattr() didn't check if the invoker had permission to read
          the attribute. Reported by Vedui@Robotech.


& 1.7.0p11
Version 1.7.0 patchlevel 11                    November 18, 1997

Commands:
        * page/blind produces a separate page to each person paged,
          so they can't tell if the page was a multipage. This is the
          same as the default PennMUSH page behavior (but see Options)

Options:
        * New mush.cnf option 'blind_page'. If 'yes', page defaults to 
          page/blind.  If 'no', page defaults to page/list. By popular 
          request. :)
        * New dune.h option MUSH_IP_ADDR. Define if your host system has
          multiple IP addresses to specify which address to listen on
          for connections. By Bobby Bailey (Chil).

Minor Changes:
        * All calls to isalnum replaced with isalpha || isdigit, because
          some linux systems appear to have a broken isalnum!
        * For some reason, the variable name 'restrict' in fun_lsearch
          broke compilation on James Cook's system. Gwennie@SNW fixed
          this by changing the name. Ok, I've changed the name, too,
          as a preventative measure. *shrug*
        * When a player can't connect because logins are disabled or
          the MUSH is full, we no longer (a) show a disconnect message
          to MONITOR players, (b) purge the player's mail anyway, or
          (c) show the player quit.txt in addition to full.txt/down.txt.
          Suggested by John Hutchinson.

Fixes:
        * When a halted player triggers a $command *:, %0 was including
          an initial space that wasn't being trimmed. Reported by
          Jonathan Booth. [TAP]
        * functions() works right again. Patch by Atuarre@ATS TrekMUSH
        * look/out allowed looking at any db#. Reported by Lews Therin@DDM

& 1.7.0p10
Version 1.7.0 patchlevel 10                    October 30, 1997

Minor Changes:
        * Players can now have @parents. Inspired by AJ Prowant.

Fixes:
        * @drain was doing @notify instead. Ick. Reported by Amberyl.
        * Royalty can @boot, as the help suggests. Reported by Vedui@Robotech
        * (Hopefully current) copies of hdrs/funs.h and hdrs/cmds.h are
          kept in the win32/ directory for win32 folks who don't have
          a Bourne shell and can't run utils/mkcmds.sh.


& 1.7.0p9
Version 1.7.0 patchlevel 9                    October 16, 1997

Fixes:
        * @clone could corrupt the db on some machines in some cases. 
          Report by Jonathan booth. [TAP]
        * @list attribs now works. Report by Corum@StormWorld.

          
& 1.7.0p8
Version 1.7.0 patchlevel 8                    October 15, 1997

Fixes:
        * Hopefully the final command_parse fix. 


& 1.7.0p7
Version 1.7.0 patchlevel 7                    October 15, 1997

Fixes:
        * The ANSI_JUSTIFY patch got left out somewhere. It's back.
          Report by John Hutchinson.
        * +channel and exits are broken in 1.7.0p6 due to our stupidity.
          Fixed again. Report by John Hutchinson.
        * @cemit was restricted to Wizards, and should have been restricted
          to Wiz or Royal. Fixed. Reported by Vedui@Robotech.


& 1.7.0p6
Version 1.7.0 patchlevel 6                    October 9, 1997

New Functions:
        * cand(), cor() are short-circuit boolean functions. Suggested by
          Flame who saw reference to them in a patch to TinyMUX. [TAP]
        * if() and ifelse() do about what you'd expect. Suggested by
          a number of people. [TAP]

Minor Changes:
        * Prototypes for the functions in src/local.c are now in
          hdrs/externs.h
        * round(.15,1) = .1 on many systems due to the floating point
          representation. A tiny kludge around this is now in place.
          Reported by Flame.
        * @command/disable say now disables " as well. The same applies
          to other single-character command forms. If you disable SAY,
          commands of the form "hi! are rewritten as: say hi! before
          being passed to the checker for user-defined commands
          so you need only set up $say *: to catch both. %c will, as always,
          contain the raw command as entered (i.e. "hi!). Aliases
          (like 'p' for page) are treated similarly when the aliased
          command is disabled -- you need only match $page *. [TN]
        * The Huffman compression algorithm is now 8-bit clean, in 
          preparation for a future internationalization of PennMUSH
          (Eh? Dite "help" pour aide. :) In addition, none of the compression
          algorithms treat the first character of a compressed string
          specially anymore -- they don't have to. [TAP]
        * The customize.pl script no longer copies over all the distribution
          help files from game/txt/hlp. Instead it makes customdir/txt/hlp
          into a link to game/txt/hlp, which is a good thing when future
          patches update the help files. Dedicated to Oleo.

Fixes:
        * @list/attribs showed many duplicate attribute names.
          Reported by John Hutchinson.
        * Fixed a mislabeling of allocated memory by htab.c, so mem_check
          stats will be correct.
        * @channel/gag now works.


& 1.7.0p5
Version 1.7.0 patchlevel 5                    October 1, 1997

Minor Changes:
        * New os2/ subdirectory with information for those looking to
          build under OS2. Maintained by Sylvia (penn-os2@pennmush.tinymush.org)

Fixes:
        * Examine/brief could sometimes cause crashes. Reported by
          Sean Fike. [TN]
        * cmds.c and command.c didn't do the right #includes for the
          original chat system. Reported by Magus.
        * Added help for @shutdown/paranoid. Reported by Sean Fike
        * @chan/decompile on a nonexistant channel didn't return an
          error. Reported by Mike Wesson


& 1.7.0p4
Version 1.7.0 patchlevel 4                    September 19, 1997

New command:
        * The @shutdown command now takes a /paranoid switch
          to perform a paranoid dump when shutting down
          (or rebooting, if given with /reboot as well). Idea by Flame.

New options:
        * You can define the MAILER option in dune.h to be
          something other than sendmail if you want to put a
          wrapper around the mailing program used to send out
          passwords to players using the 'register' command.
        * If you define LOCAL_DATA in options.h, you can 
          use functions in local.c to maintain your own data structures
          associated with each db object. [TN]
        * If you define the TINY_TRIM_ORDER option in dune.h,
          the trim() function takes arguments like TinyMUSH's.
        * If you define ANSI_JUSTIFY in options.h, the rjust, ljust,
          and center functions will ignore ansi codes when computing
          where the string should be placed, so they'll work right for
          strings with ansi. Wadhah Al-Tailji contributed a patch
          for this concept. TN wrote this particular implementation.

Fixes:
        * rnum() didn't find exits properly. Reported by Vedui.
        * Null channels would get added if the chatdb's channel count
          got unsync'd with the actual number of channels in the chatdb.
          Reported by Matt@New England: The Reckoning.
        * @wcheck/all didn't work. Report by Wolverine@Holodeck1
        * HPUX needs _XOPEN_SOURCE_EXTENDED in the hints. Report by Angel.
        * db reading error messages are slightly more verbose.
          Suggested by Flame.
        * Mortals examining DARK rooms don't see contents anymore.
          Report by Jonas Oberg. [TN]
        * Attribute names may no longer contain the caret (^) character.
          It's a security risk. Noted by Rob Wilson.
        * hdrs/funs.h was being appended to, not rebuilt. Noted
          by John Hutchinson.
        * setunion fixed again, so that setunion(a a,) correctly
          returns 'a', not 'a a'. [TN]
        * Various references to mellers1 updated to pennmush.tinymush.org.
        * COPYRITE file added to explain a couple of the unclear
          points in hdrs/copyrite.h and to serve as a pointer.
        * @chan/rename didnt work. Reported by Jonathan Booth.
        * Help for entrances() updated by Naomi Novik
        * Players no longer hear about all the channels they're
          no longer gagged on when they disconnect. Report by
          Naomi Novik.
        * The time noted in the LAST attribute now will always
          have day numbers 01-31 instead of 1-31, just like time()
          does. This makes convtime() work better on LAST for some
          systems. Reported by Valin@PernMUSH.
        * MUSHcoding a command called $attr * would crash the MUSH.
          Fixed. Reported by Sam Knowlton. [TN]
        * Disabling say now disables ", (same for pose, semipose,
          emit, and chat and their corresponding tokens).
          Reported by Flame.
        * The hint for Dec Alpha OSF now indicates that you need to
          use native malloc. Reported by Sean Fike.
        * We now check for the assert() macro in Configure. NetBSD may
          not have it, according to Logan Five.
        * Doing a LOGOUT after a @shutdown/reboot caused crashes
          because mail pointers weren't being reset.


& 1.7.0p3
Version 1.7.0 patchlevel 3                    August 13, 1997

Fixes:
        * setunion(,list) should work now.
        * @wall/wizard and @wall/royalty work right. Report by Alan T. [TN]


& 1.7.0p2
Version 1.7.0 patchlevel 2                    August 12, 1997

Fixes:
        * Linux 2 is now instructed not to use nm to find objects
          in libraries since its nm output doesn't seem to be
          BSD compatible or something.
        * Compile with CSRI malloc in debugging mode didn't work.
          Reported by TwinSuns MUSH.
        * Exits in transparent rooms with COMMA_EXIT_LIST had
          vanished. They're back! [TN]
        * More command parser bugs ironed out. [TN]
        * 'e' is examine, 'b' is brief, 'w' is whisper
           (unless you reserve them). [TN]
        * @config said conflicting things about possessive get.
          Report by Jonas Oberg.
        * When not using @prefix, audible messages were prefixed
          with "From <source>" instead of "From <source>,".
          Fixed. Report by Jonas Oberg.


& 1.7.0p1
Version 1.7.0 patchlevel 1                    August 7, 1997

Minor Changes:
        * New file local.c (from local.dst) makes more local hooks
          available. Some of the hooks in command.c have been moved
          here, so you may have to mess around a bit if you've already
          added things in command.c's local_startup or local_shutdown. [TN]
        * Functions can now be defined and added all within funlocal.c
          so you don't have to muck with the function.c table. [TN]

Fixes:
        * restrict_command didn't restrict commands to God correctly.
          Reported by Jason Newquist.
        * @command indicates if commands are restricted to God.
        * When COMMA_EXIT_LIST was defined, rooms with no exits
          still showed the "Obvious Exits:" message. Report by Michael Rudel.
        * Partial switch-matching for commands is back.
          And CMD_T_NEWSTYLE is gone. [TN]
        * Makefile doesn't clobber existing funlocal.c/cmdlocal.c
          any more. Report by Jason Young.
        * inv wasn't working for inventory, and other command aliasing
          flaws are fixed. Report by Corum. [TN]
        * MUSH wouldn't compile if PLAYER_LOCATE wasn't defined. Fixed.
          Report by Alan T.
        * Some leftover defines removed from game.c and mushcnf.dst
        * @lock didn't parse right. Fixed. Report by Corum.


& 1.7.0p0
Version 1.7.0 patchlevel 0                    July 31, 1997

The major goals of this release are to make what used to be
compile-time options into run-time options, and improve a number
of internals.

Major Changes:  

        * The hashtable functions from TinyMUSH (htab.c/htab.h) are
          now used by PennMUSH (with permission), so instead of 
          every subsystem writing its own hashtable code, they now
          all use the standard code.

        * The giant switch in game.c has been replaced by hashtabled
          commands. [TN] 
          Groovy new features:
          * @command/enable and @command/disable for any command
          * Multiple switches (@pemit/noeval/silent) work
          * The left side of the = is always evaluated before
            the right (previously, this was compiler-dependent).
          * Command table is built during compilation, and there's 
            a standardized command interface, so adding commands
            is easier.
          * local.c contains hooks for local routines to run
            on startup and shutdown, and to use to add new commands.

        * Configuration options which restricted or disabled commands
          (READ, NO_KILL, ROBBERS, HATE_TOAD, ROY_FIND, HARSH_GUEST,
          SITELOCK_COMMAND) have been replaced the 'restrict_command'
          directive in mush.cnf. Check there and be sure things are
          set the way you want them!

        * Commands may be overridden by completely disabling them,
          and providing a MUSHcoded version instead.
            
        * Ident and DNS lookups are handled by a slave process
          if possible. [TAP]

        * The help files have been rewritten by Naomi Novik!

        * The MUSH now closes and reopens the log files when it
          receives a SIGHUP signal. [TAP]

        * @shutdown/reboot will dump the database and restart the
          MUSH without disconnecting the players. So will a USR1 signal.
          Good for patching in new source code on the fly. Based on the 
          patch by Cro@Spaceballs which is itself based on ideas from
          TinyMUX. This may be nonportable - if it fails on your OS, 
          pennmush-bugs@pennmush.tinymush.org would like to hear about it. 
          [TAP]

New commands:
        * @command (see above)
        * @list/commands
        * @attribute, similar to Tinymush (but doesn't save data
          across shutdowns at this point, so you've got to use it
          on an @startup!). Also @list/attribs.
        * @function/delete 
        * @channel/gag <channel>=<yes|no>, keeps you on the channel
          (preserving your title, etc.) but silences it so you don't 
          hear messages. The channel is automatically ungagged if
          you log out from the MUSH.
        * @conformat and @exitformat allow custom-formatted Contents:
          and exit lists. [2.2,TAP]

Minor Changes:
        * Configure now looks for libbind.a, the BIND 8.1 library
        * @config shows more of the configuration options
        * @mail/unfolder <folder> can be used to remove a mailfolder's name.
          Suggested by Julianna Barrenson.
        * The default malloc is now CSRImalloc, which is now distributed
          in a single-file form with the MUSH. 
        * The MALLOC define in src/Makefile has been removed.
          Unlike MALLOC_D and MALLOC_O, it didn't do anything.
        * The "CHANGES" file now contains only the current
          version's changes. Older changes are in the 
          "CHANGES.OLD" file.
        * The attribute flag AF_ODARK is now assumed to be default, 
          and is thus no longer used or stored. Instead, AF_VISUAL
          is used to indicate a visual attribute (previously, this
          was indicated by the absence of AF_ODARK). To note this
          change in the db, a new DBF constant, DBF_AF_VISUAL,
          has been defined.
        * Code for "privilege tables" (like chat channel privs, 
          attribute flags, etc.) has been centralized into privtab.c

Fixes: 
        * Locks on zone exits now evaluate with the right enactor.
          Problem noted by Leonid Korogodsky. [TAP]
        * Win32 compatibility improvements. [TAP]
        * Prefer limits.h to values.h. Suggested by Atuarre.
        * SIGCHLD and SIGCLD now both work. Noted by Naomi Novik
        * If you idle out and get hidden, only the idle descriptor
          should get hidden. Noted by Gepht@Hemlock
        * With DBF_LESS_GARBAGE, garbage objects were loaded with
          owner NOTHING instead of owner GOD, which could cause
          crashes in the @mail code. Reported by Harvester@StarWars.
        * Problems with getrandom() on some systems fixed.
        * Help for dist3d() clarified. Reported by 
          Kova'khan@Among the Stars TrekMUSH via Leo at the same MUSH.
        * You may now use power() for integral powers of negative
          numbers. Suggested by John Hutchinson.
        * setunion(,test,|) used to return |test, now returns test.
          Reported by Ashford @ V MUSH
        * SAFER_UFUN now blocks non-God eval'ing a u() on God.
          Reported by MRR@ATS
        * Building with SunOS cc and COMPRESSION_TYPE 0 works now. 
          Reported by Jonas Oberg.

Personnel Changes:
        * Ralph Melton has retired as a member of the PennMUSH 
          devteam. Alex and Javelin send him best wishes and big
          thanks for all his work. Replacing Ralph will be
          Thorvald Natvig. Welcome aboard, TN!

& 1.6.10p6
Version 1.6.10 patchlevel 6		      May 11, 1997

Fixes:
	* inc() and dec() didn't work right with NULL_EQ_ZERO.
	  Fixed. Report by Dennis DeMarco


& 1.6.10p5
Version 1.6.10 patchlevel 5                 April 29, 1997

New Commands:
        * @channel/title sets a player's title for a channel.
          The title appears prepended to their name.
          I forgot this, and Thorvald Natvig noticed.

Minor Changes:
        * The inc() and dec() functions can now increment and
          decrement strings that end in integers. For example:
          inc(LINE_10) => LINE_11
          inc(LINE-10) => LINE-9   (incrementing -10)
          inc(LINE1.9) => LINE1.10 (incrementing the 9)
        * The LOWER_MATH option has been removed. Everybody
          gets shr(), shl(), inc(), and dec().
        * New attributes OIDESCRIBE and AIDESCRIBE do what you'd 
          expect for the internal descs of objects. Suggested
          by Stacy Robinson.
        * @chan/on by a Wizard always succeeds, even if there's a 
          join lock. Suggested by Mike Wesson.
        * Enhanced protection against malicious ANSI codes.
        * @channel/decomp displays locks in a better format.
          Suggested by Naomi Novik.
        * Numbers are now checked to be sure they're not so
          large as to bring down the system, at least in theory.
          Suggested by Atuarre.
        * Configure rebuilt under dist-3.0 pl70.
        * queue_write has been modified to reduce the number of
          packets sent out on the net; it only sends when needful
          and lets the usual output loop handle most output.
          The many packets issue was noted by Doogie.
        * All references to "parent rooms" have been changed to
          "zone master rooms" for clarification. Noted by Jonas Oberg.

Fixes: 
        * Long output should no longer cause NeXT
          systems to disconnect the user. Fix by Mike Kienenberger
        * Long output should no longer cause Win32 systems to
          disconnect, but it will throw out the beginning of 
          the output. Fix by Hans Engelen.
        * Bad objects on chat channels are now removed when the
          chatdb is loaded. Suggested by Dennis De Marco.
        * help for last() added. Report by Flame.
        * Objects couldn't be added to object channels. Fixed.
        * If a site matched in access.cnf, but didn't specify 
          a certain access rule, a later matching site could. This
          is bad for 'register', and not what was intended (that
          a matching site completely controls that site's access).
          Now fixed. Report by William Browning.
        * If you're on a channel but don't pass the see-lock,
          @chan/who returns a better error. Report by Cro.
        * help for remove() now mentions delimiters. Noted by J. Wilcox.
        * All tabs in helpfiles replaced with spaces. [TAP]
        * Loading a db that didn't have garbage objects stored
          caused a slew of warnings about null names. Should be fixed
          now. Reported by Atuarre.
        * FreeBSD hints improved, thanks to Atuarre and Doogie.


& 1.6.10p4
Version 1.6.10 patchlevel 4                 March 3, 1997

Major Changes:
        * The disk db can now be dumped without including GARBAGE
          objects, which may make it somewhat smaller. [TAP]

Minor Changes:
        * The %? substitution returns the current function invocation
          count and recursion depth as two space-separated numbers. [TAP]
        * dig() can take a single argument instead of 3.

Fixes:
        * set(obj/attr,flag) no longer says "Set" when the object or
          player is QUIET. Reported by Graywolf.
        * Search_All players couldn't use @search. Now they can.
          Reported by Cro.
        * lnum(2,1) didn't work right, and things were broken with
          floating point args to lnum. Fixed.


& 1.6.10p3
Version 1.6.10 patchlevel 3              February 9, 1997

New function:
        * graball() as per TinyMUSH 2.2. [TAP]

Fixes:
        * On some systems, make clean would go into an infinite loop
          if src/CSRI didn't exist. This should now be fixed.
          Report by Cro@Spaceballs.
        * Restart script now looks for minimal.db.gz if minimal.db.Z
          can't be found. This helps people running under Mklinux
          on Power Macs(!). Report by Jason Newquist.
        * Fix to matchall(). [TAP]
        * move.o doesn't compile if FIXED_FLAG isn't defined.
          Noted by Andy Jalics.



& 1.6.10p2
Version 1.6.10 patchlevel 2              February 2, 1997

Minor Changes:
        * If forking to do dumps, lower the priority of the dumping 
          process to keep the parent process more responsive.
          Based on a patch by Doogie@ATS TrekMUSH.

Fixes:
        * Code cleanup and fixes to comp_w.c. Problems reported by
          Mike@TBFF
        * Portability fixes for alpha-linux systems. Thanks to Roger
          Chen for facilities to work on this.
        * Added help for @dump/debug. Report by Flame.
        * Note added to game/txt/Makefile about braindead Irix 6.2 make
        * Ident source files now do better #ifdef'ing of Unix include
          files to help out Win32. 
        * Configure changes to enhance portability.


& 1.6.10p1
Version 1.6.10 patchlevel 1              January 25, 1997


Commands: 
        * New command: @dump/debug. Like @dump/paranoid, but
          it also tries to fix the memory db, so a shutdown/restart
          may not be necessary. It is never forked. Suggested by Atuarre.

Fixes:
        * externs.h now declares crypt() as char *, not const char *.
        * free_access_list's declaration is now K&R compatible again.
        * repeat() now doesn't work with a null string, which prevents
          a denial of service attack. Report by Atuarre. [TAP]
        * Fencepost error in huffman compression code fixed.
          Report by Mike Wesson. [TAP]
        * idlesecs() is now referenced in pennfunc.hlp. Report by Flame.
        * parse() is now referenced in pennfunc.hlp. Report by Sandi Fallon.
        * lsearch() now gives the correct types in the help.
          Report by Sandi Fallon.
        * Halted messages now indicate the object that was halted,
          even if they are halted as the result of a chown.
          Report by Sandi Fallon.

& 1.6.10p0
Version 1.6.10 patchlevel 0              December 16, 1996

Major Changes:
        * The attribute matching order has been cleaned up. Code by [TAP]
          If you do ex obj/attribpattern, and...
          1. If attribpattern has no wildcards:
             a. Return attribpattern's value if set, else
             b. Return the value of an aliased attribute, if any.
          2. If attribpatern has wildcards:
             a. Return anything which matches the pattern, and
                don't bother about aliases.

        Here's a little example:
                       only DESC set   only DESCRIBE set    both set
  ex foo/desc          DESC            DESCRIBE             DESC
  ex foo/desc*         DESC            DESCRIBE             both
  ex foo/describe      (error)         DESCRIBE             DESCRIBE


Minor Changes:
        * parse() is now an alias for iter() [TAP]
        * Attribute set/clears report the name of the attribute in the
          set/cleared message. [TAP]
        * fun_lattr is now in fundb.c. [TAP]
        * Improved setq/setr help. [TAP]

Fixes:
        * Typo in help evaluations corrected. [RLM]
        * The side-effect version of lock() no longer returns a value.
          Reported by Corum.
        * help quota() added. Report by Dennis De Marco.
        * help INHERIT updated to reflect current control structure.
          Suggested by Vedui.
        * vmul() with a separator now returns the vector separated with
          that separator, as promised. Report by Atuarre@TrekMUSH.
        * FIXED now overrides STICKY, so you can't set yourself STICKY,
          get yourself dropped, and go home. Report by Anthony Ivan.
        * lsearch(all,flags,c) worked, but lsearch(all,flags,Pc) didn't!
          This is fixed. Report by Flame.

& 1.6.9p9
Version 1.6.9 patchlevel 9               November 18, 1996

Fixes:
        * A Wizard doing @find on a MUSH with garbage crashes the MUSH.
          Fixed. [TAP]
        * Fairly major security problem due to a typo in the player-
          destruction code fixed. Reported by Dennis DeMarco.


& 1.6.9p8
Version 1.6.9 patchlevel 8               November 10, 1996

Major Changes:
        * The control system has changed slightly: only wizards
          control wizobjects and only royalty control royobjects.
          If a mortal's object gets wizbitted, the mortal will
          cease to control it. Also, protection is now afforded
          to players from non-inherit objects.

Fixes:
        * Setting an @listen on a room caused a crash. Fixed.
          (Note: @listen on rooms still doesn't work - it's not
           supposed to -- use LISTENER and ^patterns -- but at
           least it doesn't crash. :)  Report by Flame@B5.
        * dune.h.dist now defaults the index and rules indx files
          to ending in .idx, as they should. Noted by Jason Newquist.



& 1.6.9p7
Version 1.6.9 patchlevel 7               October 30, 1996

Functions:
        * The help for vmul() suggested it did an elementwise product
          of 2 vectors, returning a vector. In fact, it was doing a
          dot product (sum of the elementwise product, which is a scalar).
          vmul() now does what the help suggests, and vdot() does
          a dot product.

Fixes:
        * Bug in comp_w.c (word-based compression) which could cause
          loss of subjects in @mail has been fixed. [NJG]
        * Help for "control" made more explicit, and help for "controls()"
          references "control", not "controls".
        * @wait 0 now queues its subject immediately, rather than waiting
          1 second. [TAP]
        * The "Patchlevel" file is now more grammatical. For Sam Knowlton. :)
        * Variables named "listen" have been renamed "listener" to
          remove compiler warnings about shadowing the listen() system call.
          Reported by Flame@B5


& 1.6.9p6
Version 1.6.9 patchlevel 6               October 24, 1996

Fixes:
        * Removed needless calls to tprintf() within do_log() in 
          access.c
        * Fixed the variable j in fun_lnum to be the right type


& 1.6.9p5
Version 1.6.9 patchlevel 5               October 15, 1996

Options:
        * COMMA_EXIT_LIST causes exit lists to be comma-separated,
          and include the word "and" before the last exit. [NJG]

Functions:
        * lnum() with multiple arguments now behaves exactly like
          Tiny 2.2's lnum().

Minor Changes:

        * @pcreate failure messages distinguish between bad passwords
          and bad names. Related to a suggestion by Philip Mak.

Fixes:
        * elements() used to put a leading space in output. Fixed. [RLM]
        * index(foo|||,|,2,1) now returns nothing, instead of ||,
          as it should. Fix by Harvester@StarWarsMUSH.
        * @cpattr a/DESC=b (where a has a DESCRIBE attribute and no DESC
          attribute) correctly grabbed DESCRIBE from a, but copied it to
          DESC on b. This is now fixed. [TAP]
        * Various unused variables and missing prototypes fixed. [NJG]
        * More win32 fixes. [NJG]
        * Revised comp_w.c to handle table overflow better. [NJG]
        * splice() wasn't putting spaces back in between words.
          Reported by Philip Mak.
        * Help for aposs() was never added. [MPC]
        * mkindx doesn't compile on systems without strcasecmp. Fixed.
          Reported by Stephen Sanderlin.
        * Configure: -lsocket is used if it's found (also -lcrypt, -lnsl)
        * Various missing includes fixed
        * Linux systems weren't doing daylight savings time right.
          We now always try to use tm_isdst = -1 to get this right.



& 1.6.9p4
Version 1.6.9 patchlevel 4               October 9, 1996

Fixes:
        * Restart script fix in 1.6.9p3 is buggy. Fixed the fix.


& 1.6.9p3
Version 1.6.9 patchlevel 3               October 7, 1996

Changes:
        * @wipe/wipe() of a single attribute (no wildcards) no longer
          checks the SAFE flag on the object.
        * Wildcards are now accepted for the attribute name when setting
          attribute flags.

Fixes:
        * @succ and &succ could create duplicate success attributes.
          Fixed so that @succ -> SUCCESS and &succ -> SUCC,
          and no more duplicates. [TAP]
        * Help for @purge had disappeared. Back.
        * Forgot to include restart patch mentioned in 1.6.9p2 [PeaK]


& 1.6.9p2
Version 1.6.9 patchlevel 2               October 5, 1996

New Compile Options:

        * The behavior of attributes is now configurable; you can
          emulate attribute setting behavior from 1.6.8 and earlier,
          use the currently recommended settings, or anywhere 
          in between. [TAP]

Functions:

        * lnum() now takes an optional second argument, which is the
          number to start with, e.g. lnum(3,4) => 4 5 6
          Suggested by [MPC]

Fixes:
        * @mail/debug clear=<player> now clears all the player's
          mail, not just their current folder. Fix by
          Leonid Korogodsky.
        * look/outside at an ambiguous name crashed. Report by Vedui.
        * New hints file: linux_2.sh
        * Help for setq() now included. Report by Flame@Babylon5
        * Added -w to the ps in restart so the output isn't
          truncated. [PeaK]
        * Restart changes to prevent some race conditions under Linux 2.0
          [Peak]


& 1.6.9p1
Version 1.6.9 patchlevel 1               September 26, 1996

New Function:

        * setr() is like setq() but returns the string as well.
          It's identical to [setq(#,string)]%q#. Suggested by Adam Dray.

Fixes:

        * Bug with @clone fixed. Report by Vedui.
        * Bug with @mail folder 15 fixed. Report by Vedui.
        * @sitelock/register worked backward. Fixed. Report by [MPC]
        * rnum() now requires that you can examine the room.
          By Jason Rhodes, with minor mods.
        * Better messages when a player or thing is set audible.
          Suggested by Babylon5@kuwait.net
        * Configure now uses your email address instead of your name
          when trying to subscribe to the mailing list; on some systems,
          it's hard to get a valid name -- getting an email address
          is usually possible. Suggested by Cro@Spaceballs
        * Configure no longer adds multiple copies of the same gcc
          warning flags when you run it again. Reported by Cro@Spaceballs

& 1.6.9p0
Version 1.6.9 patchlevel 0               September 16, 1996

Attribute Rewrite [TAP]:

        * There is now a distinction between an empty attribute and
          a non-existant attribute:
                @va me          <--- wipes out my VA attribute
                @va me=         <--- sets my VA attribute to be empty
          Empty attributes retain their locks and flags; wiped attributes
          are gone forever.
        * @set and set() can not wipe out attributes. @wipe and wipe()
          will.
        * You can now include ':'s in $-command and ^-command patterns
          by escaping them with '\'.
        * Standard attribute names are kept in a string table and
          memory is not allocated for them. We guesstimate a 3-5%
          savings in memory use from this change.
        * objmem() and playermem() are now more accurate.
        * Internal changes: new attribute flags AF_STATIC, AF_COMMAND,
          AF_LISTEN; atr_comm_match doesn't look directly at compressed
          strings any more; restructured some routines (atr_clr to clear
          attributes, atr_add to set them).

Fixes:
        
        * Add help topic SETTING-ATTRIBUTES to explain the above.
        * Fixed small error with closing a NULL file in access.c [TAP]
        * Improved help for @destroy
        * Dashed lines in @mail are now 2 hyphens longer. [MPC]
        * The Configure hints files weren't properly used when
          compiling with gcc.
        * The color flag is now aliased to colour as well. [MPC]
        * With MAIL_SUBJECTS, the @mail/list could get scrambled
          for messages from players with long names. Reported by
          Leto@DuneII.
        * Small memory leak when access.cnf is reloaded via kill -HUP
          has been fixed.
        * Vestige of old TEMPLE code removed from do_drop. Reported
          by Mike Selewski.

& 1.6.8p1
Version 1.6.8 patchlevel 1               September 7, 1996

Fixes:
        * The mail*() functions were broken due to a typo. [MPC]
        * The addr field in the descriptor structure has been expanded
          from 50 characters to 100 characters, because you'd really
          like to store the entire ident response from encrypting
          ident daemons.
        * The MAIL: announcement at login now counts your cleared
          mail in your mail totals, in case something clears mail for
          you while you're offline. Suggested by Mike Wesson.
        * Better string protection for parse_chat which may fix
          a potential crash when speaking on +channels.

& 1.6.8p0
Version 1.6.8 patchlevel 0               September 3, 1996

This is intended as a maintenance release because 1.6.7 has had
many rapid patches to achieve stability.

Fixes:
        * "make install" now implies "make all". Corrects a problem
          with not remaking hdrs/buildinf.h.
        * README file now shows the utils directory in its directory tree.
          Reported by Mike@StarWars.
        * On startup, PennMUSH now logs its version information.
        * @log/wiz was logging to trace log, not wiz log. Reported by
          Dean Moore.
        * @mail system behaved badly if you @shutdown on an empty
          maildb on some systems. Reported by Mike Selewski.
        * Detection of getpagesize() system call is now handled by 
          Configure. Fixes problems on Irix, reported by Mike Selewski. 
        * Minor typo in Irix hints file fixed.
        * Stupid misspelling of August in CHANGES-10 fixed.

& 1.6.7p6
Version 1.6.7 patchlevel 6               August 31, 1996

Fixes:
        * The attribute clear fix in 1.6.7p5 is buggy. Now it's really
          fixed. Report by [MPC].


& 1.6.7p5
Version 1.6.7 patchlevel 5               August 30, 1996

Fixes:
        * Sites not listed in the access.cnf file should have been
          allowed, not denied access. Fixed. Best report by Cwilla@Victory
        * A little more info in mush.cnf about how player_creation and
          access.cnf interact
        * Trying to clear a never-existant attribute got the right
          error message, but clearing an attribute that had existed,
          but been already cleared got the "Foo - Set." message.
          Fixed - atr_add now skips disposed attributes.  Report by [MPC]


& 1.6.7p4
Version 1.6.7 patchlevel 4               August 28, 1996

Fixes:
        * Bug in mail functions that caused mail(1:0) to crash
          has been fixed. Reported by Corum@StormWorld.
        * Another Win32 fix by Pat Pinatiello.


& 1.6.7p3
Version 1.6.7 patchlevel 3               August 28, 1996

Fixes:
        * Configure wasn't setting HAS_SENDMAIL correctly because the
          updated config_h.SH wasn't included in the diff!
        * @mail/clear's message about unread mail was screwy.


& 1.6.7p2
Version 1.6.7 patchlevel 2               August 27, 1996

Fixes:
        * Forbidden_Site wasn't working quite right
        * Win32 compatibility improvements suggested by Pat Pinatiello.
          Hopefully, no further real hacking should be required to 
          build under Win32 with Visual C++. Pat's instructions included
          as win32/README.visualc++


& 1.6.7p1
Version 1.6.7 patchlevel 1               August 27, 1996

Fixes:
        * #ifdef's and the like were missing which prevent compilation
          unless HAS_SENDMAIL and CHAT_SYSTEM (>2) were defined.
          Fixed by [TAP].


& 1.6.7p0
Version 1.6.7 patchlevel 0               August 22, 1996

Major Changes:

        * The lockout.cnf and sites.cnf files are no longer used.
          Instead, the file game/access.cnf controls all aspects of
          site-based (or, with ident, possibly user-based) access.
          Sites can be explicitly allowed or denied the ability to:
            * Connect to guest players
            * Connect to non-guest players
            * Create players
          Sites can be configured to:
            * Use email registration (see below)
            * Set all players from the site SUSPECT
          See the file game/access.README for file format information.
          The LOCKOUT and WCREATE defines have been removed from options.h.

        * A new access option, email registration, is available.
          From the connection screen, the command
            register <player> <email address>
          will create the player with a random password, which will be
          emailed to the address. The email address is stored on the player
          in the wiz-only attribute REGISTERED_EMAIL. 
          Obviously, this requires that the system have a way to send email.
          Ideas in this code came from Jim Cook.

        * @powers are now tabled in flags.c.

        * Nick Gammon's word-based compression algorithm is now
          COMPRESSION_TYPE 3. This algorithm may be faster than
          Huffman on the whole, and may provide better compression
          for large (>1.5Mb of text) databases.

        * @mail message-lists now understand the format [folder#:]msg[-msg]
          For example, the first 3 messages in folder 1 are 1:1-3.
          @mail commands that are not given any message list are assumed
          to apply to all messages in the current folder. You can also
          do this explicitly by using the word "folder". When you use
          the word "all", you match all messages in all folders.
          For example, try: @mail all
          @mail internals rewritten to increase code reuse.

New Commands:

        * @sitelock has got an additional syntax to support the new
          access.cnf system.

New Functions:

        * powers() returns the list of powers set on a thing.
          If HASPOWER_RESTRICTED is defined, you must be able to
          examine the thing to do this.
        * mail(), mailtime(), mailstatus(), and mailfrom() now accept
          this syntax:
                mail([<player>,] [<folder #>:]<message #>)
        * cemit() does what you'd expect. Suggested by [MPC].

New Powers:

        * Open_Anywhere power allows the player to open an exit between
          to any room, even if the player does not control the source
          or target room.


Minor Changes:

        * Previously, a player with the Halt power could use
          @halt obj=command to effectively @force any object.
          This form of @halt is now only allowed if you control the
          object. Bug reported by Flame.

        * When EXTENDED_ANSI is defined, ansi codes are stripped out
          of strings before checking them against LISTEN and ^patterns.
          Suggested by Mike Wesson.

        * HAVEN players are no longer notified when they send back
          an @haven message in response to a page. Page-locked players
          still are. Suggested by Naomi Novik.

        * @decompile me results in a decompile with "me" as the object name
          @decompile <player> results in the player's name as the object name
          @decompile of an exit will use the exit's short name instead of
          its full name for setting attributes and flags. 

        * Utilty scripts (customize.pl, update.pl, update-cnf.pl, 
          fixdepend.pl, and make_access_cnf.sh) are now in the utils/
          subdirectory.

        * Default rwho server is now littlewood.math.okstate.edu,
          which replaces riemann, which has been turned off.

        * time() and convsecs() now indicate the first 9 days of the
          month as 01..09, rather than 1-9, which makes convtime()
          happier when you convert back.

        * You may @tel an exit back into its own room. Added for
          compatibility with other MUSH flavors. Suggestion by Philip Mak.

        * Dark connections are now broadcast only to MONITOR wizards and
          royalty. This involved replacing the raw_broadcast and
          toggle_broadcast functions with a new flag_broadcast function
          which subsumes them. Suggestion by Philip Mak.

Fixes:
        * Noted the 256-character limit on channel descriptions in the help.
        * abs() now deals correctly with floating points.
        * Win32 compatibility improvements suggested by Pat Pinatiello.
        * Updates to BUGS, README.Deprecated, and FAQ [TAP]
        * An ANSI_NORMAL is sent at the end of the Doing message in WHO.
        * mail() and related functions now accept "me". Bug noted by
          Mike@TBFF
        * Help for @squota no longer says that it works like @quota
          when no limit is given, because it doesn't. 
        * Bigram compression was not freeing memory that it used
          for initialization. Fixed, and made faster.
        * Help for @unlink fixed; you can't pick up unlinked exits. [TAP]
        * Potential string overflow in new_connection fixed. Idea by [TAP]
        * Code cleanup: many old sections that were commented out
          with #ifdef NEVER ... #endif have been removed.
        * @set obj=!going gave an error message but still reset the flag.
          Now it should just give the error. Reported by Philip Mak.

& 1.6.6p0
Version 1.6.6 patchlevel 0               July 28, 1996

This version involves primarily cleaning up and streamlining code
in preparation for major internal changes in later releases.

Major Changes:
        * The following options are now standard and no longer turned
          on via dune.h/options.h: RALPH_LOCKS, EXTENDED_MAIL, 
          INHERIT_FLAG. [TAP]

New Commands:
        * @firstexit command moves an exit to be first in the list of 
          a room's exits. Based on contrib/topexit.165p3 by Marlek@Earth1996
          (but note that it requires control over the *room*, not the
          exit).

New Functions:
        * poll() returns the current poll. By William Knopes.

Flags:
        * TEMPLE flag has been removed. This requires adding a new
          DBF bit. [TAP]

Minor Changes:
        * Admin no longer automatically pass leave-locks and NO_LEAVE.
          Suggested by Naomi Novik. [TAP]

Fixes:
        * Users could cause an infinite loop with @mail/fwd. Fixed.
        * The fix to pmatch() in 165p4 didn't quite do the job.
          Alex's does. [TAP]
        * @mail/stat commands now show correct number of cleared messages.
          Bug reported by [MPC]
        * Typo fixed in help for items() [MPC]
        * help for BUILDER now calls it a power, not a flag.


& 1.6.5p4
Version 1.6.5 patchlevel 4               July 9, 1996

New Functions:
        * entrances() works like @entrances, including the cost.
          Suggested by Julienna@TrekMUSH.

Commands:
        * whisper/list takes multiple recipients. Suggested by [MPC].

Minor Changes:
        * A DARK-reconnected message has been added. Idea by [MPC]
        * LFAIL/OLFAIL/ALFAIL attributes now control the message
          seen when a player fails to leave an object due to the
          NO_LEAVE flag or a leave-lock.  By Naomi Novik.

Fixes:
        * pmatch() on a DARK or hidden player by an unpriv'd player
          now returns #-1 (can't find the player).
        * inc(very_big_n) now works exactly like add(1,very_big_n) instead
          of returning a huge negative number. Same for dec(). 
          Reported by [MPC].
        * Fixed spelling of Tinyfugue in help @decompile. [MPC]
        * Documented the way hasflag() works a bit better to forestall
          a common confusion: why hasflag(me,r) doesn't check for the
          royalty flag.
        * If a player tries to join a channel she's already on but
          which has since been locked against her, she receives the
          already-on-channel message now instead of the can't-join
          message. Suggested by Cwilla@VictoryMUSH.
        * Compile-time information in @version has been expanded and
          made much more robust for systems whose make program is
          broken. We now create the file hdrs/buildinf.h at the
          beginning of each build, which contains the info.
        * WHO at the connect screen works correctly now even if 
          #0 is privileged. Bug reported by Doyce Testerman.


& 1.6.5p3
Version 1.6.5 patchlevel 3              June 29, 1996

New Command:

        * @shutdown/panic causes a panic dump and shutdown. God-only. [RLM]

Minor Changes:

        * When you destroy a room you don't own, the "wrecking ball"
          message now includes the name of the owner, like the messages
          when you destroy objects you don't own. Suggested by
          Matt Chatterley.
        * The channels() function, with no arguments, returns the
          list of all channels (which the player can see).

Fixes:
        * When you try to get an object that's not in your location,
          and POSSESSIVE_GET is not defined, you don't receive
          any message at all. Fixed by Thaddeus Parkinson.
        * DARK-disconnect messages now appear.
        * All calls to random changed to getrandom (except the one
          in getrandom!), and the prototype for random removed from
          utils.c, where it causes conflicts for at least OSF/1.
        * portmsg.c extensively hacked to use the autoconfiguration
          info so you can "make portmsg" on supported systems.
        * Help for mortal() and @mortal removed. [RLM]


& 1.6.5p2
Version 1.6.5 patchlevel 2              June 19, 1996

Fixes:
        * @grep didn't check to be sure you were allowed to see
          the attributes it searched. Reported by Mike Wesson.


& 1.6.5p1
Version 1.6.5 patchlevel 1              June 12, 1996

New Functions:
        * channels(dbref) returns the list of channel names that 
          dbref is on.

Fixes:
        * When paging player(s) with spaces in their names, the
          LASTPAGED attribute stores them with quotes around them,
          so that repaging will work.
        * @mail/fwd shows you how many players it successfully
          forwarded to. 
        * @chzone here=none produced a spurious message if here was
          Wiz/roy. Fixed. Reported by Matt Chatterley.
        * udefault failed to evaluate the arguments it passed to the
          attribute to be u'd. Reported by PeaK.
        * Added include of sys/types.h in ident code. Necessary for
          FreeBSD.
        * @chf would not return a Huh? Fix by Hemlock MUSH admin.
        
& 1.6.5p0
Version 1.6.5 patchlevel 0              June 2, 1996

Database:
        
        * The "One" character in minimal.db.Z (#1, aka God) is now
          distributed without a password. This takes care of people
          who don't have crypt(3) or have a modified one (FreeBSD),
          since you now log in without a password, and set one,
          and all is well.

Documentation:

        * README has been extensively updated.

Minor Changes:

        * When paging, LASTPAGED is set to the list of succesfully
          paged players' names, if any page was successful. This
          is how page/list always worked; now applies to normal page.
        * &foo obj = bar used to set FOO to " bar". Similarly, you
          could use page/noeval (or any speech command with /noeval)
          to page messages with initial spaces. For TinyMUSH compatibility,
          this is no longer possible; leading spaces are trimmed now. [TAP]
        * F_INTERNAL flags (like GOING) are now visible unless they're
          also F_DARK. [RLM]
        * When you @decomp obj/atr and atr doesn't exist, you now get
          a message about it. Suggested by Matt Chatterley.
        * PREFIX semantics now like INPREFIX (see 1.6.4p2) [TAP]

Fixes:

        * Bug in parse.c which could causes crashes fixed. Reported
          by Atuarre. [TAP]
        * On at least 2 systems, the system date was screwed up,
          which made updating dune.h and options.h still produce
          files younger than dune.h.dist and options.h.dist.
          This is not our fault, but we'll fix it anyway - now we
          touch dune.h.dist and options.h.dist before we update
          dune.h and options.h. 
        * @wiping a STARTUP attribute didn't reset the STARTUP flag. [TAP]
        * Fixed bugs in the freebsd hints.
        * All of a sudden, linux systems have started barfing on
          our declaration of signal() in externs.h. All right, if they
          want to play that way, we now test for this in Configure
          and don't declare it ourselves if it would break things.
        * Changed Amberyl's address in the source to lwl@digex.net
        * Somehow the fix for add(+1,0) got left out of 1.6.4. Back in. 
        * The ansi() function now produces underscore with "u", as
          advertised. [TAP]
        * Warning about discarding const in assignment fixed in game.c.

& 1.6.4p2
Version 1.6.4 patchlevel 2              May 14, 1996

Minor Changes:
        * At game startup, semaphores on all objects are cleared.
          Prevents objects from having leftover semaphore states after
          a shutdown. [TAP]
          INCOMPATIBILITY WARNING! If you have objects which expect
          to always have sempahore -1 (or something else), be sure
          that they do "@drain me; @notify me" in their STARTUP
          (as recommended in Amberyl's MUSH Manual).

Fixes:
        * @dump/paranoid produced db's with incorrect db flags
          when CHAT_SYSTEM was 3 or 4. Reported by Matt Chatterley.
        * Under certain conditions, one could get inside a ZMO using
          the "go" command. Fixed. [RLM]
        * A strcpy in fun_match is now a safe_str. [PeaK]
        * INPREFIX fixes: (1) no space if INPREFIX evals to a null string,
          (2) message to be prefixed is passed as %0, (3) %1-%9 are
          temporarily cleared. [TAP]


& 1.6.4p1
Version 1.6.4 patchlevel 1              May 11, 1996

Fixes:
        * Forgot to #ifdef MAIL_SUBJECTS around fun_mailsubject.
          Reported by Mercurial Mink@Protean.
        * Quirk in @dbck fixed. [RLM]
        * Possible denial of service attack using repeat() fixed. [RLM/TAP]
        * Problem with Configure script under certain conditions (esp FreeBSD)
          producing bad compiler flags fixed. Report by Mike Wilson.

& 1.6.4p0
Version 1.6.4 patchlevel 0              May 3, 1996

Major Changes:
        * eval_boolexp rewritten again. Important features:
          - If A is locked to @B, evaluating A's lock is identical
            to evaluating B's lock
          - To do an indirect lock or an elock(), you must be able to
            read the lock on the target object (i.e., you must be
            See_All, control the object, or it must be Visual)
            (New macros Can_Run_Lock and Can_Read_Lock for this)
          - As a result, channel locks will work as advertised if
            you indirect-lock them to VISUAL objects
        * Changes to handling of plain strings (with no evaluation)
          resulting in doubling of speed. [TAP]
        * If you fail the page-lock on a DARK player, you receive their
          AWAY message rather than their HAVEN message. That is,
          failing a page-lock on a DARK player is just like paging
          a DARK HAVEN player.
        * INHERIT check moved to controls() function

New functions:
        * mailsubject() returns subject of a given mail message,
          analogous to mail() and mailfrom(). By Atuarre.

Minor Changes:
        * Don't go through some major sections of the parser if we've
          be given PE_NOTHING. Performance boost. [TAP]
        * Players who are allowed to idle past inactivity limit, and
          are unfindable, and can hide, are hidden (as before), but
          only receive the notification once, instead of every
          hour (or whatever your limit is). Players who are all of the
          above but can't hide don't get any notification now.
          Suggested by Gepht@Hemlock
        * When allocating a new boolexp, set its struct members to
          null values for better debugging. [RLM]
        * We no longer save/restore the r-values when evaluating
          the left side of the equal sign in attribute setting.
          So @desc %q0 = %q0 now works as expected. Reported by PeaK.
        * Locks set when players are initially created (lock, elock)
          are now set to "=me" instead of "me". [PeaK]

Fixes:
        * When EX_PUBLIC_ATTRIBS wasn't defined, you never saw the
          DESCRIBE attribute listed when you examined objects. [AKM]
        * Vacation and Connected were being handled incorrectly
          internally; the type of object wasn't being checked. [TAP]
        * Now that Connected is fixed, the call to @doing doesn't have
          to prefilter for players, so don't. [TAP]
        * +nn is now considered a number, so add(+20,1) works.
          Reported by Dennis De Marco.
        * String boundary problems sometimes when you hit the 
          function recursion limit could cause crashes. Fixed.
          Reported by Oliver Stoll. [TAP]
        * Making on Linux should hopefully now work with -g. [PeaK]
        * Warning message when @chzoning an inherit player used
          to be announced when @chzoning *any* player. Fixed. [PeaK]


& 1.6.3p7
Version 1.6.3 patchlevel 7              April 25, 1996

Fixes:
        * beep() works without arguments now, as promised. [TAP]
        * repeat(string,-number) caused an infinite loop. Reported by
          Atuarre.
        * The create() function didn't accept a single argument. [RLM]
        * last(a b c) was returning " c" instead of "c". [TAP]
        * The Configure script did indeed send email to listproc if
          you asked to be subscribed to the pennmush mailing list.
          But it sent it with Precedence: junk, which listproc ignores.
          Fixed.
        * %q9 wasn't preserved due to a typo in function.c. Fixed. [PeaK]
        * SIGHUP now handled synchronously to prevent race conditions.
          Noted by PeaK.



& 1.6.3p6
Version 1.6.3 patchlevel 6              March 30, 1996

Minor Changes:
        * A channel's owner now always passes the channel's modlock.
        * Wizards may now do folderstats(player,folder). Previously
          on God could, but wizards could see the stats for the player's
          current folder, and could reset the current folder, so it
          doesn't make sense to restrict. Report by Cwilla@Victory-MUSH
        * @function is restricted to see_all players. Suggested by
          Oderus (Mike Wesson).

Fixes:
        * @sitelock/ban and @sitelock/register had their effects
          mixed up. Reported by Matt Chatterley.
        * Objects that were undestroyed were having the GOING flag
          removed but not the GOING_TWICE flag. Fixed. [RLM]
        * element() now works as advertised. [RLM]
        * Systems without IEEE math now can't do power(x,y) if
          *either* x or y is greater than 100. Report by InsaneJoseph@WoP



& 1.6.3p5
Version 1.6.3 patchlevel 5              March 12, 1996

New Powers:
        * The immortal power has been split into 3 powers:
          no_pay (has unlimited money), no_quota (has unlimited quota),
          and unkillable (can't be kill'd). For backwards compatibility,
          @set player=[!]immortal sets/unsets all three. Objects which
          were immortal before this patch will have all 3 flags set.

Minor Changes:
        * The DEBUG flag can now be set by any user. The Can_Debug power
          will automatically be removed from all objects.
        * The "directive not found" message in loading mush.cnf has been
          changed to a more comprehensible/less scary "directive in 
          cnf file ignored" message.

Fixes:
        * FIXED players can no longer "go home" or "move home"
        * index-files.pl was producing incorrectly titled index entries. [RLM]
        * More fixes to elock() and zone locks. Elock() should now work
          even when RALPH_LOCKS isn't defined. Zone locks are checked
          on the correct object. [TAP]
        * @open exit=variable should work correctly now. [TAP]


& 1.6.3p4
Version 1.6.3 patchlevel 4              February 27, 1996

Fixes:
        * Complex evaluation locks may be better behaved. [RLM]
        * ex/debug now shows flag bits in hex, not decimal [RLM]
        * % failed to quote the following character in some cases.
          Fixed to work like 1.50. [PeaK]
        * iter() only allowed a single-character output separator instead of
          an arbitrary string. Fixed. [PeaK]
        * Bug in extmail.c which caused crashes on find_exact_starting_point
          with newly created players may be fixed.
        * Repaging with page/list uses the correct format.
          Also, failing to page anyone successfully doesn't clobber
          LASTPAGED when using page/list.
        * Dark-connecting admin now trigger connection messages on
          admin chat channels (unless the channels are quiet)
        * Help for pos() corrected. 
        * Things starting with #- (error messages) are now treated as
          false (0) in boolean functions, as under 1.50. [TAP]
        * The recursive_member function was inefficient, and potentially
          buggy, which could allow things to be teleported into things
          they contained. Fixed.
        * @drain wasn't lowering QUEUE attrib. Fixed. [RLM]
        * Zone master help updated to refer to zone locks [RLM]
        * Memory malloc'd by replace string, though freed, didn't
          have its mem_check cleared in a few places, which could make
          it appear that replace_string was leaking. [PeaK]


& 1.6.3p3
Version 1.6.3 patchlevel 3              February 12, 1996

New option:
        * If NULL_EQ_ZERO is defined in dune.h, a null string will
          be considered a zero in a math function. For example,
          add(,3) will return 3, instead of #-1. 

Minor Changes:
        * Guests may not join or leave channels. [Mike Wesson, Oderus]

Fixes:
        * edefault() core dumps fixed.
        * eval() now behaves correctly. [TAP]
        * ALL players (inc. Wizards) now subject to BUILDING_LIMIT.
        * Quota now properly updated on object destruction. [RLM]
        * Misc. fixes to object destruction, especially in the case
          of what happens to SAFE objects of destroyed players. [RLM]
        * Queue was handled strangely for priv'd players. Fixed.
        * New internal macros NoQuota and NoKill, both the same as
          NoPay, established in preparation for future splitting of
          Immortal power into 3 powers.
        * help @clock2 typo fixed.


& 1.6.3p2
Version 1.6.3 patchlevel 2              February 7, 1996

[L@E] refers to Lukthil@ElendorMUSH, who did many patches to 1.50
that I'm just now getting to integrate.

Minor Changes:

        * Wizards are now effectively pemit_all
        * @dol/notify notifies even if given a null list. [L@E]
        * See_All players can see quotas with @quota. [L@E]
        * If we're logging forces, don't just log forces *by* wizards,
          log forces *of* wizards (and things they own) by anybody. 
          Idea by L@E.
        * Removed obsolete code: clear_atr_name
        * mkindx now sorts index entries alphabetically, so it
          doesn't matter what order you have get() and get_eval()
          in your help file - help get will give get().
          Code by Pavel Kankovsky (PeaK).

Fixes:
        * #-1 was being considered "true" instead of "false" when
          TINY22_BOOLEANS was not defined. [RLM]
        * munge() is better behaved when there are duplicates in the
          first list, accurately matching them with the second. [L@E]
        * Emits weren't propagating through audible exits when
          there was nobody in the room. Fix idea by L@E.
        * Charges were broken. Fix idea by L@E.
        * Immortal players could lose coins when their non-immortal
          objects ran code. Fixed. [L@E]
        * @edit is less likely to overflow buffers when using ^ and $. [L@E]
        * @halting objects used to queue them for #0. Fixed. [L@E]
        * Semaphores weren't removed when an object was halted. Fixed. [L@E]
        * Possible permissions problem in running STARTUP when objects
          are chowned fixed. [TAP]
        * make etags now picks up dune.h and options.h [RLM]
        * Code consolidation: chowning when an exit is linked is done
          via a call to chown_object now. [RLM]


& 1.6.3p1
Version 1.6.3 patchlevel 1              February 4, 1996


Minor Changes:

        * NO_LEAVE is now settable by anyone
        * The index-files.pl script indexes admin news and help separately.
        * *emit() functions can now have unescaped commas in their last
          argument (the message). [TAP]

Fixes:
        * lit() doesn't screw up on braces. [TAP]
        * @search and lsearch() using eval were broken. [TAP]
        * @unlock foo worked, and also gave a Huh?. Fixed. [RLM]
        * When a player was destroyed, their SAFE exits would be
          destroyed instead of chowned. Fixed. [RLM]


& 1.6.3p0
Version 1.6.3 patchlevel 0              January 31, 1996

Major Changes:

        * Assume that object A is locked to @B, and object B is
          locked to canuse/1. It used to be that when player P tried
          to pass the lock on A, the canuse attribute on *A* was
          checked, instead of B. Fixing that required that we check
          to be sure that B is allowed to evaluate the CANUSE attribute
          on A, which required internal changes to boolexp.c.

Minor Changes:

        * Objects can now send mail as themselves, not their players.
          Mail from objects is reported as being from an object
          when read. The format for @mail(/read) has changed somewhat.
        * page[/list] now stores the last player(s) you paged in a LASTPAGED
          attribute, so you can re-multipage. The behavior is a little
          different for page and page/list. Page stores exactly what
          you typed as the last player/list of players to page; page/list
          stores only those names for whom the page succeeded.

Fixes:

        * The site of last failed login used to be a visual attribute.
        * Parser misbehaved on: think ( foo ), removing spaces. [TAP]
        * @edit and related wasn't stripping leading spaces from the
          right side of the = sign. Fixed.
        * Problem with count of unread mail on login with EXTENDED_MAIL
          fixed.
        * @channel/rename can now rename a channel to the same name
          with case changes, without an error.
        * +channel now matches partial ambiguous channels in a smarter
          fashion - it looks for a channel you're on.
        * Better help for @clock
        * die(0,x) now returns 0. die(negative #,x) returns an error. [TAP]
        * @chan/decompile can be used by the channel's owner or
          anyone who passes the modlock, as well as Wizards.
        * Channel hide locks work right. [RLM]
        * @chan/decompile now shows the correct commands for locking
          channels. [RLM]

& 1.6.2p1
Version 1.6.2 patchlevel 1              January 28, 1996

Fixes:
        * get_eval error about # of args fixed.


& 1.6.2p0
Version 1.6.2 patchlevel 0              January 26, 1996

New Commands:

        * @mortal <command> lets a privileged player run a command
          as if they were unprivileged. [TAP]
        * ahelp/anews shows admin help/news topics to admin players. 
          Admin-only topics are in the same files (help.txt/news.txt),
          but topic names begin with '&'. For example:
          & for-all-players
          ...text...
          & &admin-only
          ...text...
        * page/list <players>=<message> will do a multipage with a less
          spammy format for the pager.

New Functions:

        * mortal() lets a privileged player evaluate as if there were
          unprivileged. [TAP]

New Flags:

        * MORTAL, to support @mortal and mortal(). Used internally, and
          not settable. Can be reset by Wizards, just in case, though. [TAP]

Minor Changes:

        * If you have a channel "admin" and a global +admin (no args),
          calling +admin will run the global, not give the
          "What do you want to say to that channel" message, under
          extended chat.
        * If a panic db is corrupt, the restart script will move it to
          save/PANICDB.corrupt instead of removing it.

Fixes:
        * Problems with compile when HAS_SIGACTION is undefined.
          Noted by Brian Favela, affects Linux.
        * Duplicate uselock check in atr_comm_match removed.
          Noted by Brian Favela.
        * Looking at an exit showed the full name and aliases, not just
          the full name. [TAP]
        * Compiling without EXTENDED_MAIL works right.
        * Potential buffer overflow problems in look_exits() fixed.
        * get_eval() really uses a /, not a comma, like the help says.
        * (Hopefully) last remnants of old parser removed from externs.h
        * @dol on an empty list now doesn't give the weird "what do you want
          to do with the list" message. @dol with an empty command does. [RLM]

& 1.6.1p1
Version 1.6.1 patchlevel 1              January 23, 1996

Fixes:
        * v(#), v(!),and v(N) now return the same thing as %#, %!, and %N.
          [RLM]

& 1.6.1p0
Version 1.6.1 patchlevel 0              January 21, 1996

New compile-time options:

        * SAFER_UFUN: when defined, prevents less priv'd objects from
          evaluating ufuns on more priv'd objects, which helps a
          potential security problem with side-effect functions.
          This is more of a stopgap -- control and security will be
          revamped in a future release -- but is recommended.

New .cnf directives:

        * player_creation enables/disables "create" at login screen.
          Also @enable/disable creation
        * use_dns enables/disables IP-to-hostname resolution

New Functions:

        * tel(thing,destination)
        * oemit([room/]object,messsage)
        * emit(message)
        * lemit(message)
        * remit(object, message)
        * zemit(zone, message)
        * timestring(secs,flag) converts seconds to #d #h #m #s
          format. If flag is 1, the string always includes all time
          periods (e.g. timestring(301,1) = 0d 0h 5m 1s). If flag is
          0 or omitted, only the necessary periods are included
          (e.g. timestring(301,0) = 5m 1s). 
        * left(string, n) returns the first n characters of the string
        * right(string, n) returns the last n characters of the string
        * hasflag() syntax extended to hasflag(obj[/attr],flag) for
          checking attribute flags as well.
        * functions() lists all enabled functions
        * atrlock(obj/attr[,<on|off>])
        * doing(player) returns a player's @doing if they can be see
          on the WHO list

Minor Changes:

        * @allquota now has /quiet switch, and works correctly when
          no limit is given. [NJG]
        * The restart script is now a lot smarter, and figures things
          out from mush.cnf. All that needs to be set is the location
          of the game directory, and if you use make customize, not
          even that.
        * @wall/@rwall/@wizwall with a null message fails. (src/speech.c)
        * SIGHUPs sent to the MUSH are now logged in netmush.log
        * Common code called when object ownership is changed has
          been encapsulated into a single function for modularity.
        * crypt() is now a macro on systems which can't define HAS_CRYPT

Fixes:  
        * The table() function was incorrectly truncating some
          list elements. Fixed. Report by Alaric@WoP
        * The match() function was returning an empty string instead
          of 0 when it failed to match. Fixed. Report by Alaric@WoP.
        * help math functions now list the transcendental and other
          floating point functions
        * map() and mix() were broken. Fixed. [TAP] (src/funlist.c)
        * @grep/print is now case-sensitive, like help says. (src/predicat.c)
        * Refunding money when objects are chowned 
          was refunding 10 coins, instead of the object deposit. [RLM]
        * convtime() hadn't been converted to the new parser,
          and therefore was broken. Fixed. (src/funtime.c)
        * Compilation warning in src/game.c fixed
        * Giving players large negative amounts of money was slightly
          broken and is now fixed. Obscure, eh? [RLM] (src/rob.c)
        * Misleading comment in options.h.dist about QUEUE_LOSS
          fixed. [RLM]
        * Help fixed to indicate that there's no longer a 10 dimension
          limit on vector functions.
        * Various missing prototypes corrected.
        * make customize now correctly sets the restart script
          executable, and installs links to netmud and mkindx.
        * Improved Win32 portability [NJG]
        * Fixes to default() and edefault() [TAP]

& 1.6.0p5
Version 1.6.0 patchlevel 5              January 17, 1996

Fixes: 
        * Extended chat: @chan/decomp shows privs correctly now
        * Extended chat: When a player is destroyed, channels they own
          are chowned to God.

& 1.6.0p4
Version 1.6.0 patchlevel 4              January 17, 1996

Fixes:
        * Extended chat: Formerly, non-players could create channels.
          No longer.
        * Extended chat: Channel creation cost is now refunded when
          channel is removed.
        * Help text for HALT (game/txt/pennflag.hlp) and SUBSTITUTIONS
          (game/txt/penn.hlp) now notes that HALTed objects do not
          evaluate functions or substitutions.
        * Nick Gammon's new email address is in README and win32/README


& 1.6.0p3
Version 1.6.0 patchlevel 3              January 16, 1996

Fixes:
        * default, edefault, udefault now work like Tiny 2.2, not eval'ing
          their arguments.
        * Many fixes to the extended chat system.
        * Fixed misspelling of Guest in @config.
        * @function on a non-existant object no longer crashes. [TAP]
        * Problems with paranoid dumps not setting the correct dbflags
          corrected. [TAP]
        * Problems with EXTENDED_MAIL crashing when using LOGOUT fixed. [RLM]
        * @warnings for exit-msgs and thing-msgs warned when there was
          no OFAIL on a locked exit/thing, which is silly. [1.6.0p1]
        * Started patching the CHANGES file, like I should.
        * Fixes customize.pl
        * Fixes update-cnf.pl so that 'make update' won't trash player_flags
          (and other repeatable directives) in mush.cnf
        * Fixes game/txt/README

& 1.6.0p0
Version 1.6.0 patchlevel 0              January 10, 1996

Major Changes:

        * New function parser with improved speed, sanity. [TAP]
        * Complete rewrite of destruction code. Undestroying supported
          for all objects, @adestroy works sanely, SAFE is safer,
          better consistency checking. [RLM]
        * Support for 'plural' gender for TinyMUSH compatibility. [2.2]
        * Most filenames are now 8.3, to support the win32 port
        * Some options have been moved to the runtime config file
          (dbcomp). Others have been removed entirely.
        * 'make update' will update runtime config directives
        * The chat system has been completely rewritten. Number of 
          channels is limited only by memory, channels are saved
          across shutdowns (modifying source to add channels never
          required), channels can be locked in various ways, 
          non-wizards can create channels, etc.
        * New .cnf directives: chat_database (where to store channels),
          max_player_chans (how many channels can a non-admin create),
          chan_cost (how much does creating a channel cost)
        * The CSRI malloc is now supported and suggested. In addition
          to being extremely memory-efficient, it offers leak detection
          and profiling features.
        * The database format now defaults to quoting text, which is
          less vulnerable to corruption, in particular the loading of
          attribute locks starting with a number. [1.50-15-04,05 TAP]

New Functions:

        * matchall() [2.2]
        * default(), edefault(), udefault() [2.2]
        * aposs() and %a return absolute possessive pronouns [2.2]
        * elements() [2.2]
        * mudname(), version(), starttime() [2.2]
        * stats() is now an alias for lstats() [2.2]
        * ulocal() [2.2]
        * search() is now an alias for lsearch() [2.2]
        * folderstats() returns information about numbers of messages
          in a given @mail folder
        * last() is the counterpart to first(), and returns the last
          item in a list
        * mailtime(), mailstatus(). Suggested by Alaric@WorldOfPain.

New Commands:

        * @emit can be abbreviated '\\', for TinyMUSH compatibility
        * The speech commands (say, pose, @[po]emit, whisper, page)
          can now take a /noeval switch, which prevents them from
          evaluating the message.
        * 'semipose' is an alias for pose/nospace
        * 'INFO' from the connection screen gives version info for
          the MUSH, for use by automated mudlists and the like.
        * @sitelock/name adds names to the banned names file.
        * @enable/@disable guests (and new cnf file directive guest_allow)
        * @decomp now takes /flags and /attribs switches to only decompile
          the creation/flags information or the attribute information.
        * @list command partially implemented for TinyMUSH compatibility.

New Flags:

        * CLOUDY flag on exits provides partial transparency. A CLOUDY
          TRANSPARENT exit shows only the description of the room beyond, 
          no contents.  A CLOUDY but not TRANSPARENT exit shows only 
          the contents, no desc.
        * FORCE_WHITE flag on an ANSI player forces their output to be
          reset to white, necessary for some poor ansi terminals which
          "bleed". [Kalkin]

Minor Changes:

        * @chzone'ing an object to 'none' no longer clears its privbits.
        * OXMOVE attribute is shown to the room you're leaving.
        * Setting and resetting the SUSPECT flag is now logged in wizard.log
        * Various outdated defines have been removed from options.h/dune.h
        * Objects can now use @mail commands, as if they were their owners.

Fixes:

        * idlesecs() now accepts "me".
        * "pose" (not ":") used to discard everything after an "=".
        * The "entries" entries in help.txt, etc, have been fixed a bit.
        * index(a| |b,|,2,1) now returns a null string instead of "|b"
        * Various memory leaks [1.50-15-01]
        * When fork fails, a non-forking dump is done, and the MUSH
          no longer exits. [1.50-15-02]
        * Soundex() no longer hangs on non-alphabetical. [1.50-15-06]
        * dist2d and dist3d are safer on non-IEEE math systems. [1.50-15-03]
        * mail() now counts messages across all folders
        * Better matching of del_check to add_check [1.50-15-11]
        * PennMUSH now compiles correctly without EXTENDED_MAIL
          [1.50-15-10]
        * Some fixes to unparse.c to stabilize huffman compression
          [1.50-15-09,RLM]
        * Fixes to @boot [1.50-15-08,TAP]
        * Fixes to variable exit handling by quick-unparse [1.50-15-07,AKM]
        * Configure now tries to find a full path for uptime(1) so that
          @uptime will work
        * Fixes to forbidden_site and forbidden_name when there's no
          sites/lockout/names file. [NJG]
        * Backspace handling for really dumb terminals improved [NJG]
        * When changing the text of an attribute, its flags are no longer
          reset. [RLM]
        * When seizing a link, coins weren't refunded if the seize failed.

& 1.50p14
Version 1.50 patchlevel 14              July 3, 1995

This patchlevel is primarily concerned with bugfixes and patch management.

Maintainer changes:
  * New file 'Patchlevel' tracks mandatory patches to insure that they 
    are applied in the proper order
  * Clearer 'restart' script. [TAP]
  * The indexing script for help/news/etc now creates the topic 'Entries'
    instead of 'Index', to prevent a conflict with 'help index()'.
  * The file hdrs/db.h is now hdrs/mushdb.h, to match Tiny 2.2 and
    because FreeBSD complains about db.h.
  * The links hdrs/dune.h and hdrs/options.h were unnecessary and
    are now removed.
  * The noforking dump messages have been moved to mush.conf

Commands:
  * The @set obj1=attrib1:_obj2/attrib2 form no longer works, as
    it conflicts with general attempts to set attributes that start
    with underscores. Use @cpattr for copying attributes.

Options:
  * EXITS_CONNECT_ROOMS, if defined, prevents rooms with at least one
    exit from being announced to players as "disconnected rooms".
  * RALPH_DEBUG option allows for improved DEBUG flag output. [RLM]
  * When MEM_CHECK is defined, it dumps mem_check info to the
    checkpt.log before each dump.
  * SAFER_PLAYER_NAMES options has been removed. Player names can't
    contain those funny characters, period.

Fixes:
  * Added -D_INCLUDE_AES_SOURCE to hpux hints
  * stdlib.h is now included in eval.c to get atof. This was breaking
    linux MUSHes badly.
  * Linux hints now use BSD signal semantics.
  * Various attempts to fix possibly unusual bugs in compression.
  * The internal TRANSPARENT flag bit macro is now TRANSPARENTED,
    because Solaris defines TRANSPARENT
  * A bug causing setq'd registers to be incorrectly munged has been fixed.
  * @chzone warning messages refer to zone-lock, not elock, if RALPH_LOCKS
    are compiled in.
  * Examining a player who was on a null channel was reported to crash
    one MUSH. Some attempts have been made to fix that problem.
  * The compose.csh script in game/txt has been replaced by 
    compose.sh, which now deals properly with systems which are missing
    perl (gasp!)
  * Configure script hopefully won't die when checking signals on Linux.
  * Fixes to some strange @mail behavior. [RLM]
  * CType in compress_h.c is now unsigned long, not long. [RLM]
  * Fix to converting old maildbs to mail subjects [RLM]
  * Bigram compression could (rarely) cause $commands or ^patterns
    to stop functioning.
  * GoodObject() used to consider db_top to be a valid dbref. It's not.
  * Recycling of objects was broken in pl13 and is now fixed. [RLM]
  * mush.conf can now deal with the FIXED flag as a default flag [RLM]
  * A lot of mem_checks weren't being deleted, especially exec.buff ones.
  * Defining COMPRESSION_TYPE to be 0 (no compression) now works. [TAP]
  * Paranoid dumps no longer stomp out tabs and newlines unnecessarily.
  * Configure now checks for IEEE math compliance, and defines HAS_IEEE_MATH
    which is used by the code to determine if some math functions need
    to be limited.
  * SOLARIS defines have been removed as extraneous.

& 1.50p13
Version 1.50 patchlevel 13              June 1, 1995

Patchlevel 13 was very much a collaborative effort with Ralph Melton
and T. Alexander Popiel, terrific MUSHhacks.

Major user changes:

  * Complete rewrite of locks, which allows for many, many new
    locks, including user-defined locks, with reduced memory usage. [RLM]
  * @mail can now have a subject.

Major maintainer changes:
  * The code now contains ANSI prototypes (if Configure ascertains that
    your compiler likes 'em) for easier debugging.
  * The help, news, and events entries are now managed in subdirectories
    of game/txt/, and automatically indexed.
  * The names.conf file now accepts wildcards
  * New Makefile target 'update' will propagate your options.h/dune.h
    settings into an options.h.dist/dune.h.dist template, ask you
    whether you want to define any newly-introduced options, ask
    you if you want to remove any obsoleted options, and write out
    new options.h/dune.h files.
  * Improvements to the autoconfiguration scripts, which now generate
    a config.h and confmagic.h file in the top-level directory. These
    headers tell the code what kinds of features are available.
    Accordingly, the old hdrs/config.h header file has been renamed 
    hdrs/conf.h
  * The 'whisper_loudness' config directive in mush.conf sets the
    probability that a noisy whisper will be noticed in the room. 
  * If the standard Huffman attribute compression gives you trouble, you
    can use the COMPRESSION_TYPE define to use the older bigram
    compression system, now auto-tuning, or no compression at all.
  * The TINY22_BOOLEANS option causes the MUSH's boolean functions
    (and(), or(), not()) to be compatible with TinyMUSH 2.2. In Tiny 2.2,
    only non-zero integers are "true". In PennMUSH's default, non-zero
    integers, non-negative db#'s, and strings are "true". You pick.
  * NO_NUKE_SAFE_PLAYER prevents @nuke from working (for Wizards) on
    players set SAFE. You have to unSAFE them first.

New functions:

  * MWHO() function is like LWHO() but always evaluates as if the
    enactor were an unprivileged player. Useful for globals.
  * ISDAYLIGHT() returns 1 if it's daylight savings time, 0 if not.
    By Dave Sisson
  * CWHO() now returns a list of dbrefs, NOT NAMES. Much more flexible.
  * ITER() now can take a fourth argument, which is the output delimiter.
    You can have any string shoved between the output elements instead 
    of a space (for example, a %r).
  * TABLE() for presenting lists in rows.

New commands:

  * Players can connect with 'ch name password', which is just like
    'cd', but connects hidden. Activated by defining DARK_CONNECT
  * @warnings now allows players to exclude warnings by using
    @warnings me=!warning. [RLM]
  * @ps/quick now displays only the summary line of @ps for players.
  * @decomp can take a /tf switch, which makes its output emulate
    the 'FugueEdit' object (originally by van@TinyTIM) which
    lets you use tf to edit attributes. Idea by Lord Argon.

Minor changes:

  * The 'news code' and 'news changes' entries are now in help.txt,
    so you don't need to update your MUSH's news.txt files when you upgrade.
  * In an ambiguous situation (i.e., @dest foo when you carry
    foobar and foofoo), @dest will no longer pick one at random. It'll fail.
  * #0 is now evaluated as TRUE in the context of boolean functions,
    because it's a valid dbref (applies only #ifndef TINY22_BOOLEANS)
  * haspower() allows players to see powers on things they control,
    even with HASPOWER_RESTRICTED defined. [RLM]
  * O-attributes which evaluate to nothing are no longer displayed. [AKM]
  * Paranoid dumps no longer smash \r and \n.
  * @mvattr no longer deletes the original attribute if the copies fail.
  * Secure now stomps out ^'s
  * The getrandom() function has been rewritten. [RLM]
  * It's now a lot harder to have Guest and Wiz/Roy set on the same
    player. Players shouldn't be able to connect to Wiz/Roy Guests anymore.
  * HARSH_GUEST is now a lot harsher. Guests pretty much can't modify
    the database except to lock/unlock things they control.
  * players who are on a priv'd channel may speak/leave
    even after they lose their privs. [RLM]
  * Xenix options removed from options.h.dist, since the Xenix code
    isn't supported anymore anyway.
  * The size of MAX_COMMAND_LEN (and therefore all derived buffers)
    has been doubled.
  * Doing a 'make' from the src/ directory will now call the top-level
    makefile. This helps those who use emacs (like Ralph, who came up
    with this) and M-x compile from the srcdir.
  * @version shows compilation flags.
  * Admin WHO no longer wraps lines. Sitenames are truncated as needed. [TAP]

Fixes

  * Repaging a player with a multi-word name works correctly now.
  * Players with the tport_anything power can teleport FIXED things. 
  * @map works as documented again.
  * Paranoid @dumps don't give so many spurious bad attribute warnings.
  * ZMO elock checking now uses PLAYER_START and MASTER_ROOM instead
    of #0 and #2. [RLM]
  * @pemit/list now replaces ## with the target's db#, as the help says.
  * Subtle bug in exit matching fixed. [RLM]
  * escape() and secure() no longer parse their arguments.
  * The asterisk-line separators on the nologin messages have been
    prettified slightly, at Tigger's suggestion
  * Some systems didn't deal well with overflowing @doing and @poll's.
    Dave Sisson patched it.
  * Error in bsd.c when compiling with DARK_CONNECT but without ROYALTY
    fixed. (Reported by Suud@Gohs)
  * hasflag, andflags, and orflags patched to prevent mortals from
    using them to see mdark flags [RLM]
  * Type mismatch in warnings.c fixed [RLM]
  * fun_lcstr() and fun_ucstr() have been changed slightly in order to
    support unices like MachTen which appear to define tolower() as 
    a macro meaning (isupper(x) ? _tolower(x) : (x)), and were getting
    hosed by the tolower(*ap++) call. Bug reported by Adrick.
  * It was possible to overflow the buffers in do_log by having a 
    Wizard do @fo me=think lnum(5000), for example. No longer, I hope.
    Bug report and suggested fix by Adrick.
  * Removed an old bit of code that broke compiles using original mailer
  * The restart script is a little smarter about preserving databases.
  * Fixed a bug that caused ALWAYS_PARANOID to dump core.

& 1.50p12
Version 1.50 patchlevel 12              March 23, 1995

Major changes:

  * The matching routines in match.c have been rewritten to be
    reentrant, which fixes some subtle but important bugs
  * New Makefile target 'customize' for setting up customized
    per-mush subdirectories for those who run multiple mushes.
  * An untested DELETE_POWERS define in options.h, which will remove
    powers from a database, to make it easier to switch to TinyMUSH

New flags/powers:

  * Things with the Pemit_All power can @pemit to HAVEN/ulocked players.
    Useful for globals.

--- Fixes ---
  
  * Previously, passing the elock of a ZoneMaster player allowed 
    control over *all* the ZM's objects, including the ZM player itself.
    Players are no longer controllable this way.
  * Incorporated patch for compiling without CREATION_TIMES defined
  * Incorporated Ralph Melton's patch to warnings.c to fix core dump
    with multiple exits warning.
  * Nobody can @tel rooms any more. New code for @tel'ing exits has
    been written, however, and players may now @tel exits they control
    from rooms they control to rooms they control.
  * Z_TEL bug: players could defeat Z_TEL by entering an object and
    @tel'ing from there. Reported by Ralph Melton.
  * Bug in puppet checks in @teleport fixed.
  * Players in exactly 15 levels of container could defeat NO_TEL. Fixed.


& 1.50p11
Version 1.50 patchlevel 11              March 5, 1995

At Amberyl's suggestion, the "dune" numbering scheme has been 
abandoned. This is 1.50 pl11, and future versions will be numbered
accordingly.

Major changes:

  * All objects can now have creation dates. Non-player objects have
    attribute modification dates as well. Players have number of login
    failures since last logins tracked instead. Supported by
    ctime() and mtime() functions to return creation/modification time.
    (CREATION_TIMES define in dune.h)
  * The extended @mail system now maintains the maildb sorted by
    recipient, and each player descriptor has a pointer to where that
    player's mail begins in the maildb. This is much faster for reading 
    and listing and clearing mail, only slightly slower when sending.

New Commands:

  * @boot/me: boots a player's idle descriptor (to selfboot hung 
    connections).
  * whisper has two switches: silent and noisy. Standard PennMUSH whisper
    is silent, and is the default unless NOISY_WHISPER is defined.
  * @grep can take two new switches, /ilist and /iprint, which are just
    like /list and /print, but case-insensitive.

New Flags:

  * LIGHT (as in TinyMUSH): LIGHT objects/players appear in DARK rooms.
    In addition, LIGHT exits also show up.
  * Z_TEL: When set on a Zone Master Room or a room in a zone, prevents
    players from using @tel from that room to any room that's not in the
    same zone. Useful for puzzle areas or enforcing some IC constraints.

New Functions:

  * The lsearch() command can take a range of db#'s
  * ctime() and mtime() functions (if CREATION_TIMES is defined)
  * grepi() is a case-insensitive grep
  * hasattr() returns 1 if an object has a given attribute
  * hasattrp() returns 1 if an object or its parent has a given attribute

Minor Changes:

  * @away/@haven/@idle messages are not sent if they're null
  * Players always receive feedback when they use @hide
  * Players who are FIXED are now permitted to @tel objects into their
    inventory. This makes coding puppets which follow you much easier.

--- Fixes ---

  * examine/mortal now functions more like it should. 
  * If a ZMO was elocked to an object in #2, players couldn't @chzone
    things to it. Reported by Melkor@Beleriand. Fixed.
  * WHO is grammatical when reporting # of connected players. Idea
    from Kalkin.
  * The Connected ('c') flag is no longer visible to mortals.


& 1.50pdune2
Version 1.50 patchlevel dune2              March 5, 1995

DuneSource pl2 changes

Major changes:

  * Extensive warning system for things missing on objects, rooms, etc.
    @warnings command for players to set the level of warnings they want,
    @wcheck[/all] command for players to check an object (checks can also run
    at a God-configurable interval on the whole db), NOWARN flag for objects
    and players. Idea from Kalkin's adaptation of MUSE code, totally
    rewritten.
    

New options (dune.h):

  * GUEST_TEXTFILE option enables a textfile (guest.txt by default)
    to be shown to Guests who log in. Idea and source code from Kalkin.
  * PAGELOCK_NOT_USELOCK option causes @lock/use to fail for players,
    requiring them to type @lock/page. The lock itself has not changed,
    just the interface, to remind players of its function. By Ralph Melton.
  * More control over possessive gets with the POSSESSIVE_GET define
    and the POSSGET_ON_DISCONNECTED define. Possessive get can be
    disabled, enabled for all but disconnected players, or enabled
    at all times (the default PennMUSH behavior)

New functions:

  * lit() returns its input totally unparsed, and without spaces compressed.
  * t() returns the truthvalue of its input, guarranteed to be either
    1 or 0.
  * objmem() and playermem() functions, return the memory usage of
    an object or all of a player's objects. Requires search_all power.
  * grab(list,pattern[,delimiter]), returns the first element of list
    which patches the pattern. Patterns are of the match() type.
    From the TinyMUSH 2.2 code.

Minor Changes:

  * You must actually own an object (not just control it) or be a
    Wizard in order to set it chown_ok or dest_ok. By Ralph Melton.
  * You can use #$ in the actions in a switch() function
    or @switch/@select statement, and it will be replaced by the switch
    expression before executing or evaluating. This can improve
    efficiency and save space. For example:
        switch(complexfunc(%0),Bob,BobResult,#$)
    is equivalent to:
        switch(complexfunc(%0),Bob,BobResult,complexfunc(%0))
    but only requires a single evaluation of complexfunc(%0).
    Suggested by Kenric@DuneII.
  * "things" is a synonym for "objects" in @search now. By Ralph Melton

--- Fixes ---

  * #-2 is treated as a "0" (false, like #-1) in functions which need a
    logical value for it. Previously, it was treated as -2 (true).
  * @select is now considerably more efficient - it no longer will 
    evaluate anything after the matched action. The old behavior
    could well be a bug in the right conditions as well. 
  * atr_add now rejects null attribute names, so you probably can't set them
    any more. Suggested by Kalkin, the code's by Mike@StarWars.
  * Players can reset a DARK flag on themselves, but still can not
    set themselves DARK.
  * andflags(me,!Dc) used to return 1 if I am !dark and !connected,
    instead of !D and connected, as the help states. Fix by Ralph
    Melton.
  * Halting an object which is @wait'ing used to fail to decrement
    the owner's queue attrib. Fixed now. Patch by Ralph Melton.
  * set_flag uses strupper instead of upcasestr now, which should fix
    a bug on some systems wherein "cd" command would crash the MUSH and
    a similar bug wherein players connecting would crash the MUSH if
    the ON-VACATION flag was in use.
  * The old channel syntax (@channel foo=command) works again.
  * The RULES option now works.
  * The convtime() has been rewritten to work on NeXT's correctly.
    Previously, its malloc failed and it returned -1.
  * Systems which have getrlimit, but *don't* have RLIMIT_NOFILE,
    are now supported. Notably, Aix 2.x and 3.x.
  * The installation hints for Solaris 2 have been improved.
    WAIT_TYPE is defined as int, and if NBPC can't be found for
    getpagesize(), it'll try PAGESIZE instead. Thanks to Kalkin for these.
  * Installation for AIX has been improved. AIX required inclusion of
    sys/select.h in the IDENT stuff.
  * Various rewrites of tests against NOTHING to use the GoodObject()
    macro instead. Thanks to Ralph Melton for some of these.
  * Got rid of some warnings when compiling mkindx

 
& 1.50pdune1
Version 1.50 patchlevel dune1              March 5, 1995

DuneSource pl1 changes

Major changes:

  * Whem players attempt to log in to a Guest character that is already
    in use, the server tries to find one that isn't, and connects the
    player to that. If it can't, you get the old behavior (two connections
    to the single Guest).
  * Extended @mail system is available with many new mail commands.
  * Dump warnings 5 minutes and 1 minute before non-forking
    dump, and optional announcement at completion of dump.
  * Guest players may not set attributes.
  * Kill command can be disabled.
  * @aconnect/@adisconnect messages on individual rooms.

Changes to commands:

  * CD command at connection screen allows Wizards to connect to the game
    DARKly.
  * @sitelock command for on-the-fly sitelocking by Wizards.
  * @dump/paranoid can try to fix the db in memory, too.
  * @decomp/db, produces decomp output using dbref of object instead
    of its name.
  * ex/mortal, shows examine output as if player were mortal.
  * Option to rename @destroy to @recycle, since @dest and @desc are
    easy to confuse.
  * @restart command. Combines an @halt with triggering @startup.
  * @hide now provides feedback when used.
  * @find may be restricted to royalty, the only ones for whom it might
    possibly be useful.
  * @function now lets you know when it updates an @function.
  * The old (pl8?) @channel <channel>=<function> syntax is back, along
    with @channel/<function> <channel>, for those who liked it.
  * @grep can be either case-sensitive or not (the default).
  * If you don't specify the destination attribute in @cpattr, it
    assumes you want the same attrib name as the source attrib.
  * @mvattr, like @cpattr, but removes old attribute.
  * ANSI players now see their @edit additions in bold.
  * Rooms and exits can @emit. Rooms @emit into themselves (like @remit),
    and exits @emit to their source room.
  * @squota can now be given quota levels as +<quota> or -<quota>, to
    increase or decrease a player's quota from its current level.

Changes to functions:

  * encrypt() and decrypt() functions.
  * hidden() function for checking if a player is hidden.
  * hastype() function for checking if a thing is a given type.
  * pemit() function sends pemits to a list of objects.
  * lparent() function, returns object's parent, grandparent, etc.
  * quota() function, returns a player's quota.
  * N-dimensional vector arithmetic functions: vadd(), vmul(), vsub(),
    vmag(), vdim(), vunit()
  * haspower() can be restricted to admin.
  * "Lower math" functions: shr(), shl(), inc(), dec()
  * beep() with no arguments produces a single beep.
  * pmatch() will now accept *player or #dbref arguments.
  * lsearchr() function does an lsearch *backwards* through the db.

Changes to flags/powers:

  * Flags can be defined as dark (invisible to all but God), 
    mdark (invisible to mortals), and odark (invisible to mortals who don't
    own the object) in flags.c.
  * @cemit can be granted as a power
  * The ability to set/unset the DEBUG flag on objects the player controls
    can be granted as the Can_Debug power. (Idea by Kenric@DuneII)
  * Optional COLOR flag to control reception of ANSI color apart from
    ANSI hiliting.
  * OPAQUE flag on exits. OPAQUE exits in translucent rooms look
    like normal exits in non-translucent rooms.
  * FIXED flag prevents @tel and home.
  * DARK Wizards need not trigger @aenter.
  * The SUSPECT flag is now abbreviated 's'.
  * NO_LEAVE flag on objects prevents 'leave' command from working in them.
    Useful for flying vehicles and the like.

Minor changes:

  * &adestroy attribute triggered when object is dest'd.
  * Player/room/object names can appear automatically in bold.
  * Dark and Hidden players are distinguished on the admin WHO list
  * Dark and Hidden players are indicated on the admin DOING list
  * Wizards who idle are set hidden, not DARK. Same for royalty.
  * DARK wizards enter and leave @chat channels silently.
  * Royalty can now see the Wizard @channel/list
  * The mortal @channel/list lists only public channels.
  * @idle/@haven/@away attribs which evaluate to nothing are not
    sent to the paging player.

--- Fixes ---

  * TRANSPARENT variable exits don't crash the MUSH when looked at.
  * @channel/delete and @channel/privs take the right number of arguments
  * @decomp now decompiles flags properly.
  * When logins are disabled, players may not create characters.
  * The controls() function is made safer. Defining SAFER_CONTROL prevents
    anyone but God from controlling God, any non-wizard from controlling
    anything with a wizbit, and any non-admin from controlling anything with
    a roybit.
  * Player names are made safer. Defining SAFER_PLAYER_NAMES prevents the
    use of [, ], %, and \ in player names.
  * The strupper() function is made safer.
  * Mortals can remove the DEBUG flag on objects they own.
  * The set functions now take delimiters like they should.
  * Revwords() takes a delimeter, like it should.
  * @config displays whether function side effects are available correctly.
    It used to get it backwards.
  * Some checks against NOTHING have been changed to use the GoodObject()
    macro in look.c and possibly other places.
  * It's more difficult for players to enter themselves.
  * PLAYER_NAME_SPACES works right now, use double-quotes around 
    multi-word names.
  * haspower() on unknown powers now returns #-1 NO SUCH POWER instead
    of a null string.

& 1.50p10
Version 1.50 patchlevel 10              March 5, 1995

Patchlevel 10 Changes

New additions:
  - Guest is now a power. Set it on a player to restrict its command set. 
  - New power Announce, which controls the ability to @wall. 
  - Global r-registers are now preserved across the queue. 
  - '#@' now replaces to the list-place for iter() and @dolist. 
  - Timers now operate on absolute time, rather than game ticks. 
  - Checks of $commands now obey parent uselocks. 
  - Variable exit destinations.  When you attempt to go through one of these
      exits, it evaluates the exit's DESTINATION attribute as a
      U-function, and uses the result accordingly. 
  - Rooms can now be set LISTENER. The flag name has been changed to MONITOR
      (which is what it's called in 2.0), with LISTENER as an alias.
      (Thus the MONITOR flag on things/rooms and on players mean
      different things.) 
  - If the EXTENDED_ANSI option is turned on, it enables the ansi() function,
      allowing ANSI control codes to be used.  
  - New wizard command @log can write information to a log file.  
  - @oemit now takes its target location from the person to exclude, not
      the person who is doing the @oemit (consistent with 2.0 behavior,
      and more flexible).  
  - @ps now follows the 2.0 syntax. Items deleted from the queue are now
    counted, and the entire thing calls a single generic routine.

Function changes:
  - More functions take delimiters. The newly-modified ones are:
      extract(), filter(), first() fold(), iter(), match(), member(), munge(),
      rest(), revwords(), setdiff(), setinter(), setunion(), shuffle(), 
      sort(), splice(), wordpos(), words()
  - If function side effects are configured as enabled, the functions link(),
      set(), parent(), lock(), clone() and name() can make db changes.
  - controls() has been tweaked so it returns '#-1 <error message>' on invalid
      objects, for consistency with other functions and with 2.0.
  - delete() is now ldelete(). The new delete() function deletes characters
      from a string. This is a change to be consistent with 2.0.
  - lcon() is now consistent with the 2.0 convention -- no more partial lists;
      either you can get the entire list, or you can't get it at all.
  - locate() has some new parameters: 'c' matches 'carried exits', supported
      by match_carried_exit(). Exit matching now calls match_exit_internal().
      'X' allows random choice if the result is ambiguous (#-2).
  - lsearch() now takes an EVAL class.
  - objeval() evaluates its first argument.
  - owner() now can take an object/attribute pair.
  - sort() autodetects for floating point, and uses qsort.
  - User-defined functions, such as U(), now return an empty string, rather
     than #-1 SOME ERROR MESSAGE, because 2.0 behavior is to return an empty
     string, and, generally, the empty string is easier to handle.

New functions:
  - New substitution: %qN is equivalent to r(N)  (also twiddled v() slightly)
  - Findable(). Can <a> locate <b>? Useful for those WHO-list-type globals.
  - Foreach(). Works basically like MAP(), but on strings.
  - Haspower(). Like hasflag(), but for powers.
  - Ports(). Returns the network descriptors a player is connected to.
  - Rloc(). Returns an object's location at a variable level.
  - Sortby(). Sorts a list by an arbitrary u-function.
  - Stripansi(). Strips the ANSI codes from a string.

Important other changes:
  - Fixed a bug in the checking of ZMO locks in the game's internal controls().
      The privs parameter to eval_eboolexp() needs to be the ZMO in question,
      rather than the object itself, in order for attribute locks to work as
      would seem logical (the object being checked shouldn't even factor into
      the equation, since by definition zone control is based solely upon
      the ZMO's enter lock).
  - Because people seem to want it back, the "pose" command is back, together
      with a /nospace switch.
  - TRACE is now an alias for the DEBUG flag.
  - Player lookups on dbrefs work (i.e, '*#1' is now valid).
 
& 1.50p9
Version 1.50 patchlevel 9

Patchlevel 9 Changes

New additions:
  - @cemit command emits to a channel.
  - "Quiet" channels added. They don't show connect/disconnect or joined/left.
  - '%c' returns the current command.
  - @dolist/notify queues a '@notify me' after queueing the list commands.
  - @pemit/list pemits to a list of dbrefs. No more @dolist/@pemits needed!

New functions:
  - Center(): centers text on a field.
  - Cwho(): returns the names of players on a channel.
  - Isdbref(): checks if something's a valid dbref.
  - Map(): like iter() over a user-defined function.
  - Mix(): like map(), but takes two lists.
  - Munge(): combines lists, allowing you to do things like conversion sorts.
  - Objeval(): evaluates an expression from another object's viewpoint.
  - Trim(): trims characters at the beginning and/or end of strings.
 
Other changes:
  - Add(), And(), Mul(), and Or() can take up to 100 arguments.
  - Channel commands are now switch-form.
  - Debug-flag output is neater and more useful.
  - Default input line length is 2K.
  - @grep output format is neater and shorters. 
  - @link can link already-linked exits.
  - Locate() can take an 'l' parameter to check object location.
  - Output line termination is now carriage-return-newline.
  - Starting quota is now a conf option.
  - @wipe can take an object-attribute pattern.
 
Important bugfixes and modifications:
  - Controls() now obeys the inherit flag.
  - Enactor (%#) in idesc evaluates to the player, not to the object.
  - The escape character is stripped by the parser.
  - Listening objects trigger enter/leave messages in DARK rooms.
  - Matching is only done on exits if there is no exact match after trying
    all other possibilities.
  - Non-INHERIT things can no longer @parent things which are INHERIT.
  - Delete(foo%b,1) and Delete(foo,1) now return the same result.
  - Replace(foo%b,1,Test) and Replace(foo,1,Test) now return the same result.
  - Taking from an object is now governed by control, as well as ENTER_OK.

& 1.50p8
Version 1.50 patchlevel 8
 
Patchlevel 8 Changes
 
Major new features:
  - Players can now set an @alias.
 
New additions:
  - Player ZONE flag and ZoneMaster control provide "safer" zones.
  - @hide command hides player from WHO list.
  - @oemit can take a room dbref, behaving like @remit with an exception.
  - mortal_dark and wizard attribute flags are settable. 'm' and 'w'.
  - @pcreate power added.
  - Channels can be wiped.
 
New functions:
  - Visible(): can one object examine another object or attribute?
  - Items(), Element(): like Words() and Match(), but for arbitrary separators.
  - Delete(), Replace(), Insert(): list-manipulation, arbitrary separators.
  - Orflags(), Andflags(): check multiple flags.
  - Fullname(): full name of an object.
  - Many floating point functions.
 
Other changes:
  - Lattr() can take an <obj>/<wildcard> pattern.
  - @prefix and @inprefix do pronoun substitution.
  - @search can take an 'eval' parameter.
  - No second arg to @lock or @link unlocks/unlinks.
  - Mail() can now, for wizards, give info about other players' mail.
  - Sort() now 'autodetects' sort type. Nsort() has been removed.
  - Get_eval() is an alias for U() rather than Eval().
  - Non-listening objects trigger @aenter and @aleave.
  - @search, @find, and examine always ignore the MYOPIC flag.
  - Queue deposits get refunded at startup.
  - Words() uses ' ' as the delimiter, _not_ any whitespace.
 
Major bugfixes:
  - Many problems with flags have been fixed.
  - "#123's foo" is no longer matched the same as "#123".
  - Switch() nesting behaves properly.
  - Parser bug with '/' in pre-parsed attribute names fixed.
  - Remove() no longer screws up on things like 'remove(#434 #43 #22,#43)'
  - Index() and friends no longer screw up on null separators.
  - Squish() trims leading spaces properly.
  - Various bugs with setfunctions fixed.
  - Function recursion bug fixed.
  - @scan no longer chokes on '='.
  - no_inherit attribute flag works for real.
 
& 1.50p7
Version 1.50 patchlevel 7

Patchlevel 7 Changes
 
Major new features:
  - Powers system. Individual objects and players can be given the ability
    to do special things, such as "examine anything", "teleport anywhere",
    "boot players", etc. The BUILDER and IMMORTAL flags are now powers.
  - Expanded flag system. Some flags are valid for more types of objects,
    and flag lookups are quicker. The flag order is now alphabetized,
    first by "generic" object type, then by specific object type.
  - User-defined global functions, which behave just like built-in MUSH
    functions, but are programmed in MUSH in a UFUN() format (i.e. you
    can call them like any other function, i.e.  '@emit [my_function(foo)]')
    The "@function" command is used to define and list these functions.
  - Local variables (registers, numbered 0-9) which are retained for
    the duration of a single command. Extremely useful for storing long
    function evaluations, especially if you are programming "switchless".
    The setq() and r() functions are used to set and retrieve the registers.
  
New additions:
  - "no_clone" attribute flag (do not copy attribute when object is @clone'd)
  - "@config/functions" lists all functions.
 
New functions:
  - squish() removes leading and trailing spaces from a string, and crunches
    inter-word spaces down to a single space.
  - filter() returns members of a list for which a user-def'ed function
    evalutes to true ("1").
  - fold() recursively evaluates a user-def'ed function and list.
  - rjust() and ljust() pad strings with spaces (or another fill character)
  - nsort() sorts a list of numbers.
  - shuffle() randomizes order of elements in a list.
  - scramble() randomizes order of characters in a string.
  
Other changes:
  - cat() can take an arbitrary number of arguments.
  - conn() and idlesecs() now recognize #dbref and *player. idle() is now
    an alias for idlesecs().
  - "Exits:" line in examine is back.
  - examine on non-existent attribute(s) returns "No matching attributes."
  - NO_COMMAND doesn't block ^, since you have to set the LISTENER flag anyway.
  - @config shows a couple more options.
  - The QUIET flag suppresses "Drained.", "Notified.", and "Halted."
  - Debug and Verbose output no longer clobber the stack.
  - switch() and iter() nested within other functions works properly.
  - Players cannot enter objects remotely via dbref.

& 1.50p6
Version 1.50 patchlevel 6

Patchlevel 6 Changes
 
Major bugfixes:
  - Eval locks work with get(), ufun(), etc.
  - Rooms can use @trigger again.
  
Changes to the parser:
  - Spaces are no longer added around equals signs in 'say', 'pose', etc.
  - The construction '<name of object> <command>' can no longer be used to
    force a nearby object. '<dbref of object> <command>' still works.
  - ITER() is much better-behaved; escapes and braces in the second
    argument are no longer needed. It also now works properly with ufun().
  - switch() can now take up to 100 arguments. Arguments to it are not
    evaluated until needed.
  
Miscellaneous changes:
  - Royalty can now set themselves DARK, but this affects _only_ their
    visibility on the WHO list and related functions; they still appear
    in the visible contents list of a room, on channel who, etc.
  - Royalty can set themselves MONITOR.
  - The TERSE flag suppresses _only_ auto-look messages (so if you type
    'look here' while TERSE, you will get the description of the room).
  - VAL() function returns the leading numeric prefix of a string.
  - INDEX() is an extract()-like function which works for an arbitrary
    character separator.
  - WHERE() returns the "true" location of an object.
  - HOME(), etc. now works on objects you do not control but are VISUAL.
  - REPEAT() of something zero times returns a blank string, not an error.
  - Commands done in GOING rooms are no longer considered invalid.
  - "@parent <object>" by itself unparents an object.
  - Exits in the same room as you are considered "nearby".
  - All attribute fetches use the same permission checks. LINK_OK on a
    zone object no longer allows zfun() to be done on the object if
    the attribute cannot normally be read.
  - Attribute flag sets added (@set obj/atr = flag). There are three
    settable flags, 'visual', 'no_command', and 'no_inherit'. 'Examine'
    displays these as 'v', '$', and 'i'.
  - The lcon(), lexits(), con(), exit(), and next() functions now check
    permissions differently. You can use these functions on a location 
    that you own, or in a location that you are in and is not DARK.
    If you cannot check the room, these functions will return #-1 even
    if you have objects/exits in the room. This behavior is identical
    to TinyMUSH 2.0's, and provides more privacy.
  - 'examine' output for objects you don't control is now similar to
    TinyMUSH 2.0's. The option to examine public attributes by default
    is configurable.

& patchlevels
For information on a specific patchlevel of one of the versions listed,
type 'help <version>p<patchlevel>'. For example, 'help 1.7.2p3'

1.8.7: 0
1.8.6: 0, 1, 2
1.8.5: 0, 1, 2, 3, 4, 5, 6, 7
1.8.4: 0, 1, 2, 3, 4, 5, 6, 7, 8
1.8.3: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
1.8.2: 0, 1, 2, 3, 4, 5, 6, 7, 8
1.8.1: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
1.8.0: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
1.7.7: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
	19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
	36, 37, 38, 39, 40
1.7.6: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
1.7.5: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
1.7.4: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
	19, 20
1.7.3: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
1.7.2: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
	19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
1.7.1: 0, 1, 2, 3
1.7.0: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
1.6.10: 0, 1, 2, 3, 4, 5, 6
1.6.9: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
1.6.8: 0, 1
1.6.7: 0, 1, 2, 3, 4, 5, 6
1.6.6: 0
1.6.5: 0, 1, 2, 3, 4
1.6.4: 0, 1, 2
1.6.3: 0, 1, 2, 3, 4, 5, 6, 7
1.6.2: 0, 1
1.6.1: 0, 1
1.6.0: 0, 3, 4, 5
1.50: dune2, dune1, 6, 7, 8, 9, 10, 11, 12, 13, 14
