UglyMUG builders' tutorial

Contents

  1. Audience
  2. Typographic Conventions
  3. General Information
    1. What is a Builder?
    2. How to get a Builder flag
    3. Email addresses and HUH logs
    4. Getting More Building Points
    5. Guidelines for Building Good Areas
    6. Object Costs
  4. The Tutorial
    1. Designer Rooms
    2. Creating a Room
    3. Linking a Room into the World
    4. Building an Area
    5. Linking Rooms with Exits
    6. Exciting Exits
      1. An Exit you can't see through
      2. Hidden Exits
      3. Locking an Exit
  5. Making your own commands
    1. Simple Commands
    2. Success and Failure
    3. Changing Player ID
    4. Automatically executed commands
    5. Variable referencing
    6. Command parameters
    7. Using Queries
    8. Embedded Newlines
    9. Drop To's
  6. Alarms and Fuses
  7. Credits

Audience

This tutorial is intended for new builders, or non-builders who wish to take their building test. It is not a substitute for the online reference manuals.

Typographic conventions

A few conventions are used consistently throughout this tutorial:

General Information

What is a Builder?

A builder is a player who is able to extend the game by creating and altering scenery and commands. When UglyMUG was started, there were only about 250 objects in its database. Now there are over 60,000. Almost all of the other objects were created by Builders, extending the game.

How to get a Builder flag

We strongly suggest that you spend some time looking around UglyMUG and the manual before you request a builder's flag. There's little point just building yourself another poorly thought out, badly-described house and bedroom; there are plenty of those around already. Try thinking of something original to build. See Guidelines for Building Good Areas below.

To get a builder's flag, ask a wizard who is online or MUD-mail a wizard. They will probably ask for some kind of evidence that you could build and that you have read and understand (at least bits of) the manual.

The wizard will also ask for an email account; they don't hand out flags without an email address, so don't ask. This email address is only visible to admin, who use it for two purposes:

  1. To contact builders before doing something unusual, such as deleting objects owned by someone who hasn't logged on for a long time;
  2. To mail out the nightly HUH logs (see Email addresses and HUH logs below).

The wizard will give you some building points for you to start. If you need more, be prepared to justify why you need them (see Getting More Building Points below). For large projects that will need lots of building points, talk to a wizard. They sometimes hand out experienced-builder (X) flags for that purpose.

Email addresses and HUH logs

Every night, a program runs on the UglyMUG server that emails out various information. Much of it goes to the admin, and some of it is even useful.

When you become a builder, UglyMUG will start emailing you a HUH log. This lists things people have typed in your area that UglyMUG could not understand. Some will be pretty useless (a misspelled tell command, for example). Others are more useful - you'll find out pretty quickly about any commands people want to run that you haven't provided. Please look through your HUH logs on a regular basis, check for commands that you don't yet offer, and add them.

Don't be surprised if you don't get HUH logs every night. If nobody has typed anything in your area that UglyMUG didn't understand, you won't get any email that night.

Getting More Building Points

When you first become a builder you will be given a few building points. These are to allow you to build something interesting, so use them to do this. If you run out of building points and need more, there are two ways to get some:

  1. Recycle some of your existing objects. UglyMUG refunds the BPs used to create an object when you @destroy it.
  2. Ask a wizard for more BPs.

If you need ask a wizard, expect them to look around your area with a critical eye. If it's good, they'll give you more building points and a gold star. If it needs work, they'll point out what parts could do with some attention but won't hand out more BPs.

Guidelines for Building Good Areas

This isn't an exhaustive list, but think about the following when you're building an area.

Object Costs

Creating an object always costs building points one way or another.

Object typeCommandCost (BP)
Room@dig10
Thing@create10
Exit@open1
@link1
Command@command10
Property@property1
Array@array1
Dictionary@dictionary1
Fuse@fuse10, +1 every time it fires.
Alarm@alarm0 (Wizard only), +1 every time it fires.
Non-player Character@npc1,000

The Tutorial

The reference manual is fine if you need the syntax of a command, but it's a bit bewildering when you don't know what any of the ideas mean. This section sets out to restore the balance, by providing a (hopefully) simple introduction to building On UglyMUG.

I'll start with a small example: a study. It's a room with a way in and out to a landing, a desk, a chair, a computer on the desk and a chiming clock.

Designer Rooms

The first thing to do is to work out roughly what you want in the room. In this case, I've already done that - it's the list shown above.

The next thing to do is to have a think about each thing you want to build, and work out what type of UglyMUG object would be best suited to it. There are many kinds of object in UglyMUG: Alarms, Arrays, Commands, Dictionaries, Exits, Fuses, NPCs, Players, Properties, Rooms and Things. Most of these are intended for use when you're programming, and we'll only cover Rooms, Things and Exits in this part of the tutorial. In this tutorial, I'll always use a capital letter when I mean an UglyMUG type - Room rather than room, for example.

When do you use each type? Here are some rules:

Looking at our simple example, we can see that the study should be a Room, the ways in and out should be Exits and everything else should be Things. We can see how to do most of it, although making the clock show the right time and/or chime could be troublesome.

Creating a Room

It's quite possible to dig a Room and pretend it's in the middle of a vacuum --- in fact, if you don't do anything else to it, that's where it will be. Newly created Rooms are just empty spaces, with no relationship to anything else in the game. So:

@dig Wizard's Study
Wizard's Study created with room number #244.

The system told you the room's ID. An ID is a unique number that's assigned to each object in the system when it's created, and stays the same until (unless) the object is destroyed. In this case, our Room is object number 244 in the database, so we can refer to it as #244. Even if there's no other way of referring to an object, you can always use its ID.

You own anything you create, so you can examine this new room using examine (ex for short):

ex #244
Wizard's Study (#244 R)
Owner: Wizard(#1 PG); Key: *UNLOCKED*; Building points: 10; Flags:
Contents:
Mass Limit: None.
Volume Limit: 10000 Litres

So the new room has no contents, no ways in or out - in fact it's a perfectly normal piece of empty space.

Now that we've got our Room, the next thing to do is to make it something other than an empty shell. Real rooms, such as the study we're trying to represent, don't just have a name. They're not all uniform, cubic, unlit grey spaces. So it is with the study we've built. It needs:

You can set the description of a room using @describe (@desc). Long descriptions can spread over more than one paragraph. Just as in a word processor, you should type a paragraph so that it's all on one line. UglyMUG will then format the paragraph appropriately for each player's screen.

If you want a multi-paragraph description, or you just want a newline in a description, you need to put a backslash (\) just before the newline. If you don't do this, UglyMUG will assume that you've finished telling it the description and will set it. This trick works for all input in UglyMUG, by the way. Try it using say or emote:

say Line one...\
Line two.

You say "Line one...
  Line two."

So our study could be described as follows:

@desc here=This used to be the back bedroom of the house. It's about four metres by three. A modern window shows the back garden; the view is framed by a pair of curtains.\
\
Evidently the study can get quite dark; the walls are white, the carpet is a pale grey that shows up a number of coffee stains. Whoever works here obviously likes coffee.

There are several things to note about this description:

We have now set up an isolated room. It has a description and (if you've followed the section on physics) it's the right size. However, we still have to connect it up to the rest of the MUD, and we still have to fill it with Things for the players to play with. Read on...

Linking a Room into the World

An isolated room isn't much good to anybody; it needs linking into the rest of the game. There are two parts to this:

Building an Area

In real life, spaces aren't isolated. People group them into things that are more useful to talk about. Rooms are grouped into houses or offices; buildings are grouped into streets; streets are grouped into towns.

UglyMUG has the same approach. Any Room can be put into an Area. An Area is simply another room - there's nothing special about it except that it happens to hold some other Rooms. Area rooms can be put into other area rooms, and so on.

Apart from general tidiness, why would you want to do this? There are a number of advantages:

The area approach carries on further than this. UglyMUG has its own area hierarchy, containing Sandyville, High Vulcan, Idlesville and the other towns. Ultimately, these are all parts of Top Area (#2). Once you have your own top area, ask a Wizard to place your top area into the main area tree. This helps both you and the admin team.

Let's use an example to illustrate this. Here, we'll create a house, place it in an area, then get a wizard to place it in 'Top Area'.

The first step is to dig a 'top room'. This room won't have any entrance or exit; it's the container into which you place all your rooms. Other than that, it's just an ordinary room:

@dig My top area
My top area created with room number #25000

#25000? Just lucky, I guess. Now we dig the other rooms in the house:

@dig Bedroom=Very messy, wouldn't want to be in here too long
Bedroom created with room number #11945
@dig Garden=More of a builder's yard really.
Garden created with room number #12552
@dig Landing=Don't leave the landing light on...
Landing created with room number #4756

At the moment, none of the rooms of this house are in an area. Commands like silly will not work, and we won't be able to @open any Exits from any of them.

This is an important point: you have to control the room's area (and it must have one!) before you can open exits from it. If you try anyway, UglyMUG will respond You don't control (whatever), where (whatever) is the name of the area containing the room. If the room isn't in an area, *NOTHING* will be displayed instead, leading to one of UglyMUG's craziest error messages: You don't control *NOTHING*.

To place the rooms in #25000 (my top area), I use the @teleport (@tel for short) command:

@tel #11945=#25000
Located.
@tel #12552=#25000
Located.
@tel #4756=#25000
Located.

Oh yes, we'd better put the study in that area as well:

@tel #244=#25000
Located.

The first number is the ID number of each room; the second is the ID of our top area.

Now we can @open exits from these rooms to make the house navigable, and we can put commands (see later) in #25000 that will be available in all the rooms.

There's one more thing to do. Wandering around my little house, we still can't use commands like 'silly'. We need a wizard to @tel #25000 into the game's geography for us.

page flup=Please could you move #25000 into Top Area?
Message sent.
PAGING from Flup's Workshop, Flup says "Done."

That's all there is to it! The area structure now looks like this:

 Top Area 
 | 
 ... 
 | 
 My top area
#25000
 
+---------------+----------+----------+---------------+
Bedroom Garden Landing Study

Linking Rooms with Exits

Now that the room's been placed in its correct area, we can set up ways into and out of it. Let's assume that we've already built the landing of the house, and described it. We want to create a doorway that's the way out to the landing. We use an Exit for this job.

Exits are created using @open. This requires a list of exit names. Each name in the list is separated by a semicolon (;). The first name in the list is special - it's the one that is displayed in the list of 'Obvious exits' when you look at the room. If a player types any of the exit names, (s)he tries to go through the Exit. So, to create a door to the landing:

@open A cheap wooden door from MFI;wooden door;door;MFI;landing;land;lan;l;out;o;exit;back;leave
Opened.

This looks like a very long list of possible names, but don't panic. It was made up by using the following rules:

The exit is created in whichever Room you are at the moment. If this happens to be the wrong one, don't panic; you can pick the Exit up using get and drop it in the correct place.

Now that we've created the exit, we can link it to the landing. As UglyMUG doesn't understand 'landing' unless you're in the room, you need another way of referring to it. The usual way is to use the ID of whatever you're referring to (it's the number preceded by # when you look at something you own). This number is unique to the object and is guaranteed to refer to it at all times. So, if the landing is printed as:

Landing (#4756 R)

then you can link the door to the landing using @link:

@link door = #4756
Linked.

If you now examine the Exit, you will see:

[TODO: insert examine here]

Exits work in one direction only. Just because we've created an Exit from the study to the landing, it doesn't mean we can get back again. To do that, we need an Exit going in the other direction as well. It's time to take a look round our study, remember its ID (we'll need it to link the Exit from the landing) and step outside:

out
Landing (#4756 R)
...

Now that we're on the landing, we can create our Exit into the study. It should re-use as many of the names from the 'out' Exit as possible. Since we already know the ID of the Room we're linking it to, we can open the Exit and link it all in one command:

@open On your left is a cheap wooden door from MFI;left wooden door;left door;left MFI;study;stud;stu;s;left;l = #244

We've had to alter the exit names slightly, as there will be other cheap doors from MFI going to other Rooms. This one is the one on the left, so we've called it that. We've also fixed the other names so that they include 'left' where needed.

Just to make sure, we can now go back to the study:

study
Study (#244 R)
...

Exciting Exits

Just as Rooms are different, so are Exits. It's not just their names, either; you may wish to change:

An Exit you can't see through

Going back to our study, we might decide that the door is closed except when somebody opens it to go through. Since it's a cheap, tacky, wooden door, nobody can see through it. To make this kind of Exit, you set it OPAQUE:

@set door=opaque
Flag set.

If an Exit is OPAQUE and a player looks at it, they see the Exit's description. If you've not set anything else, they'll be disappointed:

look door
You see nothing special about it.

So we'd better set a description for the door:

@desc door = It's cheap and tacky. The door was originally stained dark brown; owing to carelessness on the part of whoever does the painting round here, it's flecked with bits of paint.\
The door might keep a fire at bay for as long as five seconds, but it's not guaranteed.

Description set.

Since the door had better be OPAQUE both ways (it's not a one-way mirror, after all), we should do the same thing to the Exit from the landing:

out
Landing (#4756 R)
...
@set study=OPAQUE
Flag set.
@desc study = It's cheap and tacky, and stained dark brown. It might keep a fire at bay for as long as five seconds, but it's not guaranteed.
Description set.
study
Study (#244 R)
...

If we hadn't done this and somebody looked at the door, they would see straight through it and into whatever Room is at the far end. This works well for open bits of land (or open-plan houses), but it's not so good for doors.

The OPAQUE flag controls whether you can see through an Exit or not. Later there's an example of a command that will open and close a door, setting OPAQUE accordingly.

Hidden Exits

If we look at the study now, the Exit announces itself but no longer says where it leads to:

[TODO: look]

Most of the time, an exit should announce itself like this; but what about less obvious exits? In our case, how about a fire escape:

@open window;wind;win;w;garden;g = #12552
Opened.
Linked.

gives us an exit through the window to the garden. Since it's not going to announce itself, it doesn't need a fancy label as the first part of its name. All we need to do now is to make the exit a hidden one, using the DARK flag:

@set window = dark
Flag set.

We don't want this exit to be OPAQUE, since we want a Player to be able to see through it into the garden if they happen to look through the window. This serves a double purpose: as well as the fire escape, we've now answered what will happen if someone notes that there's a window in the room's description and tries to look at the window.

Locking an Exit

We've now set up the static parts of the Exits, but haven't really thought about what happens when a Player tries to go through one. First of all, can they go through the Exit at all? This may sound silly, but things like a toughened glass window are pretty hard to get through - yet, with an Exit, you can see what's on the far side. And, even if you can get through, what do you need? A hammer? A key?

Access through an Exit is controlled by the Exit's lock. Look in the online help for @lock for the kinds of things you can do with locks. For now, let's just note that you can lock an Exit to any logical expression involving bits of the game. Since we want to be able to get through the window (a quick route to the garden while we're building things), but we don't want anyone else to, we can lock the Exit so that we're the the only object that can open the lock:

@lock window = me
Locked.

This says that if anyone other than us (that's the me in the command) tries to use the Exit, they'll fail.

If you want to unlock an Exit, use @unlock:

@unlock window
Unlocked.

Messages when you use an Exit

When someone tries to use an Exit, the Exit's lock is checked. One of two things can happen:

Creating Things

Odd Things

Locking Things

Messages when you use a Thing

Containers

Making your own commands

The text below here still needs rearranging. It's garbled and, in some places, incomprehensible. Don't bother looking. No, really, don't.

Simple Commands

TODO: Erm, I'll fill this in afterwards

Success and Failure

Success is of course the opposite.

Changing Player ID

TODO: See @chpid and @unchpid for the moment.

Automatically executed commands

.login

This is a command that will be executed whenever you logon to the game, it must be on you, in an object you are carrying, or in the room that you are in. This is the only special thing about it, otherwsie it executes the sames as any other command. If there is another command in the area called ".login" then this will execute as well as your own one, afterwards.

.logout

This is similar to .login except it executes on QUIT from the game.

.enter

This command is executed whenever a person enters a room or area. All .enter commands are fired all the way up the area tree.

.leave

This command is executed when a person leaves an area. As with .enter they are fired all the way up the area tree.

Variable referencing

"drop Variable = Object" will attach a variable to an object. To attach it to a room type "drop Variable". To get a variable back you must specify its full name, ie "get the-thing:fred".

You can construct variable names out of expressions involving other variable names by surrounding the constructed name with braces (`{' and `}'). Braces can also be used when a colon just after a reference would otherwise screw things up. NB - Anything within {...}'s is executed as a command, therefore use "{@?desc var", rather than "$var"

Command parameters

All of the parameters will stay the same through csuccess and cfail links except for $0 which changes whenever you execute a command. If you call a command by name then the parameters are all reset to new values. Return Parameter $0: This is set to the return value from the last command executed. It can be used in the next command. Example: >> @command openlink=@dig \$2\ >> @open \$1 = \$0 >> openlink North;n = My new room wot I dug with openlink First input parameter $1: This is set to the first argument to a command. It is not set outside a command. The first argument is the bit between the command name and the first `=' sign. Example: >> @command yell=:yells "\$1!" >> yell hello Joanna yells "hello" Second input parameter $2: This is set to the second argument to a command. It is not set outside a command. The second argument is the bit after the first `=' sign, up to the end of the string. Example: >> @command tell=:tells "\$2" to \$1 >>tell fred=Hi there. Joanna tells "Hi there" to fred Combined Input Parameter $3: This is the first and second input parameters all rolled into one (with an equals between them). It is useful for the lasy people of this world ie me! it allows the passing of the whole command line at the same time, to make short forms of commands. Example: >> @command wh=whisper \$3 >> wh fred=Hi there.

Using Queries

TODO: Urm you sort of use them.

Embedded Newlines

It is possible to embed NEWLINEs in descriptions. To do this, prefix the NEWLINE with a backslash. A backslash can still be generated by prefixing it with two other backslashes. eg.: >> @describe object=Here is a backslash:\\And here is a...\ >> new line. Here is a backslash:\ And here is a..." new line."

Drop-To's

When the "@link" command is used on a room, it sets a dropto location for that room. Any object dropped in the room will go to that location. If the room is set to be STICKY, the effect of the dropto will be delayed until the last player leaves the room. The special location `HOME' may be used as a dropto, as in "@link here = HOME"; in that case objects dropped in the room will go to their homes. "@link = #" "@unlink "

Alarms and Fuses

An alarm is set on a command to make that command execute automatically at a certain time(s) during the week, or an amount of time into the future, relative to the time when the alarm is set. Syntax: "@alarm = s m h d" "@alarm = + s m h d" ----------------------------------------- The first form sets an alarm to go off at the same time each week, days are numbered from 1 to 7, Monday is day 1. If you enter a `*' in any field then the alarm will execute for any value of that field. ie `0 0 9 *' is the alarm for opening the bank. The second form causes the alarm to execute only once, the amount of time that you specify into the future.ie `+ 0 0 1 0' causes the alarm to execute one hour into the future. To get the alarm to actually do something you have to set a csuccess on it to the command that you want to execute when the alarm goes off. Once an alarm has been created its value can be reset using "@desc". To turn an alarm off just describe it to null. This command is Wizard-only due to the amount of processor time that alarms use. Syntax: "@fuse " ---------------------- Creates a fuse called "". The name is useless for all practical purposes; it just serves to identify the fuse. Whenever a fuse is triggered, its value (stored in its description) counts down by 1. If the value is non-zero, it executes any command linked to its cfail. If the value is 0, the value is re-loaded from the fuse's `drop' field and any command attached to its csuccess is executed. Fuses trigger when attached to different objects. Attaching one to a player will cause it to trigger each time the player types a command; to an exit, each time the exit is used; to a thing, each time the thing is picked up or dropped; and to a room, each time player types a command in that room. After creating a fuse, you set its description equal to the value t at you want the counter to start at. You then also set an "@drop" on it, ie:- "@drop =" This is the value that will go back into the fuse after it has gone BANG. Then all you have to do is set a "@csuccess" on the fuse for the command which should be executed when the fuse goes BANG, ie the counter reaches 0, and a "@cfail" for each time the fuse is activated, but doesn't go BANG, ie it just `ticks'. "@fuse my-silly-fuse" "@describe my-silly-fuse = 20" "@drop my-silly-fuse = 10" "@csucc my-silly-fuse = {@command fsucc = @silly :wibbles loudly}" "@cfail my-silly-fuse = {@command fsucc = @silly :wibbles quietly}"

Credits

Originally started by The Ozzard of Wiz, sometime around late 1991.
Modified by ReaperMan.
Added to by a cast of tens. Thanks to ReaperMan, Flup.
Converted to HTML (XHTML 1.0) by The Ozzard of Wiz, March 2002 (ten years on!).
Extensive reworking by The Ozzard of Wiz, March-April 2002.