Starting from Scratch (or, The HitchMUCKer's Guide to the Galaxy) DON'T PANIC! :) by Tardis [Davis Herring] Version 0.1, July 30 2002 >> 0: Contents -------- 1: Introduction: What is a MUCK? 2: Commands 3: Objects in general 1: The #dbref 2: 5 classes of objects 3: The unparsed object string 4: Unparsed object string examples 5: Ways to refer to an object 6: Properties of all objects 4: Object classes 1: Players I 2: Rooms I 3: Things I 4: Exits I 5: Programs I 5: Properties 1: What are they? 2: Implicit properties 3: Flags 4: Locations and the environment tree 5: Explicit properties 1: What are they? 2: 4 Data types 3: @set and @propset 4: Property directories 5: Property permissions 6: Common properties 6: Locks 7: Objects II (?) 8: MPI I (?) 9: MUF I (?) >> 1: A MUCK is a program that interprets commands and maintains a database of objects. This guide will tell you how to understand the commands and use the database, and how the commands interact with the objects. Therefore, this guide will teach you how to MUCK. Please note that this guide is not a newbie page; this isn't meant to tell you how to get around. This is meant to tell you how to use the MUCK, from the ground up. The getting around and talking to people is just a part of what we're talking about here. I'll point out where we'd see them in passing, but they're not the focus here. Also note that this document was written for Fuzzball 5.6x. Many (most, probably) of the concepts are similar on other, derivative, MUCK servers, but not all the commands are the same, and not all of the generalizations will hold, etc. If you find any mistakes in my descriptions, please tell me; I'll check and correct problems as soon as I can. >> 2: As such, in a MUCK, you have commands. Commands are either 'exits' (see sections 3.2 and 4.4) that execute programs loaded into the MUCK's database, or they are internal commands--that is, commands that the server itself executes. Most internal commands begin with an @ symbol, and most others don't. In neither case is the rule absolute, however. For example, the '@when' command is a program, and the 'take' command is an internal thing. Still, an @ generally means it's an internal command. You have to type the @. Most inserver (or internal) commands share a common syntax: @command [=] For example, '@desc here=This is a room.' executes the @desc (DESCribe) command on 'here' (the room you're standing in), setting its description to be the string 'This is a room.'. Some commands don't need an effect specified. An example is @recycle. It destroys its target. So '@recycle here' destroys the room you're standing in (assuming that you own it). >> 3: The MUCK's world is composed of objects and only objects. This section describes the nature and use of these objects. >> 3.1: One thing is common to all classes of objects: a 'database reference number' or '#dbref' for short. The #dbref is the only always-unique thing about an object (although among players names are unique as well). The #dbref can be thus used as a pointer to an object wherever it is, whoever owns it, all that. >> 3.2: There are 5 classes of objects: [That's right, only 5. There aren't any more. Really.] ------------------------------- 1: Players, which are objects that can be connected to by humans at keyboards, and are the characters of the realm. 2: Rooms, which are places, can contain anything--other rooms, even, if they're a parent room (see section 5.4). 3: Things, which are items; they can be carried, and can have exits on them, etc. They can also contain other things, or programs, or even players (but only if they're @set VEHICLE--see sections 4.3 and 5.3). 4: Exits are objects that have targets (this target is called a 'link'); typing their name when you are 'near' the exit does something with the target. 5: And finally, programs are objects that, while they have physical existence (can be carried, etc.) are there for another purpose--they contain code that can be executed (by using an exit linked to them, for example). These classes of objects are referenced by a letter: Player, Room, Thing, Exit, and muF program (that's F). >> 3.3: If you own an object (or something is special about the object; see section 5.4), then when you see its name you will often see a number and letters in parentheses afterwards, as in 'Q-Glasses(#1659W)'. This string gives 4 pieces of info: ----------------------------------- 1: The name of the object, before the parentheses: 'Q-Glasses' here. 2: Its #dbref, the # and numbers in parentheses: #1659 here. 3: Its object type, the next letter: ...but there's no P, R, T, E, or F! I'll explain in a moment. 4: Its flags, as single letters, or an M with a number. I'll explain this next. >> 3.4: So, for this, the name of the object is 'Q-Glasses', its #dbref is #1659, its type is ... blank? If there isn't a P, R, E, or F, the default is Thing. (In fact, the MUCK never prints the implied 'T' in flaglists.) So this is a Thing. Its flag (it happens to have only one) is W, for WIZARD, which means these glasses, or, in this case, code stored on them in the form of MPI (see section 8), has much power. Another object would be easy-say.muf(#284FWM3). Its name is easy-say.muf, its #dbref is #284, its type is F (muF program, remember), and its flags (this one has two!) are W and M3. The W is again WIZARD, which means this program can also do most whatever it wants. M3 is also a permissions level; it's kinda redundant here, though. MUCKER3 is one level /below/ WIZARD, so that's kinda like being a Colonel /and/ a General at the same time. Being a Colonel doesn't help ya. Maybe I should fix that. I'll tell you how you could (...that is, if you were being allowed to) later. Incidentally, this easy-say.muf is a program that ... can you guess? Handles 'says'. That is, when you type 'say hi'... the 'hi' is sent to this program. It reads your properties (discussed later) and then outputs to the room you're in what you say, with formatting specified by those properties. And you thought you were just talking! >> 3.5: How to name an object for most commands: ---------------------------------------- #: Way PROS CONS 1: By name. Makes sense. Object has to be nearby. Easy to remember. Object needs a unique name. 2: By dbref. Never ambiguous. Easy to forget. Almost always works. Typ0s. 3: By $regname. Pretty-close-to-always works. Have to be specifically assigned. '$chrono' is just cool. User-specific, unless a wiz sets it. What's a $regname? 4: By *playername. Kinda-always works. Often, only wizzes can use it! All four of these will work (given the right circumstances) for /almost/ any of the internal @commands, and most of the others. Occasionally, though, one (or ten) will decide that it's (they're) special. Try another method. >> 3.6 All objects share some common data: ----------------------------------- 1: They all have a name, which (except for players) has very few restrictions. 2: They all have an owner, which is always a Player. 3: They all have a location, which is never an Exit or a MUF program. 4: They all have timestamps indicating the times at which they were created, last modified, and last 'use'd. 5: They all can have explicit properties (see section 5.) Each of the classes of objects (to be discussed shortly) adds more information that completes their representation, and perhaps specify rules about their fields (where they can be, etc.). >> 4: This section will introduce the attributes of each of the five object classes. >> 4.1: Players I Players add several pieces of data to the generic object: --------------------------------------------------------- 1: A password (string, of course). 2: A number of pennies. (An integer; Things also get this.) 3: A contents list (A list of Things: what the player is carrying; Things and Rooms also get this). 4: An exits list (A list of what Exits are 'on' the player; Things and Rooms also get this). 5: A @link field (a room reference), used by Players as their 'home'. (Only MUF programs do not get this field). A Player is only different from a Thing in a small number of ways: ------------------------------------------------------------------ 1: It has a password assigned it, and can be connected to using that password ('connect playername password', of course). 2: It is generally a lot more fun than things, at least when there's a player connected to it. 3: It has a different set of restrictions on teleportation/location (for instance, any Thing can be inside any other Thing or any Player, but a Player can only be inside a Thing @set VEHICLE and can never be inside another Player). 4: It can own objects. 5: Its home must be a room. 6: Its name must be no more than 16 characters long and may contain no spaces. Other than that, a Player is just like any other object. Players are created with @pcreate and destroyed -- or rather, turned into Things -- with @toad. Both of these are wizard-only commands, for obvious reasons. Players also have pennies. Pennies on Players are used for building (and perhaps other MUCK-specific economic ventures). Players can also attempt to 'rob' one another. If such a command is issued, the @lock on the victim is checked. If it passes (or is absent), the robber transfers one penny from the victim's supply to their own, and @success messages are generated (see section 5.5.6). Otherwise, @fail messages are generated. For this reason, newbie players are often advised to '@lock me=me'; since that lock will only pass when they are executing the command, no one can rob them after they use that security measure. (If that didn't make any sense, see section 6.) Players have an owner, but it is always themselves. >> 4.2: Rooms I Rooms also specify additional fields: ------------------------------------- 1: A contents list (A list of Players, Rooms, and Things: what the room contains; Players and Things also get this). 2: An exits list (A list of what Exits are 'on' the room; Players and Things also get this). 3: A @link field (reference to another room). (Only MUF programs do not get this field). A Room is thus different from a Player in relatively few ways: -------------------------------------------------------------- 1: It has no password, and cannot be connected to. 2: It can only be inside another Room (this is called its 'environment room' or 'parent room'), never a Thing or Player. 3: It has no pennies. 4: A Player can be inside it, and can be @link-ed to it. 5: It can't own objects. 6: Its @link is not a 'home' but a 'drop-to'. An environment room, which is a room containing other rooms, is used for several grouping purposes, including organization of areas by owner or geography. They are covered in greater detail in section 5.4. Use @teleport to set a parent room for a room. ('@teleport room=parent', because you are putting the room inside its parent.) A 'drop-to' on a room, established with @link (and removed, since they can be removed, with @unlink) is the location to which objects 'drop'ped in the room are sent. If the room is @set STICKY (a flag; see section 5.4), the objects are sent there as soon as there are no people standing in the room. Rooms are created with @dig (which by default costs 10 pennies), and destroyed with @recycle. Non-wizards must be standing in a room to @recycle it. If a room is @recycle-d with objects in it (as is always the case if a non-wizard is recycling), those objects are sent to their homes. If that room WAS their home, Players have their home set to the default player home (see section ?.?) and Things have their home set to their individual owners. Then all objects are sent home. Any exits on (contained within, attached to) a room that is @recycle-d are destroyed as well. Rooms within a @recycle-d room are...? >> 4.3: Things I Things are even more similar to Players in their additional data: ----------------------------------------------------------------- 1: A number of pennies. (An integer; Players also get this.) 2: A contents list (A list of Things: what the Thing contains; Players and Rooms also get this). 3: An exits list (A list of what Exits are 'on' the Thing; Players and Rooms also get this). 4: A @link field (a reference to a Player or Room), used by Things as their 'home'. (Only MUF programs do not get this field). Things are different from Players in the following ways: -------------------------------------------------------- 1: It has no password, and cannot be connected to. 2: It can be inside a player. 3: A player can be inside it (if it is @set VEHICLE). 4: It can't own objects. 5: It can be 'take'n and 'drop'ped. 6: Its home can be another Thing, a Player, or a Room. Incidentally, this is what happens when a player is @toad-ed. Their password is deleted, and they are converted into a Thing. All their properties (see section 5) remain, as do their dates of creation and whatnot. So, while @toad-ing is generally permanent, someone with access to the server can actually un-@toad someone by modifying the database to have a password listed for them, and marking them as type Player. However, this is rarely done, and would require shutting down the MUCK for the meanwhile, and all kinds of other ugly things (like giving the player back all their objects, which @toad removed). Things are created with @create (which by default costs 10 pennies) and destroyed with @recycle. Non-wizards must be holding a Thing to @recycle it. Objects within destroyed Things are swept home as are those within rooms. >> 4.4: Exits I Exits specify this additional field: ------------------------------------ 1: A @link field (to any object). Exits are the type of object most different from the rest, because they represent not a physical object but an action, specified as another object called the exit's 'target'. Exits /do/ something with their target when their name is typed as a command. What is done depends on the type of the object involved: If the target's type is... The exit... --------------------------------------- Room Moves you there. Player Moves you to that player's location. Thing Moves the target to the source ('pulls' the Thing back along the Exit) MUF Program Runs the program. You're near an exit if it's on (on here means has as a source; technical term is 'attached to') you, on a room you're in (or a parent room), on an object you're carrying, or on an object sitting on the floor with you in the room. Exits are also known as actions--the only difference is that if you specifically say 'exit' you're more likely to mean one that's a physical exit, a way from one room to another. Exits are rather different from the three main kinds of physical object -- they can contain nothing, can have multiple @link-s (in a relatively-rare construct known as a metalink), and have no pennies, password, etc. Exits are created with @action or @open. The creation of an exit costs 1 penny by default, and @link-ing it (whether as part of an @open, or with a separate command) costs another (by default). Exits are unlinked by @unlink, destroyed by @recycle, and moved by @attach. >> 4.5: Programs I Programs provide almost all the high-level functionality for a MUCK. On most MUCKs, 'look', 'say' (or '"'), 'pose', 'page', 'whisper', 'hug', 'who', 'ws', 'wizzes', and sometimes 'WHO' are ALL programs, written in MUF, that the server executes whenever those commands are typed. There are often more specialized programs, too -- programs to generate a visual effect, provide atmosphere, automate a process, do recordkeeping, manage specialized objects (like spaceships in a space section of a MUCK), or any of an innumerable set of other tasks. >> 5: Objects have what are known as 'properties' to make them distinct and worth more than a pile of beans. That's not just a cliché; a pile of beans isn't very interesting because each bean's just like all the rest. Properties keep objects from being 'just like all the rest'. >> 5.1: Properties thus control or specify how you, other players, and other things and programs can or do interact with the object. Properties are set with various @commands. Properties are read with the 'examine' or 'ex' (for short) command--that's one of the internal commands that doesn't start with a @. There are, in fact, two kinds of properties: implicit and explicit ones. Implicit properties correspond to the fields described above for different kinds of objects; every example of a given class of object has an instance of every implicit property that class gets (although it may have a 'null' value there). Explicit properties only exist for an object if they are specifically set, and any explicit property may exist on any class of object. The MUCK itself (as opposed to a program running on it) mostly worries itself with implicit properties; only a few explicit properties are ever read by the server for its own purposes, and even fewer are set by it. >> 5.2: [Implicit properties are generally read with 'ex obj'. Ways listed here are alternatives.] Implicit properties include: How set/read: ---------------------------- -------- An object's name @name obj=newname [any object] Any listing of the object, such as 'ex' or even 'look' Who owns an object @chown obj [CHange OWNer to you] ex obj (even if you don't own it) Where an object is @teleport obj=newlocation [for things, players, rooms (special)] @attach exit=object [for exits] Just by carrying it around [things] @trace obj For a player, a password @password oldpassword=newpassword @newpassword player=newpassword (for wizzes) Passwords can never be read through the game. A penny count (for Ps, Ts) give player/obj=amount (non-wizards can only give non-negative amounts, and only to players) 'score' or 'inventory' (for you) Its home, or default location @link obj=home [things, players] An exit's target @link exit=target A room's dropto (special) @link room=dropto Timestamps Set by the server to say when something was created/modified/used @when obj Flags--important @set obj=flag @set obj=!flag [to remove it] The server program primarily sets and reads these properties. They dictate the structure of the MUCK world, and some of its basic behavior. >> 5.3: Flags are binary settings (only yes or no) on an object, many of which control very important things about that object. Flags are known by letter, with different meanings for, say, players and things. The letters are A B C D H J K L M Q S V W X Z Usual meanings: B U H A A U I I U U T E I F O O I O R V M L N C E I H Z O M D L W K E P L K K L C I A R B E D N N _ _ _ E L K C R C I E _ O O O R Y L D I E R O K K K # E B K L E Occasionally flag names change to represent a different behavior on a different class of object: ABODE becomes AUTOSTART on a program. BUILDER becomes BLOCK on a room and BOUND on a program. DARK becomes DEBUG on a program. HAVEN becomes HARDUID on a program. STICKY becomes SILENT on a player or SETUID on a program. The MUCKER flags are an exception; internally they actually are flags, the MUCKER and NUCKER flags. But what you see is a number ranging from 0 (no permission) to 3 (nearly wizard-level permission), describing for a player what programs they may write, for a program what functions it may use, and for an exit what it can override (this is a rare use). If an object is @set ABODE, CHOWN_OK, or LINK_OK, then anyone who sees its name in any inserver printout (such as output from examine) or in many programs' displays (such as 'look', most often a program) will see a flaglist after it, just as if they owned it (unless they themselves are @set SILENT, which blocks all such flaglists). For help with a flag (explanation of what it does, who may @set it, etc.), type 'help ' at any time. >> 5.4: The 'location' of a room is called its parent room; you can put any number of rooms into a parent (or environment) room. This allows (as mentioned above) an exit to be usable from multiple rooms. The global commands, or rather the exits leading to them--like whisper, page, pose, or say, as opposed to something like 'easy-say.muf' which is the MUF object--are put onto an environment room that contains most everything else--perhaps even onto #0. #0 is the room that contains /everything/ else, so any action @attach-ed to it is usable anywhere. The sequence of locations--the place where an object is, where that is, where that is, and so on (up until #0, which isn't inside anything), is called moving along or 'down' the 'environment tree'. 'Environment tree' may also be a diagram denoting what environment rooms contain which other ones, mainly used with the really big ones that are there to hold global commands. So, a command will work if its exit is located 'somewhere down the environment tree' from you; also, some properties can be established for a whole area by @set-ting them on a room on the environment tree from the rooms to which you want it to apply. >> 5.5: >> 5.5.1: An explicit property usually controls something more subtle about an object--if it's a room, who can spoof there, etc.; if it's a player, who they last whispered to, etc., if it's a program, what version it is... stuff like that. The system does not usually use these properties, but it can; programs are more likely to access these. Explicit properties have a name and a value. (Like the Unix file system, explicit properties' names are delimited by and begin with a '/'; this initial '/' is optional in naming the property, since there are no 'relative property names' which would not use it.) The name is what tells you what property it is and/or what data may be found there; the value is what's stored there, like a variable in programming. Explicit properties are read with a different syntax of the 'examine' command: 'ex obj=property'. The 'property' can be a property directory (to be discussed shortly), a specific property, a pattern (see 'man smatch' for information about patterns) against which properties should be checked for a match, or nothing at all (in which case the object's "root" properties are listed). >> 5.5.2: Explicit properties can have 4 types of data stored in them: ------------------------------------------------------------ 1: A string. Just text. Can contain MPI (see section 8). Most common type. 2: An integer. A number, no fractions. 3: A dbref. Pointer to an object (can be the object containing the property if desired). 4: A lock. A specially-processed string that can be checked for a success or failure. Strings are by far the easiest to use for a player, although all can be; for the most part, only MUF programs work with the other three for their own evil purposes. >> 5.5.3: Explicit (string) properties are set with a different format for the @set command. (You use other commands to set the other 3 types.) @set obj=property:value This sets the property named 'property' on the object named 'obj' (although you can use a dbref here, of course!) to the string 'value'. A slightly more advanced command is @propset, whose syntax is @propset obj=type:property:value This sets the datum 'value' into the property named 'property' on 'obj'. The 'type' token determines how @propset interprets 'value'. The valid strings for the type parameter are 'string', 'int', 'dbref', 'lock', and 'erase'. These are largely self-explanatory, although it is worthy of mention that when using 'erase' one need not even specify the ':value'. Use '@set obj=property:' as an easier way of removing a value. Use '@set obj=:clear' to remove all properties (that you're allowed to remove) from an object. (Some sets of documentation will say you just use '@set obj=:'; this is incorrect.) >> 5.5.4: Explicit properties are stored in property directories, or propdirs. Property directories, by and large, do not actually exist. This may be confusing at first, but what they really are is a naming convention. The standard page program, for instance, stores all its properties (by default) in the property directory '_page/'. This means that all page's properties begin with that, like '_page/awaymsg' for your custom #away message, or '_page/formats/o-page' for one of the format properties (see 'page #help' for more information). The only two 'real' aspects of property directories are in listing them with 'examine' and with deleting them. If you do 'ex me=/', for instance, and you have some of those page properties that I mentioned set, you would only see 'dir /_page/:(no value)' in the listing. So the property directory is a placeholder, a sign that there are more properties there, without spamming you by going ahead and listing all of them. And when you delete a propdir (with '@set obj=propdir:'), you delete all the properties under it. This can be quite convenient, but it can also be dangerous. The most delicate issue arises when there is a value stored in the property under which the other properties reside. This is evidenced by the '(no value)' for the '_page/' listing. That implies, correctly, that there /could/ be a value. And indeed, if you then did '@set me=_page:stuff', and repeated the 'ex me=/', you would now see 'str /_page/:stuff'. The trailing '/' indicates that it is still a property directory, but it now has a value, of type 'str' and value 'stuff'. So suppose we wanted to remove this 'stuff' value. The most obvious approach is to use '@set me=_page:' and remove the property. But because _page is also a property directory, if you do that, you remove all its subproperties, including all your custom formats and messages and everything! What's to be done? You use @propset's more advanced features here. Invoke '@propset me=str:_page:', and the null-string (since there's nothing after the second ':') will be stored to your '_page' directory. This is interpreted as removing its value, and you will get 'dir /_page/:(no value)' again. But the properties under it will not be affected. (@propset with 'erase' as the type is exactly the same as @set with a terminating colon.) Using 'examine' to list the contents of a property directory is simple enough: 'ex me=_page/' will list the /contents/ of the '_page' propdir instead of the '_page' property itself. In fact, the command 'ex me=/' is referring to the 'root' property directory; because the initial '/' in property names is optional, the command 'ex me=' works just as well. The special token '/**' after the name of a propdir (as in 'ex me=_page/**') asks to see ALL properties under that property directory and any subdirectories under it. >> 5.5.5: Property permissions: --------------------- There are five levels of protection for properties. They are effected by the first character of the property name. 1: /text Properties with no special character have no protection. Most any program can read or write them. 2: /_ /% /sex Properties beginning with '_' or '%', and the property 'sex', all have a slightly higher protection. Programs need high levels of authority to write to these, but are free to read them. (Properties beginning with '%' are relatively rare; they're used in pronoun substitution. See section ?.?). 3: /. Properties beginning with '.' cannot be read or written by programs without high levels of power. 4: /~ Properies beginning with '~' can be read by any program that knows where to look, but wizard-level power is required to write them. 5: /@ Finally, properties beginning with '@' can only be read OR written to by wizards and programs of their level of power. These are the only properties that an individual user cannot access on themselves; 'ex me=/**' will list all properties on you /except/ those with '@'. Thus, such properties can be used for secure information storage, such as real life information and whatnot. Because the permissions associated with a property depend only on its name, an attempt to read an unreadable property results in an error whether or not the property actually exists. Thus, knowledge not only of the value but also of the existence of such properties is protected. These property protections are actually subtly more complex. The first character of the entire property need not be a special character, as long as /somewhere/ in the full property name is the string '/*' where * is the character in question. Thus, a property such as '_prefs/@hidden' has the @ level of protection (and is thus invisible to most checks), whereas '_prefs/nothidden' inherits the _ level of protection from its head propdir. In general, property protections are extended to members of property directories. >> 5.5.6: The most important explicit properties, though, have their own commands. These that follow are called @messages because they're messages, and you set them with @commands. Property What it is Set with '@xxxx obj=' ---------------------------------------------------------------------------------------- _/de Description (what you see when you look at it) @desc _/sc Success message (when you 'use' it) @succ _/osc Success o-message (what other people see) @osucc _/fl Fail message (when you try to 'use' it but don't) @fail _/ofl Fail o-message (what other people see) @ofail _/dr Drop message (when you drop the object, plus more*) @drop _/odr Drop o-message (what other people see) @odrop If nothing is specified after the '=' in the associated @command, the property is removed. Whether the @fail or @success messages are triggered depends on the @lock setting and the identity and status of the person trying the activity. See section 6. All these messages can contain MPI; it will be parsed before displaying the message. A @message is always processed before its corresponding @omessage. See section 8. >> 6: Property What it is Set with '@xxxx obj=' ---------------------------------------------------------------------------------------- _/lok Lock (what determines if you manage to use an item) @lock _/clok Container lock (determines nestability of objects) @conlock _/chlok @Chown lock (whether object can be claimed) @chlock @/flk @Force lock (whether object can be forced to do something) @flock . . . >> 7.4: Exits II Anyone can @link an unlinked exit to something they control. @Link-ing an exit grants you ownership of it if you did not own it already. Anyone can @chown an exit that is @attach-ed or @link-ed to something they own. These can be important security issues, and should be kept in mind.