1 Introduction
1.1 History
TinyMUSH was written as a direct result of the original TinyMUD's
crash and burn due to terminal database bloat. This problem was solved in
MUSH by using more efficient methods of data storage as well as the
implementation of a destroy command, which allowed for the removal of
unwanted objects from the database.
After the @destroy command was implemented, additional features were
added, either from the author's own ideas or player's requests. It was not
unusual to see one's suggestion running on MUSH the next day, or even in
several hours. During this time, MUSH began wandering from site to site.
It started at smelt.berkeley.edu, and then moved to sigh.berkeley.edu.
After a brief vacation in Kentucky, it returned to sigh. However, sigh was
later removed from service after a failed OS upgrade, and TinyMUSH, as of
this writing, is no more (although there is a backup of it's data base.)
Fortunately, several other MUSHs have come online. The two major ones,
TinyTIM and TinyCWRU, have added their own home-grown modifications to the
original MUSH, which may at a later date become "official." This manual
will attempt to cover these additions as well. Not included in this
version of the manual are the last additions that were made on TinyMUSH,
since they have not made it to any other MUSH.
1.2 MUSH Overview
Programming in TinyMUSH can be likened to traditional object oriented
programming. All actions are achieved as a result of objects reactions to
their environment and to each other. Objects can modify themselves and
each other, as well as create new objects (spawn processes) that can handle
a task and then terminate (destroy themselves.) Some low-level math is
provided, as well as 26 "registers" per object which can either hold data
or program code. Objects can also perform most of the actions that real
players can, so that they can interact with players.
Objects can be set to respond to a number of different stimuli, such
as things they "see" or hear, receiving pennies, being dropped or killed.
This allows for the creation of autonomous machines which can be running
even if a player is not logged in. These machines can fulfill many of the
purposes that robots were used for on TinyMUD, and allows mere mortals to
create robot-like objects.
A quick nomenclature of objects in MUSH (in hopes of establishing up a
standard.) An object which is under the direct control of a player and/or
is relaying what it hears back to its owner is called a puppet. Objects
which are "running a program" so to speak are called machines. Machines
may interact with players, react to what they hear, or may just go about
randomly ignoring the outside world. Robots are either players that are
under the control of a remote program (such as Julia of TinyMUD fame) or
special players which are under the control of other players. Quite often
people will refer to machines as "bots," but are not to be confused with
the genuine article. MUSH resembles a "shell scripting" language more than
anything else.
If all of the above seems a bit complex, don't worry. Programming in
MUSH is usually simple if you know the commands, and now that you have this
manual, you will.
1.3 Manual Objectives and Assumptions
First, this manual assumes you know the basics of TinyMUD. If you
have never been on a TinyMUD (or one of its derivatives) before, it is
highly recommended that you get a manual on TinyMUD and learn the basic
commands before you try any of the advanced material in this manual. A
introductory guide to TinyMUD is probably available from the same place you
got this document. Most, if not all of the commands in MUD should work on
MUSH.
Second, this manual is not designed to give away all of the "tricks of
the trade" in MUSH programming. It is impossible to cover everything that
can be built in MUSH in a finite document. Just remember that all the
things in MUSH are made up of the commands in this document, and you should
be able to figure out a way to do just about anything.
The majority of this manual is excerpts from session logs of my
character, Croaker, creating things. To clarify just what is going on, the
following conventions will be observed. The extracts from the script will
be sectioned off from the text by a header line consisting of two dashed
lines around a statement of what the example shows. A greater-than sign,
">", at the beginning of a line will indicate text typed in by the player
(me.) If you wish to duplicate the example, you should type the text after
the ">." Please note, to avoid confusion, if the typed text "wraps around"
the screen (i.e. is continued on the next line) there will not be a ">" on
the next line. Also, the output from a command will be separated from the
next command by a blank line. All comments added in later for clarification
will be enclosed in a ">>" and "<<." Finally, to indicate the end of an
example session will be another dashed line.
--------------------------------
Example: an example session
--------------------------------
>"This would be a command that I typed in.
You say "This would be a command that I typed in."
>> This is a comment, and the text directly above is the <<
>> output from MUSH in response to my command <<
--------------------------------
And the bottom bar ends the session.
Several more notes. A lot of the things in here are much easier to do
if you are running TinyTalk. I won't go into creating TinyTalk macros and
such, but be aware that they can make your MUSHing experience a lot easier.
Also, through out the following sections, I may use the term "player" with
respect to commands. All commands also work for objects (whether they are
operating autonomously or under player control.) The use of the word
"player" in these sections therefore means "players and objects" except
where stated otherwise. To be concise, I will use the terms TinyMUSH and
MUSH interchangeably. Also, MUD will refer to TinyMUD, not the original
MUD or AberMUD or WhateverMUD.
TinyMUSH Manual Page 2 Introduction
2 Attribute Lists
Attribute lists are what makes MUSH go. Simply stated, they are a
place in an object where information can be stored. MUD had attribute
lists of a sort, like the description (@desc) or success message (@succ.)
There are many more attribute lists in MUSH, and they are much more
powerful. Here, they not only store messages, but also commands and
numbers.
The attributes are set in the same method as they are in mud, namely:
@<attribute> <object>=<string>
like:
@desc me = A toad.
2.1 New Attributes
In addition to the traditional DESC, FAIL, OFAIL, SUCC, and OSUCC,
there are many new attributes in MUSH. In this section we'll only introduce
a few new ones, since the others are used for more complex purposes.
There are four new attributes, KILL, OKILL, DROP, and ODROP, which
work exactly like the SUCC and OSUCC attributes. The KILL attribute holds a
message that will be sent to the killer of an object, while OKILL is
displayed to everyone else in the room. DROP holds a message to be sent to
the dropper of an object, while everyone else in a room see the ODROP
message.
--------------------------------
Example: Kill and Okill
--------------------------------
>> My assistant, Mocker... <<
>look me
Mocker(#3506Pc)
You see nothing special.
Last:Mon Jul 23 21:23:03 1990
Carrying:
glass of beer
>@kill me=Ow! Hey! What did I ever do to you?
Set.
>@okill me=has killed me! That Jerk!
Set.
>> Now, from my perspective...<<
Mocker says "Hey Croaker, yer a wimp!"
>kill mocker=100
Ow! Hey! What did I ever do to you?
Mocker has left.
>> From Mocker's... <<
"Hey Croaker, yer a wimp!
You say "Hey Croaker, yer a wimp!"
Croaker has killed me! That Jerk!
Croaker killed you!
Your insurance policy pays 50 pennies.
TinyMUSH Manual Page 3 Attribute Lists
Mocker's room(#3505R)
--------------------------------
There are also two other player attributes which are visible to all,
LAST and SEX. LAST indicates when the player was last logged in. The
player cannot set this attribute, it is set for her by MUSH. SEX usually
indicates whether the player is (virtually) male or female, but since it
(like all attributes) is a string, it can be set to silly things like "No,
thank you."
--------------------------------
Example: player Shiva
--------------------------------
>look shiva
The god of @destruction.
Sex:male
Last:Fri Jul 20 08:05:03 1990
Carrying:
Tan for Shiva
Shiva's *SUNBURN*
>>note the LAST and SEX attributes <<
--------------------------------
2.2 New Flags
Several new flags have also been added, and old ones changed. Below
is a brief list of them and their purposes. The commands that are effected
by them will explain them in full. The letter that symbolizes the flag
(which is usually displayed after the object's number when you look at it)
appears after the flag's name in parenthesis.
Abode (A) Allows a player to set their home in a room, and also
allows them to teleport to it as well.
Chown_ok (C) Indicates that the ownership of the object can be
changed. This allows players to "adopt" an object and
make it their own. See the command chown for more.
Dark (D) If dark is set on an exit, the exit's name will not be
displayed in the "obvious exits" list of the room. This
can also be set on objects to keep them out of sight and
on rooms to make all of its contents invisible.
Destroy_ok (d) when set on an object, allows anyone to use the @destroy
command on it to eliminate it. Particularly useful for
such things as notes and such. To destroy an object with
destroy_ok set, you must be carrying it (this prevents
random people destroying an object meant for a specific
person, like a note.)
Enter_ok (e) Setting this flag on a player or object allows objects
that don't belong to them to be given to them, and allows
objects or players to enter them.
Floating (F) (TinyTIM only) The floating flag can be set on a room to
indicate that it is all right for it not to be linked to
TinyMUSH Manual Page 4 Attribute Lists
anything. Usually, MUSH will complain to you every ten
minutes or so if you have a disconnected room. If this
flag is set on a room, then you will not be nagged about
that room not being connected to anything. Do not use
this flag unless you are one of those who Know What They
Are Doing.
Going (G) This flag is set on a room that is about to be destroyed.
It can be reset to save the room from destruction.
Key (K) When set, this flag prevents puppets from picking up an
object. Also, an object with the key flag set will go
home if the player carrying it @teleports someplace.
Puppet (p) When set on an object, the object beings to relay
everything it hears to its owner. See the section on
puppets for more.
TinyMUSH Manual Page 5 Attribute Lists
3 General MUSH commands
Almost all the commands in TinyMUD remain in MUSH. However, MUSH has
many improvements in commands over MUD, both in modifications of old
commands and totally new commands.
3.1 Commands not supported
rob
The rob command is not in MUSH anymore. This is part of the "kinder
and gentler" MUD campaign. You'll just have to kill them instead.
3.2 Changes to old commands
Several commands have been modified from the old MUD form.
@dig
Dig has been modified so a direction can be specified when digging a
room. This means that a room can be dug, and exit opened and linked to the
new room with one command. This extended syntax is:
@dig <room name> = <direction>
where direction is the direction (or directions) to open in the current
room and attach to the new room. Note, a return exit is not created
linking back to the current room, so if such an exit is desired it has to
be made manually.
--------------------------------
Example: Digging, opening, and linking
--------------------------------
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
rhombus west east north aus
>@dig Test Room=test;t;testing
Test Room created with room number 5662.
Opened.
Trying to link...
Linked.
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
test rhombus west east north aus
>>Test now shows up in the list of exits. <<
>test
Test Room(#5662R)
--------------------------------
TinyMUSH Manual Page 6 General Commands
Related to the @dig command is a feature in MUSH which warns you of
unlinked rooms. This prevents the problem of creating a room and then
"losing" it (by way of forgetting the object number.) The database is
checked every ten minutes for unlinked rooms (as well as rooms to be
@destroyed) and will notify the owner of each unlinked room found with a
message indicating the object number of the rogue room. It is possible
that you could create a room and be almost ready to link to it when MUSH
complains about you having an unlinked room. Don't worry, it just means
that the database was checked for unlinked rooms between the time you
created the room and the time you took to link to it. This message can be
eliminated on TinyTIM by setting the floating flag on the room.
--------------------------------
Example: Detached room warning
--------------------------------
>@dig detached room
>> several minutes later... <<
You own a disconnected room, detached room(#5595)
--------------------------------
Examine:
The examine command now will tell you who the owner of an object is if
you do not own it. If you own an object, examine works as before.
--------------------------------
Example: examine objects for owner.
--------------------------------
>e superbear
SuperBear is owned by BearMan
>e bearman
BearMan is owned by BearMan
--------------------------------
@force
The force command can be used by players to manipulate their objects
(before only the wizard could do this.) A player's objects may also force
each other. For more on this command, see the section on puppets.
Give:
You can now give objects to other players. The Syntax for this is:
give <player> = <object>
The receiving player/object will see:
<player> gave you <object>
The player must have their enter_ok flag set for objects that do not
belong to them to be given to them.
--------------------------------
Example: giving objects
--------------------------------
TinyMUSH Manual Page 7 General Commands
>@create Common cold
Created.
>give coyote=common cold
Given.
>> And Coyote gives it back... <<
Coyote gave you Common cold.
--------------------------------
Kill
Two changes have been made in the kill command. First, it is possible
to kill objects. Killing an object has exactly the same effect as killing
a player: the object goes home, it gets half of what it cost you to kill
it. Killing an object will stop all of its actions (see the @halt command.)
Second, you cannot kill an object in a room controlled by its owner. This
is so objects in puzzles and such cannot be killed. Also, you cannot kill a
player in rooms they own.
@link
Ok kids, *this* time around, linking an exit to an object will bring
you into that object's inventory (i.e., it will teleport you into that
object.) Go and do this quickly before it gets changed *again* (that's a
joke, ok?) See the section on vehicles and such if you're really up to it.
Objects can now be linked to their owners so that when the object goes
home it will end up in the player's inventory. This eliminates the clumsy
use of @tel for the same purpose.
--------------------------------
Example: linking to objects
--------------------------------
>>Bleedin' example deleted since it was wrong! wrong! wrong!<<
--------------------------------
@lock
It is possible to lock objects/exits against attributes (see the
section attributes and flags) such as the sex of the player. The command
syntax is:
@lock <object/exit> = <attribute>:<setting>
<setting> is a text string to match. Text matching uses the standard
wildcards "*" and "?". For example, "s?x" will match "sex", "sax", "sox",
or any other three letter word starting with s and ending with x. "*s" will
match any word ending in s, and "*s*" will match any word with at least one
s in it. The section on Listen and Ahear will deal with these extensively.
--------------------------------
Example: locking an exit to attributes
--------------------------------
>> Create a Ladies Room <<
>@dig Ladies room=Ladies
TinyMUSH Manual Page 8 General Commands
Ladies room created with room number 5671.
Opened.
Trying to link...
Linked.
>@lock ladies=sex:f*
Locked.
>>females (or any sex beginning with f) only! <<
>@fail ladies=Hey you pervert!
>> Try to go in <<
>ladies
Hey you pervert!
>> Try a quick sex change <<
>@sex me=female
Set.
>ladies
Ladies room(#5671R)
>> Now I can go in <<
--------------------------------
Look
A minor change in the output of the look command. When looking around
a room, all non-dark exits will be listed in a "obvious exits" list. This
does not mean that these are the only exits that exist, just the obvious
ones that the builder wants you to know about. This is handy when walking
around the creations of lazy builders who don't explain which way you can
go. Exits can be concealed if their dark flag is set (see the section on
flags.)
--------------------------------
Example: available exits
--------------------------------
look
The room of junk and killing.(#304RSL)
This large, darkened room has no obvious exits. A crowd relaxes on pillows
in front of a giant screen TV, and there in a fully stocked fridge and a
bar. By the TV is a black box with buttons marked with the numbers 2 thru
13 and the letter U.
You can't help but notice a chair glued sideways to the wall by its feet.
Contents:
thingy
Exit machine: if you would like to build off of here look at me
Obvious exits:
woodlock Tachea motel Kahless-exit W.AXL_ROSE-exit Jeho's_joint
Khamul-exit Izumi-exit mocker's MIIC Iriguchi Tourm's closet id-exit
double Phoenix-exit gonzo-exit test Tage-exit Catty's Desmense
Fosgate-exit bar field Drawbridge Kade Hot tub The-GoreBot-Control-
Booth(type'GOREBOT') Dayffd's Place Tardis mushland Jin-exit Thanatos-
exit Entropy-exit 20? Space_Ark JFL Whizzy-exit Trashlandia Markus'
Banker-exit Markus' Banker-exit mars Hobbes Dream-specter-exit Drawing
Room old out
>>A few exits... <<
--------------------------------
TinyMUSH Manual Page 9 General Commands
Say (and ":")
MUSH treats some characters specially, for use in functions and
parameter substitution. The percent sign and square brackets (%, [, and ])
are replaced by function or parameter values when printed out. This means
that if you try and use the %, [, or ] characters you will get strange
results. In order to say something containing any of these characters you
should put a backslash character before them.
--------------------------------
Example: using %,[, and ] with say
--------------------------------
>"MUSH is 100% better than MUD
You say "MUSH is 100 better than MUD"
>"MUSH is 100\% better than MUD
You say "MUSH is 100% better than MUD"
>:This [thing] is in brackets
Croaker This thing is in brackets"
>:This \[thing\] is in brackets
Croaker This [thing] is in brackets"
--------------------------------
There are actually a number of ways to get these characters. The "%"
will work in the place of the "\" character, so "%%", "%[" and "%]" will
work. However, the setup of functions(which utilize the square brackets)
has been radically changed, so this entire section may be irrelevant.
There is also a different form of the pose command available on
TinyTIM. The ";" command acts just like the regular pose ":", but
eliminates the usual space after the name of the player issuing the
command. This is useful for possessive statements (and we know what a
greedy lot MUSHers are, don't we?)
--------------------------------
@tel
There have been a number of changes with teleport. First, you can now
teleport yourself or any object you own to any room you own from anywhere
(before, only a wizard could @tel players.) Also, you can teleport into
any room that has the abode flag set (see the section on flags and
attributes for more.) This allows for speedy travel from place to place in
a MUSH, but creates certain problems for puzzle builders (see the appendix
on building considerations.) The syntax of the command is:
@tel <object> = <destination room number>
--------------------------------
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
west east north aus
>@tel me=#941
TinyMUSH Manual Page 10 General Commands
Drawing Room(#941R)
This is a comfortable room, with windows looking out into the garden to the
east, and out onto the front lawn to the north. To the south is a doorway
that doesn't seem to lead anywhere. There is a sign reading "rec room" over
it. There are numerous chairs and couches lying about, what seems to be a
bar in the west wall (next to a door.) A grandfather clock ticks sedatly in
one corner.
Contents:
A survalence camera(#863)
The stereo system(#2276)
Obvious exits:
bar rec west
--------------------------------
It is also possible to "push" a player out an exit using the @tel
command, if you own the room and the exit. The syntax of this is:
@tel <player> = <exit>
This, of course, is just the thing for those unwanted house guests...
--------------------------------
Example: "pushing" things out exits
--------------------------------
>look
Croaker's Robot Lab(#3061RHA)
The robot testing grounds.
Contents:
Cinema
Obvious exits:
Pit o' Death west east north aus
>>Since this is my place, I can push Cinema (which I don't own) <<
>>out through an exit <<
>@tel cinema=pit o' death
Cinema has left.
>look
Croaker's Robot Lab(#3061RHA)
The robot testing grounds.
Obvious exits:
Pit o' Death west east north aus
>> Let's go see where Cinema ended up... <<
>pit o' death
The Town Rhombus
You are in a pleasant town square, which is shaded by many old red
oaks.Pebbled paths lead off in all directions, and the grass is healthy and
well cared for. Set between the trees are various old statues, mostly made
. . .
Contents:
Cinema
Onex
exit magnet(#5636L)
Obvious exits:
Southwest Bulletin Southeast South West East North
--------------------------------
TinyMUSH Manual Page 11 General Commands
3.3 New Commands
This section deals with the new commands of general interest. Those
that are more suited to building machines will be detailed later.
@clone:
Clone will make an exact duplicate of an object you own and place it
in the room where you are. This is handy, since it saves on having to
laboriously copy an object's description and other attributes. Cloning an
object costs the same as creating the object the old fashioned way (i.e.
usually 10 pennies)
--------------------------------
Example: cloning objects
--------------------------------
>@create generic object
Created.
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
west east north aus
>@clone generic object
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Contents:
generic object(#5635)
Obvious exits:
west east north aus
>> a copy of the object has appeared <<
>i
You are carrying:
generic object(#5622)
Incomplete TinyMUSH manual(#2235)
TinyMUSH crash helmet(#1759)
--------------------------------
You can @clone objects even if they are not in your possession or in the
same room as you. In a sense, you can create a "platonic pattern" and then
knock off as many copies as you want, while keeping the original in an out
of the way place. This principle can be used in creating vending machines.
Examples of vending machines will be given in the section on basic
machines.
--------------------------------
Example: cloning by number
--------------------------------
>> The generic object is located in a room far away...<<
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
TinyMUSH Manual Page 12 General Commands
west east north aus
>i
You are carrying:
Incomplete TinyMUSH manual(#2235)
TinyMUSH crash helmet(#1759)
You have 1864113 Gold pieces.
>> Nothing up my sleeve... <<
>@clone #5622
look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Contents:
generic object(#5635)
Obvious exits:
west east north aus
>> and there is a copy of it... <<
--------------------------------
@destroy:
One of the first commands in MUSH. This command will allow a player
to destroy an object that belongs to them or has the destroy_ok flag set.
The player is refunded the cost of creating the object, and the object's
number is released for future use (therefore you really can't tell the
relative age of an object by it's object number.) All objects (rooms,
exits, etc) can be destroyed. This form of destroy command does not force
all of the objects in the database to have their numbers reassigned like
MUF.
--------------------------------
Example: destroy an object
--------------------------------
>@create generic object
Created.
>@destroy generic object
You get your 10 penny deposit back for generic object.
Destroyed.
--------------------------------
--------------------------------
Example: set the destroy_ok
--------------------------------
>@create generic object
Created.
>@set generic = destroy_ok
Flag set.
>look generic object
generic object(#5635d)
>>now it can be destroyed, unfortunately, no one else was around...<<
--------------------------------
TinyMUSH Manual Page 13 General Commands
Destroying a room is a little different. Room removal takes a little
while (up to ten minutes) do to the database design, as well as to allow
for owners to destroy the rooms they are in. When a @destroy command is
given for a room, the command sets the target room's going flag. The owner
can reset this flag in order to save the room. Rooms to be destroyed must
have two or less exits leading out of them. All exits leading out of a
destroyed room are also destroyed. Exits leading into the room are also
eliminated.
--------------------------------
Example: room destruction
--------------------------------
>@destroy here
The room shakes and begins to crumble.
You will be rewarded shortly for Test Room.
>out
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
test rhombus west east north aus
>test
Test Room(#5662RG)
Obvious exits:
out
>out
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
test rhombus west east north aus
>> time passes... <<
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
rhombus west east north aus
>>notice that test has disappeared<<
--------------------------------
--------------------------------
Example: canceling destruction
--------------------------------
>@dig test=test
test created with room number 5772.
Opened.
Trying to link...
Linked.
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Obvious exits:
test rhombus west east north aus
TinyMUSH Manual Page 14 General Commands
>test
test(#5772R)
>@destroy here
The room shakes and begins to crumble.
You will be rewarded shortly for test.
>look
test(#5772RG)
>@set here=!going
Your room has been spared from destruction.
--------------------------------
Since players are objects, they can be destroyed. You cannot however
destroy yourself. Of course wizards can do anything, and if properly
annoyed...
--------------------------------
Example: the Wizard's wrath
--------------------------------
tinyjerk has arrived.
tinyjerk stomps on the Wizard's foot!
The evil wizard wizard just destroyed tinyjerk.
tinyjerk has disconnected.
--------------------------------
and you thought @toading was bad...
@edit:
The edit command allows you modify an attribute without having to
totally rewrite it. This aids in the creation of machines, which quite
often have complex attributes which would be a major pain to re-enter. It
also means that you fix spelling errors in @descs with ease (so now there's
no excuse for misspelling!)
The syntax is:
@edit <object>/<attribute>=<text to be replaced>,<text to replace with>
--------------------------------
Example: using @edit to modify an attribute
--------------------------------
>>Let's make a minor change to my @desc <<
>look me
Croaker(#346Pc)
Pretty normal looking for a 5' 10" bipedal toad wearing a tweed jacket and
a deerstalker cap. His pockets bulge with various tools: virtual reality
inverters, aether clamps, foobar manipulators, and an Xacto knife. He can
usually be found alternatly staring off into the distance mumbling to
himself and scribbling notes on a yellow pad. There is an "amphibious and
proud!" button on one lapel of his jacket, and a "warts are a myth!" button
on the other.
TinyMUSH Manual Page 15 General Commands
>@edit me/desc=Xacto,Xacto(tm)
set.
>> So I don't sued by the Xacto knife company... <<
>look me
Croaker(#346Pc)
Pretty normal looking for a 5' 10" bipedal toad wearing a tweed jacket and
a deerstalker cap. His pockets bulge with various tools: virtual reality
inverters, aether clamps, foobar manipulators, and an Xacto(tm) knife. He
can usually be found alternatly staring off into the distance mumbling to
himself and scribbling notes on a yellow pad. There is an "amphibious and
proud!" button on one lapel of his jacket, and a "warts are a myth!" button
on the other.
--------------------------------
TinyMUSH Manual Page 16 General Commands
4 Puppets
The use of puppets is the easiest of the advanced features to use in
MUSH, and also one of the most amusing. Two simple capabilities constitute
the puppet: the @force command, and the puppet flag.
4.1 The @force command and objects
In TinyMUD, only a wizard could use force, and then it could only be
used on other players. The @force command forces an object or player to
perform a command exactly as if they had typed it in. You can make objects
walk, talk, @create objects and even @force other objects you own.
The usual syntax of the @force command is:
@force <object> = <command>
<object> can be a name of an object you own, as long as you are in the same
rooms as it is. Otherwise, you must use the object number to control it.
Since it is used so often in MUSH, the @force command now has a shorthand
syntax:
<object> <command>
The <object> in this form has the same restriction as the above form of the
command.
--------------------------------
Example: forcing an object
--------------------------------
>@create test puppet
Created.
>drop test
Dropped.
>look test
test puppet(#4306)
You see nothing special.
>@force test=:jumps up and down and waves.
test puppet jumps up and down and waves.
>@force test=@create sub-puppet
look puppet
test puppet(#4306)
You see nothing special.
Carrying:
sub-puppet(#4307)
--------------------------------
You can have puppets move about, as well, as long as you remember that
you have to reference them by object number after they have left the room
you are it.
--------------------------------
Example: making a puppet move
--------------------------------
TinyMUSH Manual Page 17 Puppets
>@force test=north
test puppet has left.
>@force test=south
I don't see that here.
Sorry.
You can only force players and things.
>> This is MUSH's way of telling you it cannot find what you <<
>> want to force <<
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Contents:
Obvious exits:
west east north aus
>>remember, test is to the north of us<<
>@force #4306=south
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Contents:
test puppet(#4306)
Obvious exits:
west east north aus
>> and test is back. <<
--------------------------------
Note that TinyMUSH does not announce the arrival of the test object.
This is because the object cannot hear anything; that is, it cannot relay
information or react to anything it hears. Only objects that can hear
things (like private conversations) will be announced when they arrive.
There are two classes of objects that can overhear conversations, and we'll
tackle the simplest form of these next.
4.2 The Puppet Flag and Objects
By setting the puppet flag on an object, the owner enables the object
to relay all it hears back to him or her. What the puppet hears will be
relayed to the owner, with a lead in to the line of text to differentiate
it from the things the player might be hearing normally (or for that
matter, might be hearing from another puppet.) The effects of puppets is
rather surreal at times. It is not too uncommon to come across a room full
of puppets talking to each other, their owners being elsewhere and doing
other things while still joining in on the conversation.
--------------------------------
Example: puppet output
--------------------------------
>@create Croaker's test puppet
Created.
>@lock Croaker's=me
Locked.
>> always a good idea.<<
TinyMUSH Manual Page 18 Puppets
>@set croaker's=puppet
Croaker's test puppet grows ears and can now hear.
>> you will always see this command when the puppet bit is set<<
Flag set.
>drop croaker's
Croaker's test puppet> Dropped.
>> There is the first output we see from the puppet<<
Croaker's test puppet has arrived.
Dropped.
>look croaker's
Croaker's test puppet(#5086p)
You see nothing special.
>>remember the puppet's number...<<
>#5086 s
>> send it to the town square<<
Croaker's test puppet> You go to the town Rhombus.
Croaker's test puppet goes south to the town Rhombus.
Croaker's test puppet has left.
Croaker's test puppet> The Town Rhombus
Croaker's test puppet> You are in a pleasant town square, which is shaded
by many old red oaks. Pebbled paths lead off in all directions, and the
grass is healthy and well cared for. Set between the trees are various old
>> truncated for brevity <<
Croaker's test puppet> Contents:
Croaker's test puppet> Martha
Croaker's test puppet> Gonzo
Croaker's test puppet> Gus
Croaker's test puppet> Desdi
Croaker's test puppet> Tweeni
Croaker's test puppet> White Rabbit
Croaker's test puppet> Alice
Croaker's test puppet> Onex
Croaker's test puppet> Lucas
Croaker's test puppet> Obvious exits:
Croaker's test puppet> Southwest Bulletin Southeast South West East
North
Croaker's test puppet> Gonzo gives desdi a spare hand so she will have 2
hands again
Croaker's test puppet> Desdi giggles.
Croaker's test puppet> Onex snorts "Docs, we don't need no stinking docs!"
Croaker's test puppet> Tweeni goes home.
Croaker's test puppet> Tweeni has left.
Croaker's test puppet> Gonzo looks at onex...you perhaps, but gonzo hasnt
seen this before
Croaker's test puppet> Desdi waves byebye.
Croaker's test puppet> Desdi goes home.
Croaker's test puppet> Desdi has left.
Croaker's test puppet> Gonzo Waves bye to desdi
Croaker's test puppet> Onex croaks "Solong!"
Croaker's test puppet> Gonzo says "this is a very ribbeting subjet, onex"
>#5086 "Be nice, you're being recorded for the documentation...
Croaker's test puppet> You say "Be nice, you're being recorded for the
documentation..."
Croaker's test puppet> Gonzo says "smile, youre on candid camera!"
TinyMUSH Manual Page 19 Puppets
>#5086="candid puppet...
Croaker's test puppet> Huh? (Type "help" for help.)
>> you even get error messages relayed to you<<
Croaker's test puppet> White Rabbit twitches his nose.
>#5086 "candid puppet
Croaker's test puppet> You say "candid puppet"
Croaker's test puppet> White Rabbit twitches his nose.
Croaker's test puppet> Gonzo considers hacking /filedump into his tinytalk
for benefit of all puppets present
>#5086 n
Croaker's test puppet> You walk toward government center
Croaker's test puppet has arrived.
Croaker's test puppet> Government center
--------------------------------
MUSH also prevents objects from impersonating players...
--------------------------------
Example: no impersonating allowed
--------------------------------
>@create Wizard
Created.
>drop Wizard
Dropped.
>look Wizard
Wizard(#5139)
You see nothing special.
>@force Wizard="The Wizard sucks Dodo eggs
You are under arrest for impersonating a player!
>@force Wizard=:tap dances
You are under arrest for impersonating a player!
--------------------------------
4.3 New command: @sweep
Since objects can now hear things, private conversation on MUSH
becomes a little more difficult. Fortunately there is a command to help
out. The @sweep command will tell you all of the possible objects which
can overhear your conversation, such as players (whether logged in or not),
puppets, and some machines (which, as usual, will be covered in another
section.)
After you sweep an area and find it empty (except for those in on the
conversation) will can be sure you are secure. Even dark people and object
will show up on it. Should any object enter the room that can hear, or if
one of the objects in a room already is set up to hear, you will see a
message tipping you off. Only objects that can hear (including players) are
announced by MUSH as they enter a room, and if the owner of an object
enables it to hear, you will get a message to the effect that the object
has grown ears and can hear.
--------------------------------
Example of the @sweep command
TinyMUSH Manual Page 20 Puppets
--------------------------------
>look
Government center
The Government center, to the east is the Temple of Chaos, to the north is
the temple, to the west is the Presidential Palace.
This doesn't seem like your typical goverment center, infact you don't see
any government here at all.
Contents:
SuperBear
Katie
NOTE TO AUSTRALIAN MUSHERS
Sign pointing South west to the science museum
Post office is south east
Sign pointing North east to the Puzzle Paradise.
Obvious exits:
sw se ne west east north south
>@sweep
Croaker is listening.
VAX9000 is listening.
BearMan is listening.
SuperBear is listening.
Katie is listening.
Manticora is listening.
anonymous is listening.
milo is listening.
nessus2 is listening.
Faradon is listening.
radio_man is listening.
Kjarsten is listening.
Microwiz is listening.
--------------------------------
Most of the listening objects in the above were players who were not logged
in. Even so, you can see that the objects SuperBear and Katie (whatever
they might be) are listening.
4.4 Puppets and Puzzles: The Key Flag
Puppets have the potential of allowing cheating in puzzles. There is
little excitement in having a puppet (or even a machine) go through a
puzzle picking up all of the keys and solving the puzzle, or allow a player
to cheat by being in two places at once (effectively) and ruining the
solution. The key flag can prevent this. If an object has its key flag
set, a puppet cannot pick it up, while real players still can. In addition,
any object with the key flag set automatically goes home should the person
carrying it @teleport away. This prevents people from stealing the keys
and rendering the puzzle unsolvable.
--------------------------------
Example: key flag
--------------------------------
>@create object
Created.
TinyMUSH Manual Page 21 Puppets
>@set object=key
Flag set.
>drop object
Dropped.
>@create puppet
Created.
>@set puppet=puppet
puppet grows ears and can now hear.
Flag set.
>drop puppet
puppet> Dropped.
puppet has arrived.
Dropped.
>@force puppet=get object
puppet> You can't pick that up.
>get object
Taken.
--------------------------------
TinyMUSH Manual Page 22 Puppets
5 Action Lists
Action lists are what make machines in MUSH possible. Simply put, an
action list is a string of commands stored in an attribute of an object
which are executed after certain conditions are met. These commands run as
if they were typed in by the object. Action lists are the "programs" that
objects in MUSH run. Each attribute can be considered as, say, a line of a
BASIC program. Each attribute can accomplish many things, including
triggering itself again, or even rewriting itself or another attribute.
Each action list has to be triggered in some way. The most common
action lists are associated with attributes that you are familiar with from
MUD. These are ASUCC, AFAIL, ADROP, and AKILL.
5.1 Common action lists: ASUCC, AFAIL, ADROP, and AKILL
In MUD, when an object is successfully "used" (that is, picked up) two
things happen. The message stored in the SUCC attribute is sent to the
player who picked the object up, and the message stored in OSUCC is
displayed to all other players in the room. In MUSH, a third thing occurs,
the commands stored in the ASUCC attribute (if there are any) are executed.
As you can probably guess, the commands in AFAIL will be run when
someone fails to use an object (tries to pick it up but can't), AKILL will
be run if an object is killed, and ADROP will be run if an object is
dropped.
The actual structure of an action list is simply a string of commands
as you would enter them to perform the desired operation. The commands are
separated by a semicolon, ";", and for the most part are executed in the
order they were entered (i.e. left to right.) Therefore, an attribute is
"programmed" thus:
@<attribute> <object> = command1;command2;command3...
There is no need for an "end" statement, execution of the action list stops
when the end of the list is reached. Command1 will be executed, and then
command2 and so forth. You can clear an attribute by setting it to
nothing.
--------------------------------
Example: Adrop
--------------------------------
>@create superball
Created.
>@drop superball=You bounce the superball on the floor.
Set.
>@adrop superball=n;s;n;s;n;s;:stops bouncing and lands at your feet.
Set.
>>when dropped, the superball will north and then south several times <<
>>print out the message that it has stopped, and then terminate <<
>>execution <<
>drop superball
You bounce the superball on the floor.
superball goes to the north end of the lab.
superball has left.
TinyMUSH Manual Page 23 Action Lists
superball goes to the north end of the lab.
superball has left.
superball goes to the north end of the lab.
superball has left.
superball stops bouncing and lands at your feet.
>>remember, we don't see the superball come back since it <<
>>cannot hear <<
--------------------------------
--------------------------------
Example: Afail
--------------------------------
>>have the ball print out a message and then go north<<
>@afail superball=:rolls away from %N;n
Set.
>>make sure I'll fail when I try to pick it up <<
>@lock superball=me&!me
Locked.
>look
Croaker's Robot Lab(#3061R)
The robot testing grounds.
Contents:
superball(#5088)
simple ahear machine(#4284)
Obvious exits:
west east north aus
>get superball
You can't pick that up.
superball rolls away from Croaker
superball goes to the north end of the lab.
superball has left.
--------------------------------
--------------------------------
Example: Asucc
--------------------------------
>> Set the ball so I can get it again <<
>@unlock superball
Unlocked.
>> have the ball page me when it is taken (a good <<
>> burglar alarm)<<
>@asucc superball=page croaker=someone picked me up!
Set.
>get superball
Taken.
You sense that superball is looking for you in Croaker
someone picked me up!
--------------------------------
--------------------------------
Example: Akill
TinyMUSH Manual Page 24 Action Lists
--------------------------------
>>Back in section #2, I killed Mocker. He's back for more<<
>>From Mocker's perspective <<
>> Mocker goes back to the robot lab and... <<
>>sets his akill to send him back to the robot lab from his <<
>>home to kill me back<<
>@akill me=s;robot lab;kill croaker=100
Set.
"Go ahead, make my day!
You say "Go ahead, make my day!"
>> My perspective, again... <<
Mocker says "Go ahead, make my day!"
kill mocker=100
Ow! Hey! What did I ever do to you?
Mocker has left.
Mocker has arrived.
>> Mocker's akill takes over and brings him back almost immediately<<
>> Mocker's perspective, again... <<
Croaker has killed me! That Jerk!
Croaker killed you!
Your insurance policy pays 50 pennies.
Mocker's room(#3505R)
Obvious exits:
s
>>Now Mocker's akill acts as autopilot and moves him to the <<
>>robot lab<<
Croaker's Workshop
This room is entirely white, with a black grid on the walls, ceileing,and
floor. It gives you the impression of being in a a room made out of graph
paper. The only furniture is a few work benches crowded with various
dimensional stabilizers, reality wrenches, foobar manipulators. There are
several doors leading in random directions, some of them seem to be leaning
against a wall.
Obvious exits:
Robot Lab North port3 port2 port1 east
Croaker's Robot Lab
The robot testing grounds.
Contents:
Croaker
Obvious exits:
west east north aus
You found a penny!
Sorry.
>> Revenge is not his... <<
--------------------------------
You'll notice that Mocker could not kill me in a room that I control. Had
it been someone other player's room, he could have gone through with his
murder plot.
AKILL only takes effect after you are sent home, so you have to go
back to where you were if you want an eye for an eye.
TinyMUSH Manual Page 25 Action Lists
5.2 Command Grouping: using the {}
Suppose you want to have an object reprogram itself, and then continue
with some operation. The problem you run in to is how to differentiate
between the commands you want to store in another attribute and the
commands you want this attribute to execute. For example:
@adrop ball="now you can't get me!; @afail me=:rolls away; north; @lock
me=me&!me
The problem is that the ADROP should store the north, not execute it (as it
will in its present form.)
To solve this problem, MUSH allows you to defer the execution of some
statements by enclosing them in braces (almost universally known as
"squiggly brackets.") All commands in the braces are skipped, and if an
attribute is set to the contents of a pair of braces the braces will be
removed and the commands in them will be stored in the attribute.
Our above example would become:
@adrop ball="now you can't get me!;@afail me={:rolls away;north};@lock
me=me&!me
After dropping it, the ball's AFAIL will be set to the contents of the
braces.
--------------------------------
Example: deferring commands
--------------------------------
>@create test object
Created.
>> have the object rewrite its ADROP after being dropped <<
>@adrop test object=@adrop me={:goes boom!;@destroy me};"If you drop me
again, I'll explode!
Set.
>drop test object
Dropped.
test object says "If you drop me again, I'll explode!"
>look test object
test object(#5666)
You see nothing special.
Adrop::goes boom!;@destroy me
>get test object
Taken.
>drop test object
Dropped.
test object goes boom!
You get your 10 penny deposit back for test object.
--------------------------------
TinyMUSH Manual Page 26 Action Lists
5.3 Cost of Running a machine
Like most things in the real world, machines in MUSH cost money to
run. It costs 1/64 of a penny for each command a robot executes in
addition to any costs those commands normally has (i.e. kill or @create.)
The reason for this cost is an attempt to keep machines from slowing the
system down with unnecessary commands. A machine that sits in a room and
says "zootlewurtle" to itself will slowly use up your supply of money, and
a machine that repeatedly creates or clones objects will burn up your money
faster, and a machine that kills itself repeatedly will drain your penny
supply in no time. You should therefore be careful of leaving a runaway
machine. Machines that sit around and wait for certain things to happen
(like being dropped) will not use any pennies while sitting idle, and are
thus economical.
TinyMUSH Manual Page 27 Action Lists
6 Other triggers and attributes: LISTEN COST and CHARGES
This section will discuss two new triggers and the attributes they
affect. LISTEN will allow machines to react to what they hear, and COST
will allow them to react to being given a certain amount of pennies. Also
introduced is a way to limit the number of times an object can be used by
using the CHARGES attribute.
6.1 LISTEN and AHEAR
By far one of the most flexible set of attributes for creating
machines is the LISTEN and AHEAR pair. These attributes allow the machine
to respond to things they hear, such as what players or other machines say
or do. This allows a machine to respond to a spoken command, or wait for a
message like "blank has arrived."
The LISTEN attribute is set to a string that the machine is to respond
to. Almost always this string includes wildcard characters to allow the
machine to be triggered by a single key word or phrase in a lengthy string.
Wildcards should be familiar to anyone using DOS or Unix systems. The
wildcard "*" matches any number of characters in a string. The string "s*"
will match any string beginning with the letter s. The string "*hello*"
matches any string where the word "hello" appears, like "croaker says
'hello there!'."
The wildcard "?" will match a single character. The string "*s?t*"
matches the string "sit", "he sat", or "his time" (a single space matching
as the "?" in this case.) Note that this is very different from "*s*t*"
which will match a string like "some time."
LISTEN is set as any other attribute, namely:
@listen <object> = <string>
such as:
@listen foo = *kill *
Which will match any occurrence of the word "kill" which is followed by a
space (i.e., it would not match the string "shiva killed foo.")
When the string in the LISTEN attribute matches a string the object
hears, the action list in the AHEAR attribute is run similar to the way
ASUCC is run if an object is picked up. For example:
@ahear foo = "now now, let's not have any violence"
would have the machine foo respond to a string like "let's kill the
wizard!" with a calming message.
--------------------------------
Example: Using LISTEN and AHEAR
--------------------------------
>>Create a simple machine to run west then east upon <<
>>hearing the phrase "trigger phrase" <<
>@create simple ahear machine
Created.
>@listen simple = *phrase*
Set.
TinyMUSH Manual Page 28 LISTEN, COST & CHARGES
>@ahear simple=west;east
Set.
>look simple
simple ahear machine(#4284)
You see nothing special.
Listen:*phrase*
Ahear:west;east
>"trigger phrase!
You say "trigger phrase!"
simple ahear machine runs like the wind into New Main Street to the west.
simple ahear machine has left.
simple ahear machine has arrived.
>>now a simple hear-respond machine...<<
>@ahear simple=say I heard the word!
Set.
>look simple
simple ahear machine(#4284)
You see nothing special.
Ahear:say I heard the word!
Listen:*word*
>"Now I say the word...
You say "Now I say the word..."
simple ahear machine says "I heard the word!"
--------------------------------
You'll notice that in the last part of that example that the machine
did not go into an infinite feedback loop event though its output contains
the phrase to trigger it. This is because the AHEAR action list is only
run if a string that was not generated by the machine itself matches the
string in the LISTEN attribute. Usually, this is what you want, since
otherwise it is very easy to get into a feedback loop where the machine
constantly re-triggers itself.
There are two more attributes related to LISTEN: AMHEAR and AAHEAR for
those occasions that you want a machine to be able to trigger itself by
saying something. AMHEAR will only respond to strings generated by the
machine (i.e. the exact opposite of ahear.) AAHEAR will react to all
strings, whether generated by itself of something else. These attributes
can be used to do things like have the AKILL or ADROP trigger further
actions by whispering to itself. There are better ways to do this, however
(see the section on extra attributes and the trigger command.)
--------------------------------
Example: AMHEAR and AAHEAR
--------------------------------
>>reset the ahear so it won't interfere<<
>@ahear simple=
Set.
>@amhear simple=say I heard the word!
Set.
>"word
TinyMUSH Manual Page 29 LISTEN, COST & CHARGES
You say "word"
>>nothing happens, since the object didn't generate <<
>>it itself, but of we force it to say "word"...<<
>@force #4284="word
simple ahear machine says "word"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
. . .
>>and we get into an infinite feedback loop<<
>>the only thing to do is to kill, @halt, or <<
>>@destroy the object <<
. . .
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
>@halt
>>now reset AMHEAR and do the same thing for AAHEAR<<
>@amhear simple =
Set.
>@aahear simple = say I heard the word!
Set.
>"word
You say "word"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
simple ahear machine says "I heard the word!"
>kill simple = 100
simple ahear machine says "I heard the word!"
You killed simple ahear machine!
>>Notice both I and it could trigger it off...<<
--------------------------------
6.2 Runaway objects and the @halt command
At this point, it would be a very Good Thing(tm) to explain how to
stop one of the aforementioned runaway machines. As can be seen above, one
can either kill a runaway, or use the @halt command on it. There are
drawbacks to both methods, however. Killing an object will stop what it's
currently doing, but will trigger its AKILL attribute. Normally this is
fine, but if the AKILL was what sent it into an infinite loop in the first
place, killing it will be of no avail. The @halt command, which is simply
given without any parameters, will halt all of the objects you own. This
means that not only will the malfunctioning machine be stopped, but all of
the machines you may have doing their thing will also stop their
operations. It does not affect any machines "waiting around" with LISTEN
attributes and such, however, just those that are actually doing something
at the moment.
To digress for a moment, it may be helpful to explain what happens
when an object triggers itself. Suppose half way through its AKILL action
TinyMUSH Manual Page 30 LISTEN, COST & CHARGES
list an object whispers a phrase to itself which triggers its AMHEAR action
list. The AMHEAR action list is not run immediately, but is placed into a
queue of action lists to be run later. Only after the AKILL has finished
will the AMHEAR action list be allowed to run (assuming that there was no
other action lists queued before the AMHEAR.)
Either killing or @halting an object will remove all the action lists
in the object's queue and terminate the currently running action list.
Killing the object stops just that object (but, of course, will trigger its
AKILL, if any), while @halt will stop all the objects you own.
Note that there are several other ways to stop out of control objects.
You can @destroy them, or you can run out of money.
--------------------------------
Example: runaway object
--------------------------------
>> Note: don't be an idiot. Never do this on purpose...<<
>@create loop killer
Created.
>@akill loop killer="another iteration!;kill me=100
Set.
>drop loop killer
Dropped.
>@link loop killer=here
Home set.
>kill loop killer=100
Halted.
You killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
loop killer says "another iteration!"
Halted.
loop killer killed loop killer!
>@halt
loop killer says "another iteration!"
Halted.
--------------------------------
TinyMUSH Manual Page 31 LISTEN, COST & CHARGES
Note that "Halted." is printed out every time loop kills itself. This is
because it is being halted by killing itself. However, the AKILL action
list gets run after the object is killed and is thus restarted. The @halt
command or waiting for me to go broke were the only two alternatives since
killing the thing would only set it off again. I would have eventually run
out of money, since I lost 50 pennies every time it killed itself (killing
itself cost 100, and it got 50 back.) Overall, running that object cost me
about 500 pennies.
6.3 Wildcards and Variables
When a string is matched by the string in the LISTEN attribute, the
characters matched by the wildcards are not simply discarded. The sub-
strings matched by the wildcards are placed in nine variables, numbered 0
to 9, and can be retrieved by using the function v(). Functions will be
discussed later, but for now it is enough to know that putting [v(0)] in a
string places the substring matched by the first wildcard in the LISTEN
attribute into the action list. The substring matched by the second
wildcard can be had by putting a [v(1)] in the AHEAR, and so forth up to
[v(9)].
The normal variables in MUD such as %N, which holds the name of the
object responsible for triggering the action, can be had in this manner as
well, by placing [v(n)] in the string. In fact, [v(n)] is set up for every
trigger, not just LISTEN, and so could be used in an ASUCC, OSUCC, SUCC, or
similar attribute.
When used in an attribute, the variables 0-9 and N will be replaced
with the text they store. This allows the machine to respond to what,
specifically, was said or done to set it off, and to know who was
responsible for triggering it. The section on functions will give a
clearer explanation as to what exactly v() and the [] mean, and how to use
them precisely.
--------------------------------
Example: Using variables
--------------------------------
>look simple
simple ahear machine(#4284)
You see nothing special.
Aahear:say I heard the word!
Listen:*word*
>@aahear simple=
Set.
>@ahear simple=say After word, I heard: %1
Set.
>"Now after word it will print this
You say "Now after word it will print this"
simple ahear machine says "After word, I heard: it will print this""
-------------------------------------
Notice in the last example there was an extra quote. The quote was
included since it was part of the string that was matched by the wildcard.
Many times you want to eliminate this trailing quote. The next example
demonstrates how to do this.
TinyMUSH Manual Page 32 LISTEN, COST & CHARGES
--------------------------------
Example: eliminating the trailing quote
--------------------------------
>@ahear simple="I heard: %1
Set.
>@listen simple=*this*"
Set.
>"notice that after this there is no extra quote
You say "notice that after this there is no extra quote"
simple ahear machine says "I heard: there is no extra quote"
>>and the extra quote is gone <<
--------------------------------
The wildcard ability is very powerful. You can specify a input format
and have the LISTEN attribute parse a line that matches. For example, you
could have the machine accept three parameters which are separated by, say,
commas or colons.
--------------------------------
Example: using LISTEN to parse a string
--------------------------------
>@listen simple=*hear*,*,*
Set.
>@ahear simple=say var0 = %0; say var1 = %1; say var2 = %2; say var3 = %3
Set.
>"It will hear this, that, and the other thing.
You say "It will hear this, that, and the other thing."
simple ahear machine says "var0 = Croaker says "It will"
simple ahear machine says "var1 = this"
simple ahear machine says "var2 = that"
simple ahear machine says "var3 = and the other thing.""
--------------------------------
Here's an application of the AHEAR and LISTEN attributes. I was curious to
see how many people (if any) had ventured through my Drawing Room (which is
directly off the Room of Junk and Killing.) The object in this example
does this. It takes a "photo" of the person who walks through the room.
Before making the photo, any old photo of them is destroyed so that the
camera won't have duplicate copies of each person. As you can see, it
works, and a few people have actually stumbled into my place.
--------------------------------
Example Object: surveillance camera
--------------------------------
>look a survalence
A survalence camera(#863)
This is just an ordinary camera, but it looks a little out of place here.
Feel someone's watching you?
Ahear:@destroy picture of %0;@create picture of %0
Listen:*has arrived*
Carrying:
TinyMUSH Manual Page 33 LISTEN, COST & CHARGES
picture of Croaker(#4487)
picture of Butler(#7495)
picture of Sugar(#6090)
picture of Number_Ten_Ox(#5279)
picture of Khamul(#4782)
picture of spooz(#5702)
picture of Mocker(#4757)
picture of(#4485)
--------------------------------
6.4 COST and APAY
The COST and APAY attributes work exactly like LISTEN and AHEAR,
except that COST is a number of pennies an object has to be given before it
will trigger APAY. This allows vending machines that can charge for the
cost of the objects they make (or even be able to make a profit if you set
the COST higher than the number of pennies needed to run the machine.)
The COST attribute has to be set to the number of pennies that the
object needs to be given for it to trigger APAY. APAY contains the action
list that will be run when the machine is given the amount of pennies
specified in COST. Attempting to give the machine less than the COST
amount will garner the player a snide little error message (and no pennies
will be given to the object.) Any excess over the COST amount will be
returned to the player as change. This is automatic, so you don't have to
worry about programming your machine to handle these situations.
COST also has two other attributes associated with it: PAY and OPAY.
These work like SUCC and OSUCC, the player giving pennies will see the
message stored in the PAY attribute, and everyone else will see the message
in the OPAY attribute. This allows for more flexibility in creating
success messages.
Note that the commands @clone, give, and the chown_ok and destroy_ok
flags are very useful in creating vending machines.
--------------------------------
Example: COST and APAY
--------------------------------
>@create stuff vendor
Created.
>@cost stuff=10
Set.
>@pay stuff=Thank you for buying some stuff.
Set.
>@apay stuff =@create stuff;@set stuff = destroy_ok; @adrop stuff =
{:implodes!;@destroy me};give %N=stuff
Set.
>drop stuff vendor
Dropped.
>give stuff vendor=10
You get 0 in change.
Thank you for buying some stuff.
TinyMUSH Manual Page 34 LISTEN, COST & CHARGES
>stuff vendor gave you stuff.
look stuff
stuff(#5142d)
You see nothing special.
Adrop::implodes!;@destroy me
>drop stuff
Dropped.
stuff implodes!
You get your 10 penny deposit back for stuff.
>give stuff vendor=5
Feeling poor today?
>give stuff vendor=15
You get 5 in change.
Thank you for buying some stuff.
stuff vendor gave you stuff.
--------------------------------
6.5 Restricting the number of uses: CHARGES
The CHARGES and RUNOUT attribute pair allow for an item to be used for
a certain number of times and then perform some action, like going home or
@destroying itself. This can be used to create magic wands that turn to
dust and other such limited use items. The CHARGES attribute is set to the
number of times an object can be successfully used. A "use" in this case
involves triggering any of the AHEAR, ADROP, ASUCC, etc. attributes. Each
time the object is used, the CHARGES attribute is reduced by one. If the
object is used when the CHARGES attribute equals zero, the action list in
the RUNOUT attribute is run. The RUNOUT attribute can do anything, like
@destroy the object, force it to go home, whatever. Remember, though, that
if the object is to be used again it is going to have to have its CHARGES
attribute reset.
--------------------------------
Example: CHARGES and RUNOUT
--------------------------------
>@create foo
Created.
>@charges foo=3
Set.
>@runout foo="Bye now!;@destroy me
Set.
>@asucc foo="I'll run out soon!
Set.
>drop foo
Dropped.
>get foo
Taken.
foo says "I'll run out soon!"
TinyMUSH Manual Page 35 LISTEN, COST & CHARGES
>drop foo
Dropped.
>get foo
Taken.
foo says "I'll run out soon!"
>drop foo
Dropped.
>get foo
Taken.
foo says "I'll run out soon!"
>drop foo
Dropped.
>get foo
Taken.
foo says "Bye now!"
Halted.
You get your 10 penny deposit back for foo.
--------------------------------
TinyMUSH Manual Page 36 LISTEN, COST & CHARGES
7 Commands and Functions for Machines
The commands and functions in this section are generally only helpful
when used in machines. These commands allow the machines to wait a period
of time before performing actions, a decision making command, and functions
to get the date and generate random numbers.
7.1 Delaying Commands with the @wait command
The @wait command can be used to specify a period of time to wait
before executing a command. This allows a machine to break up it's
execution over a period of time, instead of operating as fast as possible.
A machine that wanders from room to room at full tilt is much more annoying
and is a greater drain on the system (not to mention your bank account)
than one that moves once every few minutes.
The syntax if the @wait command is:
@wait <time>=<command>
Where <time> is the number of seconds to postpone the command, and
<command> is the single command to be executed. Note that only a single
command can be postponed by a wait command. Multiple commands must have
multiple wait commands associated with them if an entire block of commands
is to take place in the future.
While @wait does not cost more than the customary 1/64 of a penny to
run, the command does require a "deposit" of 10 pennies which is refunded
after the command is run. This is to prevent a huge number of commands to
postponed and thus slow down the system. The 10 pennies are refunded after
the time elapses and the command runs.
Note that this command (as well as every command in this section)
works with players, if for some reason you wish to put off a command for a
while.
--------------------------------
Example: the @wait command
--------------------------------
>@create time bomb
Created.
>@adrop time bomb=:is set off!;@wait 5= "tick; @wait10="tick; @wait 15=
:blows up in a thunderous roar!;@wait 16=@destroy me
Set.
>drop time bomb
Dropped.
time bomb is set off!
time bomb says "tick"
time bomb says "tick"
time bomb blows up in a thunderous roar!
You get your 10 penny deposit back for time bomb.
--------------------------------
The above example shows the manner in which commands have to be
scheduled one after the other if they are to occur. You do not have to put
events in sequence in an action list (although they tend to make more sense
that way.)
TinyMUSH Manual Page 37 Commands for Machines
--------------------------------
Example: @waits out of sequence
--------------------------------
>@create tik tok
Created.
>@adrop tik tok= @wait 5="A; @wait 1="B; @wait 7="C; @wait 6="D; @wait 1="E
Set.
>drop tik tok
Dropped.
tik tok says "E"
tik tok says "B"
tik tok says "A"
tik tok says "D"
tik tok says "C"
--------------------------------
There are some things you should think about when using the @wait
command. It is a good idea to space the events out in time, not schedule
them to occur all at once. You are not guaranteed what order commands set
to execute at the same time will run. Therefore the closest possible
spacing is one second, which is fine for most applications. It is also
possible to have a @wait command trigger the object in some manner (like
whispering to it, or by using the commands to be covered in the next
section.)
Here is a simple example object using the @wait command.
--------------------------------
Example Object: Paper Airplane
--------------------------------
>look paper airplane
paper airplane(#2273)
You see nothing special.
Odrop:throws a paper airplane
Adrop:@wait 5=:flies off north; @wait 6=north; @wait 15=south; @wait 16=
:circles around some more; @wait 50=:flies east; @wait 51=east; @wait
200=west; @wait 201=:circles and lands at %N's feet.
>drop paper airplane
Dropped.
paper airplane flies off north
paper airplane goes to the north end of the lab.
paper airplane has left.
paper airplane circles around some more
paper airplane flies east
paper airplane has left.
paper airplane circles and lands at Croaker's feet.
--------------------------------
Below is a more complex object, a robot bartender. While the @wait
commands here are not necessary for the machine to operate correctly, it
does break up its output and give a feel that the machine is actually doing
something instead of spitting out lines.
--------------------------------
Example Object: Tendomatic
TinyMUSH Manual Page 38 Commands for Machines
--------------------------------
Tendomatic(#2282)
This robotic pot-bellied bar tender is dilligently waiting to take your
order. Tell it to 'pour <drinkname>', where <drinkname> is the name of any
drink you can think of, and it will serve it to you. The special AI system
has been programmed with every possible drink combination. Share and enjoy!
Owner: Croaker Key: *UNLOCKED* Gold Pieces: 1
Ahear:"Right-o, %N, one %1 coming up!;@wait 3=:pulls a glass out of the
cabinet.;@wait 3=@clone #2284;@wait 4=get glass; @wait 6=:expertly pours %1
into the glass.;@wait 6=@name glass=glass of %1;@wait 8="There you go,
%N,enjoy!;@wait 8=give %n=glass of %1;@wait 20= :starts wiping the bar with
a rag and humming, content with another job well done.
Home: Croaker's Bar(#2021R)
Location: Croaker's Bar(#2021R)
>>And now, its output...<<
>"tendomatic, pour iced tea
You say "tendomatic, pour iced tea"
Tendomatic says "Right-o, Croaker, one iced tea coming up!"
Tendomatic pulls a glass out of the cabinet.
Tendomatic expertly pours iced tea into the glass.
Tendomatic gave you glass of iced tea.
Tendomatic says "There you go, Croaker, enjoy!"
Tendomatic starts wiping the bar with a rag and humming, content with
another job well done.
>>note that these events take place over a span of about 10-15<< >>seconds,
to make things more interesting...]<<
--------------------------------
7.2 Decision making with the @switch command
The @switch is similar to the switch command in the C language. It
allows you to match the contents of a variable or a value returned from a
function (more on that in a moment) against a number of cases. A case is
simply a string (which usually contain wildcards) that is compared to the
switch string. If a match occurs the command that follows the case is
executed. More than one command can be grouped together for execution by
using the braces, {}, to indicate that the commands are to be considered
the body of one of the cases. The format of the switch command is:
@switch <value> = <case1>,<command1>,<case2>,<command2>,...
Example:
@ahear foo = @switch %1=*hello*,"Hi there!,*bye*,"Goodbye!
--------------------------------
Example: The @switch command
--------------------------------
>@create switch test
Created.
>@listen switch test=*test,*"
Set.
TinyMUSH Manual Page 39 Commands for Machines
>@ahear switch test= @switch %1= *hello*,"Goodbye!,
*goodbye*,"Hello!
Set.
>drop switch test
switch test has arrived.
Dropped.
>"hey test, hello!
switch test says "Goodbye!"
>"test, don't say goodbye
You say "test, don't say goodbye"
switch test says "Hello!"
--------------------------------
The method illustrated above answers one of the more often asked questions
on MUSH, "how do I get multiple @ahears on one object?" Simply set the
LISTEN attribute of the object to "*" and put a @switch statement in the
AHEAR attribute with each case testing for the phrases you want to trigger
the object.
It is possible to get a "default case" with the switch command, that
is, a command that is run if none of the cases matches the switch value.
This is handy to give out error messages, or to check for a single value
(like the number zero) without having to account for all the other possible
values. The syntax for this is:
@switch <value> = <case1>,<command1>,<case2>,<command2>,<default command>
Example:
@ahear foo = @switch %1 =*hello*,"Hi!,*bye*,"Goodbye!,"I didn't understand
that!
7.3 Intro to Functions
Functions in MUSH are special commands which get evaluated and the
value they return is substituted for the actual function call. This means
that if there is a function in an action list (also known as a "function
call"), and that function evaluates to, say, 5, then the function statement
will be replaced by the value when the action list is run. The function
call is not permanently replaced with its value, mind you. It is replaced
in the copy of the action list that will run.
Function calls can be made in one of two ways. If the first word in
an argument to a command or another function is followed by parenthesis,
that string is checked against the list of function names to determine if
this is a function call or not. If it is recognized as a function, then it
is evaluated and the function call is replaced by the results. If it is
not recognized, then the text passes through unmolested, with no error
message. If it is a function call, any text in the argument after the
function is ignored. Only the first word in an argument is checked for
this.
In those cases where the results of a function are to be concatenated
with the surrounding text (i.e. the results of the function call are to be
embedded in a string) then the function is surrounded by square brackets,
TinyMUSH Manual Page 40 Commands for Machines
"[]", to indicate that the text inside should be checked for a function
call.
Function calls have this syntax:
<function name>(<parameter list>)
or
[<function name>(<parameter list>)]
where a parameter list is a list of values separated by commas. A function
must be called with the exact number of parameters it expects or it will
return an error message. For example, if there was a function foo, and it
expected three parameters, a call to it might look like this:
foo(21,42,green socks)
Functions are evaluated if they are the first word in a say command,
but the single quote and the pose command do not evaluate function calls
normally. With these commands, the square brackets must be used to force
the function to be evaluated.
7.4 Simple Functions: RAND() and TIME()
The previous section was probably more baffling then helpful, but a
few examples with some simple functions should make everything as clear as
MUD.
The RAND() function returns a random number. It expects a single
parameter which determines the range of the random number. The return
value will be between 0 and (range - 1.) Remember, you specify the range
(i.e. the number of numbers that are a possible result) not the highest
allowable number.
--------------------------------
Example: The RAND() function
--------------------------------
>say rand(4)
You say "2"
>say [rand(4)]
You say "0"
>say [rand(4)]
You say "3"
>"rand(4)
You say "rand(4)"
>"[rand(4)]
You say "2"
>"[rand(4)]
You say "0"
>:rand(4)
Croaker rand(4)
TinyMUSH Manual Page 41 Commands for Machines
>:[rand(4)]
Croaker 1
--------------------------------
You'll notice that the single quotes and the pose command ( " and : )
the function was not evaluated.
There are much more productive things to do with the RAND() function
than to spout random numbers all day. It can be used in conjunction with
the @switch command, as the following example shows.
--------------------------------
Example: @switch command and RAND() function
--------------------------------
>@create random switcher
Created.
>@adrop random switcher=@switch rand(4)= 0,"Ouch!, 1,"Boing!, 2,:smashes on
the ground,3,"I'm free!
Set.
>drop random
Dropped.
random switcher says "Ouch!"
>get random
Taken.
>drop random
Dropped.
random switcher says "I'm free!"
>get random
Taken.
>drop random
Dropped.
random switcher says "I'm free!"
>get random
Taken.
>drop random
Dropped.
random switcher smashes on the ground
--------------------------------
The other function to be introduced in this section is the TIME()
function. TIME() will return a string that contains the time and date
(remember, though, that the time will be whatever the local time of the
machine running MUSH is on, so its time and your local time may differ.)
TIME() does not expect any parameters, and will return an error message if
you give it one. The parentheses are still required, however.
--------------------------------
Example: The TIME() command
--------------------------------
"time()
TinyMUSH Manual Page 42 Commands for Machines
You say "Fri Jul 27 12:23:15 1990"
--------------------------------
One could use the time command in a number of ambitious ways, such as
to schedule the operations of a machine on a hour to hour or even day-to-
day basis. A simpler use follows.
--------------------------------
Example: the @switch command and TIME()
--------------------------------
>@create Day Teller
Created.
>@listen day=*what day*
Set.
>@ahear day=@switch time()=*mon*,{"today is Monday, N}, *tue* ,{"today is
Tuesday,%N}, *wed*, {"today is Wednesday, %N}, *th* ,{"today is Thursday,
%N}, *fri*, {"today is Friday, %N}, *sat*, {"today is Saturday, %N}, *sun*,
{"today is Sunday, %N}
Set.
>drop day
Day Teller has arrived.
Dropped.
>"what day is it?
You say "what day is it?"
Day Teller says "today is Friday, Croaker"
--------------------------------
TinyMUSH Manual Page 43 Commands for Machines
8 Machine programming
Up until now, the attributes that have been discussed have all been
directly associated with predetermined stimuli, like being picked up,
killed, or cloned. This, however, limits the amount of commands a machine
can perform, and leaves little room for control loops to run. Also, up to
now the only way to get a continuous loop of commands has been to kludge in
things like having the robot rob itself to re-trigger the ASUCC or to
whisper a phrase to itself to trigger the AMHEAR. This section will solve
this, and allow for real programming to be done.
8.1 General Attributes: VA-VZ
All of the attributes, such as ASUCC, AHEAR, and so on have been
associated with certain occurrences or stimuli. There are also 26
attributes named VA, VB and so forth up through VZ that are not associated
in any manner to an external trigger. They can be used for different
things, such as storing strings, action lists, or other values without
worrying about them being triggered by some outside stimulus.
General attributes are set in the normal manner:
@va = This is a test
will store a message in the VA attribute. There are functions that are
available to manipulate data stored in these attributes (and in any
attribute, actually.)
8.2 Action Lists and General Attributes (@trigger)
As stated above, VA-VZ are not associated with a trigger. In order
for these attribute to run action lists, therefore, the @trigger command
must be used. This command will cause the specified attribute on an object
to run. The syntax is:
@trigger <object>/<attribute>=<parameters>
The parameters are what is to be given to the triggered attribute in the
variables %1-%9. The parameters are necessary since any sort of triggering
(the trigger command, something the object hears that matches the LISTEN
attribute) will reset all of the variables. For example:
@trigger foobie/va = bing,1,23
will trigger the VA attribute of the object named foobie, with %0 set to
bing, %1 set to 1, and %2 set to 23.
--------------------------------
Example: @trigger command
--------------------------------
>@create trigger object
Created.
>@va trigger object="This is a test!
Set.
TinyMUSH Manual Page 44 Machine Programming
>drop trigger object
Dropped.
>@trigger trigger object/va
Triggered.
trigger object says "This is a test!"
--------------------------------
The @trigger command can be used to break up execution of a machine
into several action lists. This allows easier programming of machines,
longer and more modular programs to be created. Do not make the mistake of
thinking of a @trigger as a subroutine command or a goto, however. When
the @trigger command is encountered in an action list, the attribute
triggered is placed in a queue to be later executed. This means that there
is no way anything in the triggered attribute will be able to run before
the current action list is finished (and all of the previously queued
action lists, if any, have run as well.) The most common way of chaining
the action lists is simply to have the @trigger command as the last command
in the list to chain to the next list that should be executed. As with
other action lists, if there is no @trigger command and no other action
lists queued, the machine will stop running.
--------------------------------
Example: queuing @trigger commands
--------------------------------
>@va trigger object=@trigger me/vb; @trigger me/vc; @trigger
me/vd; "This is VA
Set.
>@vb trigger object="This is vb!
Set.
>@vc trigger object="This is vc!
Set.
>@vd trigger object="This id vd!
Set.
>@trigger trigger object/va
Triggered.
trigger object says "This is VA"
trigger object says "This is vb!"
trigger object says "This is vc!"
trigger object says "This id vd!"
>>Note that "This is VA" is first, even though the @trigger<<
>>commands came before it in the action list.<<
--------------------------------
8.3 Using General Attributes for Storage
The attributes VA-VZ can also be used to store data to be manipulated
by the machine. This allows such things as counters, string variables, and
so forth. Storing information is simple, since the standard syntax for
storing strings in attributes applies. For example:
TinyMUSH Manual Page 45 Machine Programming
@ahear foo=@vz = %1;@trigger me/va
will store the contents of %1 into @vz. Once set, the general attributes
will retain the data until the machine's program changes it to something
else. This allows for longer term storage than the %1-%9 variables which
are reset after each trigger.
In order to retrieve and manipulate the data, a number of functions
must be use. The simplest of these is the GET() function, which returns the
contents of the specified attribute. The syntax of the GET() function call
is:
get(<object>/<attribute>)
The get function will be replaced by the string stored in the attribute of
the specified object. It is only possible to get the attributes of objects
you own, even if the attribute to be fetched is publicly accessible.
--------------------------------
Example: GET() function
--------------------------------
@va me=This is a test
Set.
"my va = get(me/va)
You say "my va = This is a test"
--------------------------------
There exists a shorthand method for an object to get one of its own
attribute. The syntax for this method is:
%<attribute>
--------------------------------
Example: Shortcut for getting attributes
--------------------------------
"my va = %va
You say "my va = This is a test"
--------------------------------
The next object demonstrates the ability to add a great deal more
variety to the output of machines. Note the use of several attributes to
store some constant strings. This allows greater ease in programming, as
one does not have to retype the string over and over again. Also, it
allows for easier customizing of the object: changing the name of the
object is as easy as resetting a single attribute, and avoids the necessity
of having to @edit several attributes.
8.4 Numerical Functions
MUSH has a set of basic math functions that can manipulate strings
that consist of numbers. The treatment of strings as numbers (hereafter
referred to as numeric strings) is as follows:
If the string starts with a letter, its value is 0.
TinyMUSH Manual Page 46 Machine Programming
If the string starts with a number, then the string is read until the end
or the first letter occurs. The value of the string is equal to the
numeric characters encountered.
For example, the string "A4587" will equal zero. The string "123bla"
will equal one hundred twenty three. In the following descriptions of
commands, we'll assume that "number" is a string that hash some numerical
characters in it.
ADD(number,number)
Adds the two numbers together.
MUL(number,number)
Multiplies the first number by the second.
DIV(number,number)
Divides the first number by the second.
MOD(number,number)
Takes the modulo of the first number by the
second (i.e. the remainder of dividing the
first number by the second.)
--------------------------------
Example: Math Functions
--------------------------------
>"add(34,23)
You say "57"
>"add(12,-9)
You say "3"
>"add(3,bearg)
You say "3"
>"mul(45,34)
You say "1530"
>"div(5,20)
You say "0"
>"[div(20,5)]
You say "4"
>"[mod(21,5)]
You say "1"
--------------------------------
TinyMUSH Manual Page 47 Machine Programming
8.5 Functions to manipulate strings
There are four functions to manipulate strings in MUSH:
First(<string>) returns the first word of a string, that is
everything to the left of the first space in
the string (or the entire string if there is
no space in the string.)
Last(<string>) Returns the remainder of the string after the
first word. In other words, everything to the
right of the first space in the string. If
there is no space in the string, this
function returns nothing.
--------------------------------
Example: the FIRST() and LAST() functions
--------------------------------
--------------------------------
These pair of functions allow parsing of a string word by word. This
machine listens for a string with "parse:" in it. The rest of the line is
stored in an attribute with an end of string indicator (###.) The machine
then takes every word in the string and says it.
--------------------------------
Example: Parsing a string word by word
--------------------------------
>look parse
parse(#7146)
You see nothing special.
Listen:*parse:*
Ahear:@vw me=0;@vz me=%1 ###;@trigger me/va
VA:@switch first(%vz)= ###,@trigger me/vb,@trigger me/vc
VB:"------ complete ------
VC:@vy me = rest(%vz);@vx me = first(%vz);@trigger me/vd
VD:@vw me=add(%vw,1);@trigger me/ve
VE:"word #%vw = %vx;@trigger me/vf
VF:@vz me=%vy;@trigger me/va
>"Parse:this is a test of parsing a line
You say "Parse:this is a test of parsing a line"
parse says "word #1 = this"
parse says "word #2 = is"
parse says "word #3 = a"
parse says "word #4 = test"
parse says "word #5 = of"
parse says "word #6 = parsing"
parse says "word #7 = a"
parse says "word #8 = line""
parse says "------ complete ------"
--------------------------------
These next two functions act almost exactly like their counterparts in
the BASIC language.
TinyMUSH Manual Page 48 Machine Programming
Strlen(string)
Returns the length of the string in a numerical
string.
Mid(string,first,length)
Returns a segment of the string, the <length>
characters to the left of the <first>
character. Note that the first character in the
string is numbered zero, not one.
--------------------------------
Example: STRLEN() and MID()
--------------------------------
>@va me=This is a test
>"strlen(get(me/va))
You say "14"
>"mid(%va,4,4)
You say " is "
>"mid(%va,0,4)
You say "This"
--------------------------------
TinyMUSH Manual Page 49 Machine Programming
9 User Defined Commands
After a while it gets annoying to have to operate machines by talking
to it. Either you have to talk to it out in the open, and contribute to
noise pollution, or you have to go to the trouble of whispering to it.
Also, it ruins the effect of having, say, a Mighty Sword of Slaying if you
have to talk it into killing someone. User defined commands allows one to
create objects that will react to direct commands.
9.1 How They Work
When you enter something in MUSH, it is scanned by the program to see
if it is an internal command. If it is not, then all of the exits in the
current room are scanned to see if any match. If this fails, then the
command is sent out to all objects in the room for them to match against
their user defined commands. In case no object acts on the command, the
"Huh?" message is displayed.
The syntax of the user defined command is stored in an attribute
(usually one of the general ones.) The format for a command definition is:
$<string>:<action list>
where string is the command string to set off the machine. It can contain
wildcards, and will set the %1-%9 variables the same way they are set as if
the LISTEN attribute matched the string.
--------------------------------
Example: User defined commands
--------------------------------
>@create calculator
Created.
>@va calculator=$*+*:"%0 plus %1 = add(%0.%1)
Set.
>@vb calculator=$*+*:"%0 X %1 = mul(%0,%1)
Set.
drop calc
Dropped.
12+90
calculator says "12 plus 90 = 102"
23x3
calculator says "23 X 3 = 69"
look calculator
calculator(#7257)
You see nothing special.
VB:$*X*:"%0 X %1 = mul(%0,%1)
VA:$*+*:"%0 plus %1 = add(%0,%1)
--------------------------------
TinyMUSH Manual Page 50 User Defined Commands
9.2 Security Problems with User Defined Commands
As noted above, all commands that are not recognized as either an
internal command or an exit are broadcast to all machines so that they can
take a shot at matching the command. The problem is that mistyped commands
are broadcast to all the machines in the room. This means that a bit more
caution is called for if you really don't want people hearing what you are
saying. If you should mistype a command like whisper, it is possible for a
machine to record what you said, or relay it to its owner. There is no way,
however, for a correctly typed whisper command to be intercepted.
--------------------------------
Example:
--------------------------------
>@vc calc=$*:"Why did you type %0?
Set.
>grwgrw
calculator says "Why did you type grwgrw?"
>whusper shiva=something secret
calculator says "Why did you type whusper shiva=something secret?"
--------------------------------
TinyMUSH Manual Page 51 User Defined Commands
TinyMUSH Manual Page 52 User Defined Commands
Index
2 C
% See: Percent sign Canceling a room's
/ See: Back slash destruction 13
: See: Say CHARGES 35
; See: Semicolon Chown_ok flag 4
{} See: Braces Clone 12
@clone 12 Commands See: Individual
@destroy 13 command names
@dig 6 changes to old 6
@edit 15 decision making 39
@Force for machines 37
using puppets with 17 grouping 26
@force 7 New 12
@Halt 30 Copying objects 12
@link 8 COST 34
@lock 8 Croaker 2
@Sweep 20
@switch 39 D
@tel 10, See Also: Teleport Dark flag 4
@wait 37 dark flag 9
Delaying a command 37
A Desdi 19
AAHEAR 29 destroy 13
Abode Flag 4 Destroy_ok flag 4
Action lists 23 destroy_ok flag 13
ADROP 23 Dig 6
AFAIL 23, 24 Disconnected room warning 6
AHEAR 28 DROP 3
multiple for one LISTEN
40 E
AKILL 23, 24 edit 15
Akill attribute 30 Enter_ok flag 7
AMHEAR 29 Examine command 7
APAY 34 Examples
ASUCC 23, 24 format of 2
Attributes Exits
editing 15 destroying with rooms 13
locking against 8 linking to objects 8
new 3 list of obvious 9
setting 3 pushing objects into 11
storing commands in 23 the Dark flag 4
B F
Back slash Flags
in a say statement 10 new 4
Braces 26 Force command 7
in a switch command 39 Functions See Also:
individual command names
TinyMUSH Manual Page 53 User Defined Commands
G nomenclature of 1
Give command 7 preventing puppets from
Going flag 5, 13 taking 21
Gonzo 19 pushing out exits 11
relaying information to
H owner 18
Halt command 30 reprogramming themselves
example 26
K runaway 30
Key flag 5, 21 setting homes to players
KILL 3 8
Kill 8 showing the ownership of
and rooms 25 7
and the AKILL attribute Obvious exits list 9
24 ODROP 3
OKILL 3
L Onex 19
LAST 4
LISTEN 28, 32 P
lock 8 Percent Sign
Look 9 in a say command 10
player 2
M Players
Machines destroying 15
cost of running 27, 37 giving object to 7
listening 32 killing in own rooms 25
runaway 30 linking objects to 8
vending 34 Objects impersonating 20
machines 1 pushing others out exits
Money 11
running machines and 27 puppet 1
MUD 2 Puppet flag 5
MUF puppet flag 18
differences from 13 Puppets
MUSH Key flag and 5
commands changed in 6 preventing from taking
history 1 objects 21
Puppet flag 5
O puppets 17
Object number Pushing objects out exits 11
and the destroy command
13 Q
cloning by 12 Quote
forcing a puppet by 17 eliminating extra at end
Objects of LISTEN 32
and the chown_ok flag 4
cloning 12 R
Destroying Robots 1
Destroy_ok flag 4 Rooms
destroying 13 creating & linking with
forcing 17 single command 6
giving to other players 7 Destroying
impersonating players 20 Going flag 5
Key flag and 5 destroying 13
killing 8, 30 killing and 25
limiting number of uses restrictions on killing
35 and 8
linking to 8 unlinked warning 6
making invisible 4 RUNOUT 35
TinyMUSH Manual Page 54 User Defined Commands
S Timing
Say 9 of wait commands 38
Self modifying objects tinyjerk 15
example of 26 TinyMUD 2
SEX 4 TinyTalk 2
Square brackets Triggering
in a say command 10 explanation of 30
squiggly brackets 26
surveillance camera 33 U
Switch command 39 Unlinked room warning 6
default case 40
V
T Variables 32
Teleport Vending machines 34
and the abode flag 4
and the Key flag 5 W
teleport 10 Wait command 37
Tendomatic 38 Wildcards 28
The room of junk and killing in LISTEN attribute 32
9
TinyMUSH Manual Page 55 User Defined Commands
Contents
1 Introduction . . . . . . . . . . . . . . . . . . . . . . 1
1.1 History . . . . . . . . . . . . . . . . . . . . . . 1
1.2 MUSH Overview . . . . . . . . . . . . . . . . . . . 1
1.3 Manual Objectives and Assumptions . . . . . . . . . 2
2 Attribute Lists . . . . . . . . . . . . . . . . . . . . . 3
2.1 New Attributes . . . . . . . . . . . . . . . . . . . 3
2.2 New Flags . . . . . . . . . . . . . . . . . . . . . 4
3 General MUSH commands . . . . . . . . . . . . . . . . . . 6
3.1 Commands not supported . . . . . . . . . . . . . . . 6
3.2 Changes to old commands . . . . . . . . . . . . . . 6
3.3 New Commands . . . . . . . . . . . . . . . . . . . 12
4 Puppets . . . . . . . . . . . . . . . . . . . . . . . . 17
4.1 The @force command and objects . . . . . . . . . 17
4.2 The Puppet Flag and Objects . . . . . . . . . . . 18
4.3 New command: @sweep . . . . . . . . . . . . . . . 20
4.4 Puppets and Puzzles: The Key Flag . . . . . . . . 21
5 Action Lists . . . . . . . . . . . . . . . . . . . . . 23
5.1 Common action lists: ASUCC, AFAIL, ADROP, and
AKILL . . . . . . . . . . . . . . . . . . . . . . 23
5.2 Command Grouping: using the {} . . . . . . . . . . 26
5.3 Cost of Running a machine . . . . . . . . . . . . 27
6 Other triggers and attributes: LISTEN COST and CHARGES
. . . . . . . . . . . . . . . . . . . . . . . . . . . 28
6.1 LISTEN and AHEAR . . . . . . . . . . . . . . . . . 28
6.2 Runaway objects and the @halt command . . . . . . 30
6.3 Wildcards and Variables . . . . . . . . . . . . . 32
6.4 COST and APAY . . . . . . . . . . . . . . . . . . 34
6.5 Restricting the number of uses: CHARGES . . . . . 35
7 Commands and Functions for Machines . . . . . . . . . . 37
7.1 Delaying Commands with the @wait command . . . . . 37
7.2 Decision making with the @switch command . . . . . 39
7.3 Intro to Functions . . . . . . . . . . . . . . . . 40
7.4 Simple Functions: RAND() and TIME() . . . . . . . 41
8 Machine programming . . . . . . . . . . . . . . . . . . 44
8.1 General Attributes: VA-VZ . . . . . . . . . . . . 44
8.2 Action Lists and General Attributes (@trigger) . . 44
8.3 Using General Attributes for Storage . . . . . . . 45
8.4 Numerical Functions . . . . . . . . . . . . . . . 46
8.5 Functions to manipulate strings . . . . . . . . . 48
9 User Defined Commands . . . . . . . . . . . . . . . . 50
9.1 How They Work . . . . . . . . . . . . . . . . . . 50
9.2 Security Problems with User Defined Commands . . . 51
Index 53
i