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