> Valhalla MUD - The Beginner's Tutorial

The Beginner's Tutorial:
Version 3.0

The Beginner's Guide to coding on Valhalla MUD


Original Author
Revised (July 96)
Latest Revision (July 98)
Andrew Cowan (Icculus)
Ryan Holliday (Kira)
John Clare (Eirinn)
Version 1
Version 2
Version 3

 
INDEX
Introduction
Compiling Your Zone
Creating Your First Zone
The %zone Section
The %rooms Section
The %mobiles Section
The %objects Section
The %reset Section

Introduction

This Guide is a tutorial designed to introduce area (zone) building for the Valhalla MUD Engine. In addition to this document you will want to look at the other available docs which can be obtained via ftp at both ftp.valhalla.com and blinksoft.com (the site of the official VME Test site).

Anyone can write a zone and this guide attempts to introduce area building by creating a tiny sample world (with 2 rooms, 2 mobiles and 4 objects) with many added comments to show a generalization which could be applied to your ideas. Any suggestions/comments/error reports should be sent to Eirinn.

Icculus (Andrew Cowan) is the original writer of this document, although Cabal (Brian Clark), Papi (Michael Seifert), and Dethe (Tom Martin) have also influenced its creation in one way or another. Version 2 was a revision of Andrew's work by Kira (Ryan Holliday), and this third version has become necessary due to the advancements and changes to the VME Engine since version 2 of this document in July '96.


Compiling and/or Uploading Your Zone

As you write your zone, you will probably wish to see how it is shaping out and the best way to see any potential problems and get the feel of your zone is to compile it. The compiler takes your text code and converts it to something more digestible to the MUD, and then, once you've restarted the MUD, you can walk around it, provided of course your zone compiles without errors.

The Valhalla MUD test site and its compiler are available to all builders 24 hours a day, 7 days a week. The Test Site itself is accessed by telnetting to blinksoft.com port 4242, and the compiler can be accessed via anonymous ftp at ftp://blinksoft.com/vme/in or via email at mudcomp@blinksoft.com. It is a good idea to get used to the email compiler - it really is the handiest way to compile a zone both on the test mud and Valhalla itself. If you have Linux on your PC, you might find it even better to download your own little Valhalla MUD Engine from here.

(NOTE): This tutorial assumes you have access to the internet and either email or an ftp-daemon. It also assumes you know how to use ftp to send and retrieve files over the internet. If you do not you will of course need to get either an instructional internet manual or find someone to help you. If you intend to compile via email, make sure the zone file is not encoded in any way - ideally it should be the body of the email.

Before you will be able to use the test mud you will need a password and an account, which can be granted by Eirinn or Saor on the real MUD. Once this account is granted you will have full access to compile, test, and explore your zone on the test site.

(BTW): The Valhalla zone compiler is an actual compiler, very much unlike Diku I based muds which view zones through an interpreter during runtime.

Zone File Header: Perhaps the most important part of your zone file is the header. The header goes before anything else in your zonefile and must be enclosed in comment markers like the example below. Whether you use the email compiler or the ftp compiler, the format of the header file which you use to send the compiler your file details will always be this:

/*
filename    seren
password    zolan
changedby   Eirinn
EmailAdd    Eirinn 
request     compile
version     10
END HEADER*/

Filename is the name before the .zon of your zone file. In this case my zone file is seren.zon, and the filename is therefore seren. My password is zolan. Changedby is usually the last person to modify the zone, and this is followed by the email address of that person. Request tells the MUD what you want it to do with your zone - in this case, compile it. And version records the version of the zone (this is ignored on the test mud).

FTP Procedure: When you log on to the ftp site (username anonymous, password is your email), upload your zone to the /vme/in directory. It then gets fed through to the compiler. A successful compilation will create two files, filename.reset and filename.data. These files are linked in with the mud code at runtime and cannot be changed until a modification is compiled and the mud is rebooted, or crashes. Whether compilation is successful or not however, the compiler creates an error file, and if you ftped your zone to the compiler it will be placed in the /vme/out directory, or if you emailed it, the compiler will send the error file in an email to you.

Email Procedure: When compiling by email (which is probably the most convenient method because it involves least effort), the file is prepared just like an FTP zonefile, but instead we email the zone to mudcomp@blinksoft.com in the case of the test mud, and valcomp@valhalla.com in the case of the real mud. It's important not to encode the zone when you send it (email uses 7 bit methods to send information to others, which means that it misses out every 8th bit in 8 bit files. 7 bit takes into account the ASCII character set, and this suits our zone fine since it's just plain text. However, some mail programs encode files attached to an email, automatically - this means that instead of getting a nice plain text zonefile, the email compiler gets gobbledigook instead). Simply paste the zone into a blank email as the body of the message, or make sure your mailer doesn't encode it if you just attach it. I (Eirinn) personally use unix all the time and I simply type "mail mudcomp@blinksoft.com < seren.zon" to compile my zone on the test mud - I find that method a hell of a lot simpler than ftping the zone.

Once your zone is compiled, the compiler then sends you the error file (see above) direct to your email address.

All first time builders are required to take the Builder's test. This tutorial will show you how to do 95% of what is required by the Builder's Test. All rooms/descriptions/etc should be in line with the Formatting guidlines (these are mainly tips, pointers and advice on how to write good zones) - Saor, the Administrator in charge of new zones, uses these to judge whether zones are up to standard to be put on the actual MUD, so it's a good idea to read through them. You should also keep your objects and mobiles (monsters) within the Limits set down by Palio. If you have questions regarding zones, contact Saor, or if it is a limits question, Eirinn.

When your zone is bug free and approved to go on the mud, you will be given a password and appropriate header file for your zone (identical to the email compiler header format on the Test Site, but all fields are taken into account on the real mud, particularly the version number - see above on for what this looks like). You can then use these to put your zone file on the actual MUD.

(NOTE): If your recent compilation results in any errors, it will not replace the currently working zone, meaning that there is no way that errors can be mixed in to the MUD by accident. And remember, for your zone to be part of the mud, the mud must reboot, whether it is the test site or Valhalla itself.

Error Files: We get a lot of questions from new builders regarding the errors that are detailed in the error file you receive after compiling your zone. The most commonly encountered errors are missing quotation marks ", missing semi-colons ; , missing brackets ( or ) , and missing braces { or }. For example, ".8529.c:3955: unterminated character constant" means that on or before line 3955 of my zone (excluding the header), I have forgotten to put in a ". The line number will usually be quoted as the second number in each error detailed in the error file. Sometimes the compiler doesn't pick up on the error immediately, so the line number might be a few lines after the actual error. .8529.c is the name of the c file which the compiler was using when compiling that piece of code in which the error is found. Another example: ".8917.c: 3976: parse error (And on the Next Line of the error file:) Token: 'exit'" - this means that on or around line 3976 I have forgotten a semi-colon (a ; ). You'll find that 99% of the errors you have will be like the ones I've just mentioned. The language the error file uses to describe the errors can be somewhat intimidating to non-native english speakers but my (Eirinn) policy when correcting errors is not to worry too much about the actual words, just the line number because once I see the line, the error usually sticks out like a sore thumb!


Creating Your First Zone

Ok, so the rest of us want to see how to put together everything the other docs say into one working zone! In addition to this tutorial, you will probably also want to have copies of the files vme.h (a file which contains basic definitions for the mud and which should only be modified by an administrator, if at all - some of you may remember vme.h as part of values.h, but for ease of conversion, management and compatibility, values.h was cleaned up and split into vme.h and values.h. Chances are that though the vme.h files may be the same between two VME muds, the values.h will be different as this is the file that is modified when new spells and other additions come into a mud), values.h (similar to vme.h, but this contains things like RACE_XXX defs, and new CMD_XXX definitions - this file is the file to modify if adding a new spell, or command, but you must obtain authorisation from an admin before doing so), composed.h (this file contains many race statistics and should be considered as a quick way to set up a common monster, saving you the trouble of setting its stats, level, etc), dil.doc (this document is probably the most used doc in the archive - it contains information on all of the dil constructs, functions, etc, and many examples of how to use them), and wmacros.h (wmacros contains the macros for declaring mob stats [MSET_SPELLS, etc], shields [SHIELD_DEF], drinking containers, ranged weapons, etc, and it is always useful to have a look through it - it could save you a lot of trouble) available.

We will now create a tiny zone with just a couple of rooms, mobiles and objects. The idea is that you see the basic format of any zone so you can use information contained in the other docs to apply this format to your ideas!

(NOTE): Every zone is made up of 6 sections:

  1. %zone - Defines zone name and other zone-specific information.
  2. %dil - Any special dil routines which you want to create for the entire zone go here. The concepts behind having this section are dicussed here, but if you wish to get a better grasp of what dil is you'll need to look at the DIL Quest Tutorial, and for a more technical approach, looking at each command, dil.doc. Currently, a DIL tutorial which encompasses more than just dil quests is being written and should be finish shortly after this version of the beginners tutorial is online.
  3. %rooms - The room definitions are here.
  4. %mobiles - The mobile (monster) definitions are here.
  5. %objects - Objects are defined here.
  6. %reset - (Important) Defines the way in which everything in the zone resets and how (mobiles & objects) get loaded into their assigned rooms.

Tiny_Zone

(NOTE): Comments are added in C style, with a /* to indicate the start of a multiline comment and */ to indicate the end. Everything that follows this section will be actual zone file contents, except for the comments.

(NOTE): Perhaps the most important part of your zone file is the header. If you are using the ftp compiler on the test site, this will be of the format:

/*
filename seren
password zolan
changedby Eirinn
EmailAdd eirinn@valhalla.com
request compile
version 109
END HEADER*/

Filename is the name before the .zon of your zone file. In this case my zone file is seren.zon, and the filename is therefore seren. My password is zolan. Changedby is usually the last person to modify the zone, and this is followed by the email address of that person. Request tells the MUD what you want it to do with your zone - in this case, compile it. And version records the version of the zone (this is ignored on the test mud).

/* ****************************** */

/*
filename tiny
password tiny1
changedby Eirinn
EmailAdd eirinn@valhalla.com
request compile
version 1
END HEADER*/

#include
%zone tiny_zone
title "The Tiny Zone"
lifespan 20
reset RESET_ANYHOW
creators {"icculus", "kira", "eirinn"}

notes "What can I say but this will be short and probably not a very fun zone to adventure in! Send all complaints to: Andrew Cowan agcowan@turing.uncg.edu."

help "My, what a tiny zone you're in! Beware the death room, it's been said that visitors to this room often find things mildly uncomfortable."

/* ****************************** */

/*
/*filename ....*/
This is the compiler header format - see the compiling section for an explanation of this.

#include
This command is required for zones and will tell the compiler that you want all of the information contained within the composed.h doc to be applicable to your zone. Composed.h is a header file which contains definitions for previously defined mobiles which you will need for your zone.

(NOTE): The composed.h file has three #include calls within it, one for values.h, vme.h and another for wmacros.h. These two files contain very important definitions and must be included in your zone! If you have no need for including composed.h, then you must include the other two explicitly.

%zone tiny_zone
The above does two things. %zone is a label that tells the compiler that you are defining information for the zone section of your zone. The first string that follows this label is your zone name. The zone we are creating will be called tiny_zone. This name is important because everything in the zone can be referenced as object@tiny_zone. Please use lower case characters for your zone name as upper case is slightly more difficult to deal with.

(BTW): It is recommended that as a convention you use your zone name as the zone filename with a .zon extension. So for our zone, we would name this file tiny_zone.zon.

title "The Tiny Zone"
The title command merely tells the mud what name to report for the zone for players using the "areas" command. One thing to remember, if you create a zone that takes more than one zone file, for example tiny_zone1 and tiny_zone2, use the title command for only one of the two zones. Doing so will prevent your zone title from appearing twice when the "areas" command is used. If you're wondering how large a zone should be, it's generally 70 to 100 rooms per zone file. If you're zone is more than a few rooms above 100, please split it into multiples.

lifespan 20
The lifespan call simply defines the zone life for tiny_zone. In this case tiny_zone wants to reset every 20 minutes.

reset RESET_ANYHOW
The reset call defines how this zone reset is made. In our case we will reset every 20 minutes regardless of anything else! The options for reset are:

  1. RESET_ANYHOW -- Resets as often as specified by the lifespan call, no matter what else is going on.
  2. RESET_NOT -- Resets only when the mud is rebooted.
  3. RESET_IFEMPTY -- Resets only if the zone is empty.

(NOTE): Generally the only zones which reset quickly are newbie zones. It is recommended that a zone reset time of at least 20 minutes is used, If you need to make an exception please let us know, and explain why a quick reset is important.

creators {"icculus", "kira", "eirinn"}
Believe it or not, the format of this is important also! The names must be in lowercase or the correct names will not be registered. There are certain objects available to immortal designers which help debug and modify areas to meet player suggestions. These objects make sure the person using them is one of the names in the creators field, so make sure you use all lowercase, and add everyone who had a part in it!

(NOTE from Eirinn): Please don't use control codes in the creators field (ie colours) because the compiler will think the codes are part of the creator's name and won't recognise him when he attempts to use one of the objects mentioned in the last paragraph.

notes "blah blah blah..."
Whatever is put within the quotation marks after the 'notes' line is information that can be accessed only by immortal characters using the wstat command. The notes section is a good place to put your e-mail address and other information which other zone builders should know.

help "blah blah blah..."
The information put within the quotation after the 'help' line is information that players will see when they are in your zone and type 'help'. Try to include a brief overview of your zone here, as well as anything else you think players should know about your zone.

(NOTE from Eirinn): Players find it very frustrating when they type help and none is available, so please make use of help to give any information players should know, even your email address.

(NOTE): The room, mobile and object definitions which follow were originally written using Icculus' specific style (With exception to Tiamat which is Chris Armstrong's style), and slightly modified by Kira. There is a great deal of flexibility involved here and you can make up your own format for definitions. The only thing of importance here is that you start every definition with its symbolic_name (on its own line!) and end the definition with the word 'end' on a line by itself. Version 3: The code here was changed quite a lot by Eirinn, where changes and advances made it necessary to modify Icculus' and Kira's code. There are also a lot of additions to illustrate the new features.

*/
/* ****************************** */

%rooms

cluttered_room
names {"cluttered room"}
title "A Cluttered Room"

descr
"This room is very cluttered, in fact it's so cluttered that it's difficult to find an empty place to stand! Scattered all about the room are various maps made recently by explorers, as well as assorted trinkets from around the globe. Through the exit to the north, Midgaard stands proudly. There is a strange hinge in the floor between two maps here."

extra {"various maps", "maps", "map"}
"Newly received information allowed for these maps to be made. Though many died to ensure safe transport of this information, the contents will prove their value in time!"

extra {"assorted trinkets", "trinkets", "trinket"}
"All sorts of neat stuff it seems, forming a wondrous plethora of fun looking toys. It sure brings back the days when life was easier!"

extra {"hinges", "hinge"}
"Looks like there may be a hidden exit here! Could this be a trapdoor?"

extra {"$leave_s", "d"}
"You carefully drop down through the trapdoor."

extra {"$leave_o", "d"}
"$1n carefully drops down through the trapdoor, making as little noise as possible."

flags {UNIT_FL_INDOORS, UNIT_FL_NO_WEATHER}
movement SECT_INSIDE
north to market_sq@midgaard descr "The amazing city of Midgaard is there";
down to death_room open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN}
key death_key keyword {"trapdoor", "door", "hinge", "floor"}; SECRET_DOOR_DIFFICULTY(DOWN, 10)
ALWAYS_LIGHT
end /* cluttered_room */

/* ****************************** */

/*
%rooms
Like the %zone label, this label tells the compiler that we are going to define the rooms in this section of the program.

cluttered_room
This name will be the symbolic name of the room that we just made. It is important that the first line of a room definition has this symbolic name on a line by itself. To refer to this room in any dil program or on the mud you can use the symbolic format. That is, for this room, cluttered_room@tiny_zone is the way to refer to it. For dil afficienados, "cluttered_room" is the nameidx field of the room and "tiny_zone" is the zoneidx. "findroom(cluttered_room@tiny_zone)" will create a unitptr which lets you manipulate the room in dil.

names {"cluttered room"}
This command defines the name of the room that would be used if you were, for example, trying to teleport to the room. This field is not required, and can be left out unless you feel that the room is in some way special, that is, rooms that will be well travelled. If you wanted to define more than one name for this room, you could do it in the following manner:

names {"cluttered room", "messy room"}

Thus, this room could now be teleported to using either 'cluttered room' or 'messy room' as the keyword. Gods can also use these names with the 'goto' command, which believe me is much nicer than using the symbolic format repeatedly.

(NOTE): You should follow this simple convention for name-lists: Put all names which are a subset of others later in the list, following their superset. For example, in a room named 'The Room of Light Magic' the namelist could look like this:

names {"room of light magic", "room of light", "room of magic"}

It may not seem important, but due to the way namelists are searched it does turn out to be.

title "A Cluttered Room"
The title is what players see as they enter the room. The title acts like a room name as far as mortals are concerned so keep this in mind before choosing obscure titles!

descr "blah blah blah..."
The descr is what you will see when you walk into a room (provided you aren't in brief mode). This description is basically the room layout, or as much of it as is given to the mortals inside. Room descriptions are possibly the most important aspect of any zone, for no matter how great the equipment is inside, if the room descriptions are not well thought out, the players lose interest and the zone loses its link!

extra {"blah-blah blah", "blah-blah", "blah"}
The extra descriptions are used in conjunction with the room description. If you describe something within the room description, you MUST make an extra description for that item. I warn you, this is very, very tedious for large zones, but the logic is simple to see why they must be there. If I enter a room and the description says 'There is an ugly rug in the corner.', chances are I will type 'look rug' to get a closer inspection. If there is not an extra description defined for the rug, the mud will tell me 'You do not see that here' when it just told me it was there a second ago! So there must be an extra description defined for everything mentioned in room descriptions.

(NOTE): As with name-lists, all items in an extra description which are subsets of other items should be put later in the list. For example, if you want to create an extra description for 'various maps' you might do it as follows:

extra {"various maps", "maps", "map"}

(NOTE from Eirinn): Some extras are special, and these are known as the Extended Extra Tags set. They let you change the default messages people see when they do certain things. In this case, I've shown how you can change what messages are sent when someone leaves down through the secret trapdoor in cluttered_room, simply by adding the following:

extra {"$leave_s", "d"}
"You carefully drop down through the trapdoor."

extra {"$leave_o", "d"}
"$1n carefully drops down through the trapdoor, making as little noise as possible."

(NOTE): The "$leave_s" extra is the text displayed to "self" - the person actually doing the action of moving down through the trapdoor. The "d" stands for the direction which should trigger this message, in this case, down. The "$leave_o" is analgous to the "$leave_s" message, but it is shown to others in the cluttered_room as the player leaves down. There are a variety of these extras and they are very handy for customising your zone. My favourites are the wear, get, drop and remove extra tags which let you change what people see when they perform these actions on a certain item of equipment for example. These and the rest are detailed in the Extended Extra Tags set document.

flags {UNIT_FL_INDOORS, UNIT_FL_NO_WEATHER}
Several flags for rooms are defined in vme.h. Flags on rooms act as little extras to make our rooms more interesting. Our room will be indoors, and will not give players information about the weather. Some flags which you can use are:

  1. UNIT_FL_NO_TELEPORT -- Prevents teleporting to/from the room.
  2. UNIT_FL_NO_MOB -- Prevents wandering mobs from wandering into the room.
  3. UNIT_FL_NO_WEATHER -- Players in the room won't get weather information. Use this flag on indoor/underground rooms.
  4. UNIT_FL_INDOORS -- Set this flag if the room is not an open-air room, such as a cave or in a building.

movement SECT_INSIDE
This line tells the mud how much endurance each move should cost when leaving the room. There are many to choose from although some appear to be disabled. The complete list of sector types is in vme.h and you can try them all. If the compiler gives you parse errors on any sector type, it means it is disabled and you should try another. Here's a partial lists of sector types that are available:

  1. SECT_CITY
  2. SECT_FIELD
  3. SECT_FOREST
  4. SECT_MOUNTAINS
  5. SECT_SWAMP
  6. SECT_WATER_SAIL -- A boat is needed to move in this type of room.

north to market_sq@midgaard descr "The amazing city of Midgaard is there";
This line is the standard method of defining a room connection from one zone to another. In this case, going north will take you from cluttered_room@tiny_zone to the market square of Midgaard. If you wish to connect a room in your zone to an existing room of some other zone, you will need to find out its symbolic name and reference it using the format shown (room_name@zone_name). To connect rooms that are in the same zone you can simply use the symbolic room name. For example, if we were connecting a room within tiny_zone to cluttered_room, we might write:

east to cluttered_room descr "A very messy room is there.";

The descr which follows this connection definition is a description that will be seen when someone in the room types 'look east'. You should always include these directional descriptions when building your zone.

down to death_room open {EX_OPEN_CLOSE, EX_CLOSED,
EX_LOCKED, EX_HIDDEN}
key death_key keyword {"trapdoor", "door", "hinge", "floor"};
SECRET_DOOR_DIFFICULTY(DOWN, 10)
These three lines describe just one thing, a hidden trapdoor which leads down to a room with symbolic name death_room. The key things to notice are the open flags, the keyword section, and only in cases of hidden doors, the level of search required to find this door.

The open flags are what tells the mud that the exit is in fact a door and, in our example, we also make it closed, locked, and hidden on reset (means players must search to locate it). EX_OPEN_ClOSE defines a door, EX_CLOSED and EX_LOCKED tell the mud to close and lock the door on reset, while EX_HIDDEN tells the mud that this door should be hidden to all players who haven't searched and found it.

The 'key death_key' line means that only the key with symbolic name death_key will unlock this door. A key is not necessary for doors (since many can pick locks or cast unlock) but if you wish, you can define one with 'key key_name' which is specific for the door. We must now remember to write the definition for the death_key, which will be done in the %objects section. To make a door pickproof, set the EX_PICKPROOF flag on it.

The list of names under 'keyword' defines the things that a player can search for to successfully find the door. For doors that are not hidden, this list acts like a namelist and defines what the player can look at to see the door.

(NOTE): For doors that are not hidden, a descr "blah blah" must also be added so that the command 'look door' will yield results. For example:

east to death_room open {EX_OPEN_CLOSE}
descr "There is a door here." keyword {"door"};

Because our door is hidden, the description has been left out. The keywords then become the list of things a player can search for to find the door. The first name in this list defines what the player will see if they do in fact find the door. For example, if I type 'search hinge' and am successful, I will receive a message saying 'You discover a hidden trapdoor'. Additionally, a comment from Papi is that with all secret exits, you should include the surface which the exit is located on within the keyword list, ie floor, wall, ceiling, etc. should be one of the keywords.

The SECRET_DOOR_DIFFICULTY specifies the exit direction (in case of more than one hidden exit) and the 'skill level' required to search out the exit, in our case level 10. This does not mean players below level 10 cannot search here, it means players with a search skill comparable to level 10 have a good chance at success. Remember it only takes one successful search so really anyone can get lucky and find the exit, but levels 10 and up can do it consistently.

ALWAYS_LIGHT
This line defines the light for the room. In this case, the room will always be well lit. If this line is left out, the room darkness will be determined by the MUD based on time of day and whether or not the room is inside or outside.

end /* cluttered_room */
End defines the end of the room. The additional comment, signifying which room was just defined, has been added for aesthetics.

*/

/* ****************************** */

death_room
names {"room of death", "death room"}
title "The Room of Death"

descr
"The stink is so deep, it seems to take on a life all its own and it is actually visible! Carcasses lay scattered about like so much rubbish, and splintered bones are arranged in a haphazard fashion all about the room. There looks to be some sort of nest in the corner of the room."

extra {"stink"}
"Yes, it can actually be seen - this smell is so powerful!"

extra {"carcasses", "carcass", "corpse", "body"}
"There are many, all perished in truly horrid ways! Some are missing limbs, most appear chewed, and you notice charred flesh remaining on a few such corpses. Definitely looks like a dragon's work."

extra {"splintered bones", "bones", "bone"}
"Something was very hungry for there is very little remaining on most of these bones, even the marrow looks to have been sucked out!"

extra {"corner", "nest"}
"This is definitely a nest here, and from what you can tell, the owner is very large!"

flags {UNIT_FL_INDOORS, UNIT_FL_NO_WEATHER}
movement SECT_INSIDE
up to cluttered_room open {EX_OPEN_CLOSE, EX_CLOSED}
descr "There is a door here." keyword {"door"};
special SFUN_DEATH_ROOM "100" time WAIT_SEC*20
end /* death_room */

/* ****************************** */

/*
(NOTE): Since much of the coding for this room is the same as what was explained for cluttered_room, only the new ideas that are here will be discussed.

up to cluttered_room open {EX_OPEN_CLOSE, EX_CLOSED}
descr "There is a door here." keyword {"door"};
As was described for cluttered_room, this is the way to make a door that is not hidden. Since anyone who is in this room would have obviously already found the hidden door, we do not make this door hidden, thus saving players the trouble of having to search for a door that they've already found. Things to notice about the description of a door that isn't hidden are:

  1. The EX_HIDDEN flag is not set.
  2. A descr of this door has been added, allowing players to 'look door'. Additionally, if you open or close the door you will get the message 'You open the door.' If you wanted to make a gate instead of a door, you could change the descr and set the first keyword to "gate". When you opened the gate you would then get the message 'You open the gate.'

(NOTE): You should take CAREFUL notice that every directional exit statement must end with a semicolon (;). I have found that about 80% of the parse errors I get from zone compilations are due to either forgetting a semicolon, or forgetting a " in an extra description.

special SFUN_DEATH_ROOM "100" time WAIT_SEC*20
OK, this line is a call to a special assignment. There are many of these, check in vme.h to see a full list. Special assignments can be used for rooms, mobiles, and objects. The SFUN_DEATH_ROOM special says that this room will be a death trap, and we specify 100 as the number of hitpoints to be deducted. However, please note that this is actually 10.0 hitpoints... to take off 100 we would have to use the value 1000. The 10.0 hitpoints will be deducted every 20 seconds so we are actually giving the players a great chance to escape mostly intact!

Some SFUN's that are fun to use with rooms include:

  1. SFUN_FORCE_MOVE -- To force a player to go to a certain room.
  2. SFUN_DEATH_ROOM -- Deducts hitpoints at specified intervals.

(NOTE): The SFUN_DEATH_ROOM routine will deduct hitpoints from BOTH players AND mobs. Additionally, rooms that cause instant death are frowned upon. Can you say that you would actually LIKE a room that killed you before you had a chance to escape?

(NOTE from Eirinn): We are currently trying to replace all SFUNs with dil code. There are various reasons for this, but one of best is that it is easier for us to control dil programs than base code. To this end, we have replaced one of the most widely used, the aggressive and reverse alignment agressive functions with a much more powerful and flexible dil version which allows very specific types of aggression (eg you can have a nasty dwarf who doesn't like female elves under level 30 if they're not evil). So if you want to use an SFUN, please check if there is a better dil version available first. We don't allow the aggressive SFUN anymore, so please don't use it. See the Mobiles section for an example of the new aggressive function.

The romflags function has been made obselete. All of those flags are now UNIT flags which are accessed with the flags command mentioned earlier. This includes the old romflags ROOM_FL_SACRED - it is now UNIT_FL_SACRED. Similarly, ROOM_NOSAVE is now UNIT_FL_NOSAVE. UNIT_FL_SACRED is typically used to create a sacred room, ie one that gives healing at twice the normal rate (Like the Chicken's rest, Inner Sanctum or the Udgaard Temple). Please don't overuse the sacred flag - sacred rooms should be rare.

flags {UNIT_FL_SACRED}

(NOTE): No light value has been defined for this room, so it should be dark always.

*/

/* ****************************** */

%mobiles
dragon_tiamat

names {"tiamat", "dragon"}
title "Tiamat"
descr "Tiamat, the Queen of all evil dragonkind is here."

extra {}
"Tiamat is the most powerful evil dragon known to exist. Her massive body is topped with the heads of all five of her guardian dragons. Her claws are huge, and her scales are multi-colored. She has come to this place to spawn evil dragons and obviously does not like your presence. In a way, this dragon is very beautiful in all of her splendor, but at the same time, the sheer evil of this beast could make the strongest warrior cower in fear."

level 160
alignment -1000
race RACE_DRAGON_GREEN
sex SEX_FEMALE
height 2650
weight 5300
money 5 GOLD_PIECE
exp 115
NATURAL_DEF(WPN_CLAW, ARM_PLATE)
MSET_ABILITY(18,15,16,19,9,14,9,0)
MSET_WEAPON(4,5,4,4,9,4)
MSET_SPELL(1,1,1,1,1,1,11,20,11,11,11)

dilcopy combat_mag@function("fire breath","",0,1);
dilcopy aggressive@function(0, -1, 0, 10, 1, 20, 0, "ANY", {"$1n attacks $3n!", "$1n attacks you!"});

flags {CHAR_DETECT_INVISIBLE}
end /* dragon_tiamat */

/* ****************************** */

/*
%mobiles
Like the %zone and %rooms labels, this label tells the compiler that we will be defining mobs in this section of the program.

dragon_tiamat
Like a room name, this line is the symbolic name of the mob which we are defining. This name must be on a line by itself. When referring to Tiamat symbolically, we can now refer to dragon_tiamat@tiny_zone.

names {"tiamat", "dragon"}
Just like the room names. These are useful for teleports or gotos.

descr "Tiamat, the Queen of all evil dragonkind is here."
This description is what a player sees when he/she walks into a room.

extra {} "blah blah blah..."
The 'extra {}' line is a way of allowing players to 'look tiamat'. Whenever anyone types either 'look tiamat' or 'look dragon', they will see this description. The fact that there is nothing between the { and } signifies that it is an extra description on the entire mobile.

level 160
Self-explanatory. Tiamat is a level 160 mob. Not for newbies...

alignment -1000
This is the alignment of Tiamat. -1000 is as evil as a creature can be. -350 to 350 is neutral, while 350 to 1000 is considered good.

race RACE_DRAGON_GREEN
This is the race of Tiamat. values.h contains the complete list of possible races.

(NOTE Added by PAPI) If you encounter a race which is non-existant, please add it yourself by using "#define RACE_LOBSTER nnnn" where nnnn is a number that is UNUSED in values.h for RACE_XXX. Then later the administrators will insert it into values.h. At that point you will get a "warning: ... redefined". When this happens, simply erase your own definitions as they are now a part of values.h.

sex SEX_FEMALE
Hopefully this won't need to be explained to you (*grin*) There are three sexes to choose from:

  1. SEX_FEMALE
  2. SEX_MALE
  3. SEX_NEUTRAL

height 2650
The height of a mob will take some getting used to unless you are a wiz with the metric system. Height is in centimeters, so Tiamat will have a height of 2.65 meters, or about nine feet.

weight 5300
Weight is given in pounds. Weight will have an effect on the maximum damage that a mob can do using a natural attack (such as fist or claw).

money 5 GOLD_PIECE
We load her with 5 gold pieces on every zone reset.

(NOTE) There are several guidelines for money, experience bonuses, armour types, and many other items which MUST be followed for your zone to be approved. The full list is available in limits.txt.

exp 115
Players who kill Tiamat will receive 115% of the normal experience Thus, killing Tiamat will give you a 15% experience bonus versus what you would get from killing a lvl 160 mob without an experience bonus. There are some guidelines for this that you must follow which you can read about in limits.txt.

NATURAL_DEF(WPN_CLAW, ARM_PLATE)
This line defines the mobile's natural attack and defense types, which figures into battle accordingly. The natural attack type will specify which battle messages get sent, i.e. for a natural attack type WPN_CLAW we can expect to see messages like 'Tiamat slashes you with her claws', rather than something which would make no sense like 'Tiamat pounds you with her fists'. The various possibilities for natural attacks are all listed in values.h. Some of the more common ones are:

  1. WPN_FIST
  2. WPN_BITE
  3. WPN_CLAW
  4. WPN_STING

The natural armour type determines how tough the mobiles' skin will be, ie what type of armour is best comparable to her skin. She is a dragon, dragons have scales and since we want her to be rather 'thick skinned', she deserves the best, namely ARM_PLATE. The possible values for natural armour are:

  1. ARM_CLOTHES -- The weakest of the five.
  2. ARM_LEATHER
  3. ARM_HLEATHER
  4. ARM_CHAIN
  5. ARM_PLATE -- The toughest of the five.

MSET_ABILITY(18, 15, 16, 19, 9, 14, 9, 0)
MSET_WEAPON(4, 5, 4, 4, 9, 4)
MSET_SPELL(1, 1, 1, 1, 1, 1, 11, 20, 11, 11, 11)
The MSET_ listings are what tell the mud exactly what Tiamat's stats are going to be. The numbers in MSET_ definitions define the following abilities, weapon skills, and spell skills:

MSET_ABILITY(str, dex, con, hpp, bra, cha, mag, div)
MSET_WEAPON(axe_ham, sword, club_mace, flail_pole, unarmed, special)
MSET_SPELL(div, pro, det, sum, cre, min, hea, col, cel, int, ext)

Please note that the total of all abilities MUST add up to exactly 100, and the total value for weapon skills and spell skills COMBINED must also add to 100. These numbers are interpreted internally along with the mob's level to determine the mob's actual stats. A value of 20 in any skill/ability on a 200 level mob will correspond to an actual skill/ability level of 200. Similarly, a 20 skill/ability on a 100 level mob will correspond to an actual skill/ability of 100.

The MSET_ definitions as well as all of the other information needed to create a mob is explained in greater detail in the monsters.txt doc. Please check that doc if you have any questions.

(NOTE) In composed.h are the definitions of many, many types of mobs. Thus, if you do not feel like programming the MSET_'s, NATURAL_DEF, alignment, etc., you could simply use a pre-defined macro. For example, we could replace all of the lines from 'level 160' through 'MSET_SPELL' with the following line:

M_DRAGON_GREEN(160, SEX_FEMALE)

This call would do exactly the same thing as the twelve lines which we entered by using the information contained in the M_DRAGON_GREEN macro in composed.h (The level 160 and sex SEX_FEMALE serve as arguments here, telling the mud that we want a female, level 160 green dragon).

In general, we are trying to slowly add a steady base of macros to the composed.h file so try to get into the habit of using what is already defined whenever possible.

dilcopy combat_mag@function("fire breath","",0,1);
dilcopy aggressive@function(0, -1, 0, 10, 1, 20, 0, "ANY",
{"$1n attacks $3n!", "$1n attacks you!"});
These two commands are examples of special functions you can use in your zones to bring life and special abilities to your mobiles and objects. In this case, these two commands define a breath weapon for Tiamat (you can make her heal herself as well as cast spells [at the same time] using the combat_mag function), and also tell the mud that we want her to randomly attack anyone who is in the room with her, as long as they are over level 10, checking to see if anyone is present every twenty ticks. Please note you must use dilcopy and nothing else (the old special DILCOPY does not work anymore).

Other special functions are listed in function.zon. A few of these include:

  1. dilcopy wander_zones@function({"halfzon", "haon_dor"}, 5, 1); -- This makes the mob wander the zones halfzon and haon_dor, changing room every 5 seconds and opening doors if they block the way.
  2. dilcopy shopkeeper@function(See function.zon for details); -- Turn a mob into a shopkeeper. You need to define some things like his merchandise and times of opening, etc. See function.zon for details.
  3. dilcopy blow_away@function(180, "A big object vanishes!") -- Make something dissappear after roughly 180 seconds with the message "A big object vanishes!".

Though SFUNs aren't as widely used anymore (mainly because we're trying to phase them all out), the SFUNs in vme.h are handy. Here are the nicest ones:

  1. special SFUN_RESCUE "mob_name" -- Mob will try to rescue specified mob.
  2. special SFUN_TEAMWORK "mob_name" -- Mob will join in a fight when specified mob is also fighting.

flags {CHAR_DETECT_INVISIBLE}
Just like for the room, you can define flags for mobs and items. This flag lets Tiamat see invisible things (including players). The flags list can be found in vme.h. Other useful flags for mobs include:

  1. CHAR_PROTECTED -- The mob will be protected by the law.
  2. CHAR_HIDE -- The mob will be hidden.
  3. CHAR_SNEAK -- The mob will be in sneaking mode.
  4. CHAR_WIMPY -- The mob flees from combat when its hp is low.

end
The 'end' tag signifies that we have finished our definition of the specific mob. The added comment is there merely for aesthetics.

*/

/* ****************************** */

human_sacrifice
names {"human sacrifice", "sacrifice", "human"}
title "A human sacrifice"
descr "A human sacrifice waits here for his death."

extra {}
" He looks very gaunt, almost to the point of starvation. His bones show clearly through the skin and you can tell its been very long since his last meal. There are tattoos all over his arms and legs, all seem to be of a dragon, one which you recognize as the dragon Queen."

M_HUMAN_WARRIOR_SWORD(50, SEX_MALE)
money 1 COPPER_PIECE

/* Dil to make the sacrifice 'sacrifice' himself */
dilbegin sacrifice1();
code {
:init:
heartbeat := PULSE_SEC*20;
on_activation((self.position <= POSITION_SLEEPING) or (self.position == POSITION_FIGHTING), skip);
:start:
exec("emote shifts uneasily, obviously he is nervous.", self); pause;
exec("say My time has come now, pity me not.", self); pause;
exec("ponder", self); pause;
exec("emote prepares to do his master's bidding.", self); pause;
exec("sigh", self); pause;
exec("wave", self); pause;
exec("say I must feed my master Tiamat now!", self); pause;
exec("search trapdoor", self);
exec("unlock trapdoor", self);
exec("open trapdoor", self);
walkto(findroom("death_room@tiny_zone"));
pause;
goto init;
}
dilend
end /* human_sacrifice */

/* ****************************** */

/*
(NOTE): Since much of the coding for this mobile is the same as what was explained for dragon_tiamat, only the new ideas that are here will be discussed.

M_HUMAN_WARRIOR_SWORD(50, SEX_MALE)
This call is a predefined macro in composed.h. Notice that a great deal of coding that was necessary for Tiamat is not needed here. When using these predefined macros, you may override any setting by entering your own values on any line following the macro call. For example, if we wanted the alignment of our human sacrifice to be -800, we could do so in the following manner:

M_HUMAN_WARRIOR_SWORD(50,SEX_MALE)
alignment -800

dilbegin sacrifice1(); ...
Here's a simple dil program which I've named 'sacrifice1'. This program will cause the human sacrifice to talk to you when he loads, and then walk to the death_room. Dil is explained elsewhere, and we'rwe'ree not going to go into it in detail here, but this program is simple enough that it can be easily modified to allow you to create 'talking' mobiles within your zone.

The PULSE_SEC*20 defines how long a pause will last, in this case 20 seconds. So the program will wait for 20 seconds everytime it sees a pause. You can set this number to any value that you want.

The 'exec' command tells the program what we want the mob to do. Effectively, anything we put in the quotes in an exec statement is like a line that you would type in when playing. So if we want the mob to say 'Hello' we use the following:

exec ("say Hello.", self);

Emotes, socials, etc. can be used within exec statements.

The 'walkto' command tells the mob to walk to the specified room.

Finally, the 'goto init' line tells the program to go back to our ':init:' label at the beginning. Thus, if you wanted to make a mobile that just kept talking, you would put 'goto init' at the end of your program, and the program would then go back to the beginning and effectively start itself all over again.

Feel free to copy this program into your own zone... just change the text within the quotes to whatever is appropriate for you. Little extras like these programs are what help to distinguish an average zone from a good one.

*/

/* ****************************** */

%objects

sacrifice_robe
names {"sacrificial robe", "robe"}
title "a sacrificial robe"
descr "A dark black sacrificial robe lies here."

extra {}
"This robe is made of a very fine and delicate silken material. However, you feel uneasy looking at it... the robe seems meant only for those who are preparing to die!"

extra {"$identify"}
"When worn,an enhanced dexterity is attained, but your knowledge of magic will weaken slightly."

extra {"$improved identify}
"When worn, this robe will add 3 to DEX, and reduce DIV by 1. You will also receive a bonus in the war mattock skill."

manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_ABOUT}
flags {UNIT_FL_MAGIC}
ARMOUR_FULL_PLATE(+5, +5)
DEX_TRANSFER(+1)
DIV_TRANSFER(-1)
WEAPON_TRANSFER(WPN_WAR_MATTOCK, 5)
weight 12
cost 3 GOLD_PIECE
rent 1 SILVER_PIECE
dilcopy level_restrict@function(45,5,10,"");
dilcopy abi_restrict@function(ABIL_DEX,30,5,10,"");
end /* sacrifice_robe */

/* ****************************** */

/*
%objects
Like %rooms and %zone, this is the label that tells the compiler we will be defining items now.

sacrifice_robe
This is the name of the item which we are defining. It must be placed on a line of its own.

names {"sacrificial robe", "robe"}
These are the names for the robe. If we wanted to wear this robe, we would type either 'wear sacrificial robe' or 'wear robe'.

title "a sacrificial robe"
The title is what it claims to be, the title of the object.

extra {} "blah blah blah"
Like with a mob, this is an extra defined for the entire object. So if a player types 'look robe', this description is what they will see.

extra {"$identify"} "blah blah blah"
This extra is used with the identify spell. When a player casts 'identify robe', this is the description that they will be given.

extra {"$improved identify} "blah blah blah"
Like the extra for the identify spell, this extra provides information for use with the improved identify spell. Generally you want to give more detailed information with improved identify than with identify, such as perhaps craftsmanship, armour type, or the specific ability bonuses provided by the object.

manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_ABOUT}
The manipulate statement defines all of the possible ways for this particular item to be worn, held or taken. The list is in vme.h and each one is described. For this robe, it is takeable (very important for anything you want to not be bolted to the floor!) and it can be worn about the body, which means over any armour you wear already. All of the possible manipulate commands are defined in vme.h, and some of the more common ones are listed below.

  1. MANIPULATE_TAKE -- required if object can be picked up.
  2. MANIPULATE_HOLD -- torches, pens.
  3. MANIPULATE_ENTER -- coffins, boats, etc.
  4. MANIPULATE_WIELD -- swords, other weapons.
  5. MANIPULATE_WEAR_FINGER -- rings, etc.
  6. MANIPULATE_WEAR_NECK -- necklaces, amulets.
  7. MANIPULATE_WEAR_BODY -- breast plates, etc.
  8. MANIPULATE_WEAR_HEAD
  9. MANIPULATE_WEAR_LEGS
  10. MANIPULATE_WEAR_ARMS
  11. MANIPULATE_WEAR_SHIELD -- shields, of course.
  12. MANIPULATE_WEAR_ABOUT -- robes, cloaks, etc.

flags {UNIT_FL_MAGIC}
This flag sets the item as a magic item... basically all that this means is that when using detect magic, this item will be detected. All items with bonuses must be tagged with this flag.

ARMOUR_FULL_PLATE(+5, +5)
The armour defs are all defined in great detail in objects.txt, I will not go over these and I suggest that you scan the section on armours in your doc. (NOTE from Iccy): Please note that the European spelling of armour is used here; it took me a week to figure out why I was getting a parse error on this one when I was programming my first zone. (From Eirinn: you may think I'm biased because I'm european, but in general it's safer to use UK English when coding dil, etc, because any commands which would have different spellings in the US will always have the UK spellings).

DEX_TRANSFER(+1)
DIV_TRANSFER(-1)
WEAPON_TRANSFER(WPN_WAR_MATTOCK, 5)
Ok, this is how to make your objects actually transfer abilities and/or skills to a player. In this case we are giving the player a plus one bonus in dexterity, taking away one in divine, and increasing the player's war mattock skill by 5%. SPELL_TRANSFER and SKILL_TRANSFER are also available.

(NOTE): There are limits as to what you can transfer, both max and minimum (check Limits.txt).

weight 12
Weight is given in pounds and should be self-explanatory otherwise.

cost 3 GOLD_PIECE
Cost refers to the sell back value of the object. In this case the value of the object is three gold pieces.

rent 1 SILVER_PIECE
The rent is the per day charge to store this item, one gold piece in this case.

dilcopy level_restrict@function(45,5,10,"");
dilcopy abi_restrict@function(ABIL_DEX,30,5,10,"");
These are other special functions which restrict the use of this robe to certain people. The first restricts this robe to players of level 45 or higher. The second number is the percentage of hitpoints to remove from the person if they aren't over level 45. The third number is the maximum amount of hitpoints to take at one time. So if 5% of the player's hitpoints is more than 10 hits, it will only take 10 hits. The "" is an optional call of a dil to give a special message to the person if he isn't able to wear the robe (instead of just telling him he's not high enough in level and then making him drop the weapon). The second restriction is to those who have 30 dexterity or more, removing 5% hits amounting to a max of -10 hits per attempt to wear the robe. Try and make these restrictions logical. You can restrict objects by quests done, level, alignment, abilities, skills, etc. For further details see restrict.txt.

Examples of other restrictions:

  1. dilcopy quest_restrict@function("Mary's Quest Complete",0,0,"");
    -- Only players who have done a certain quest may use the item.
  2. dilcopy anti_guild@function ({GUILD_PALADIN},0,75,"");
    -- People in the Paladin's guild can't wear this item.

*/

/* ****************************** */

death_key
names {"death key","key"}
title "the Key to Death (Tiamat)"
descr "A blood red key is here."

extra {}
"This key has an inscription of a dragon's head. It looks very old and perhaps you should take care not to lose it."

type ITEM_KEY
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD}
cost 3 IRON_PIECE
weight 1
end /* death_key */

/* ****************************** */

/*
(NOTE) Since much of the code for the following items is the same as what was explained for sacrifice_robe, only the new ideas that are here will be discussed.

type ITEM_KEY
One thing of semi-importance in this definition is the type ITEM_KEY statement, but as it turns out this is not a necessity. That is the mud will allow other items to 'unlock' locks! Item types are listed in vme.h.

(NOTE) As you can see there is not too much involved with making a key. Do make sure that the symbolic name here (death_key) is the same as what you define for the door, also named death_key; otherwise the key will not work for the door.

*/

/* ****************************** */

ugly_sword
names {"ugly sword", "sword"}
title "an ugly sword"
descr "An ugly sword has been left here"

extra{}
"This sword bears the mark of Tiamat, the wielder must be a human sacrifice in the last days of his life."

manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
WEAPON_DEF(WPN_LONG_SWORD, +5, +5)
WEAPON_SLAYER(RACE_HUMAN)
weight 25
cost 1 SILVER_PIECE
rent 1 SILVER_PIECE
end /* ugly_sword */

/* ****************************** */

/*
WEAPON_DEF(WPN_LONG_SWORD, +5, +5)
This WEAPON_DEF can be read about in the objects.txt file so we will not delve into it, but this sword turns out to be pretty decent overall.

WEAPON_SLAYER(RACE_HUMAN)
This command defines one race for which the weapon will do extra damage. This WEAPON_SLAYER call can only define one slaying race, and if you try to put more than one of these calls, only the last one gets acknowledged. The slaying race is mostly a feature and should only be put on swords of high value.

*/

/* ****************************** */

gnarled_sign
names {"gnarled sign", "sign"}
title "the gnarled sign"
descr "A gnarled sign is here."
extra {}
"&lThe sign reads:

'Beware those who explore this zone! While the zone
might be tiny in size, the mobs which you may find
here are anything but tiny! It is rumored that even
the Queen of the dragons has taken up residence within
the boundaries of the tiny zone...'"
weight 100
type ITEM_NOTE
end /* gnarled_sign */

/* ****************************** */

/*
(NOTE) One very important aspect of this sign is the '&l' that is the first item inside of the extra description. '&l' is a useful way to format data -- if you put &l as the first character within quotation marks, however you type in this information is how it will appear on the screen. The mud will automatically format most text, so this operator acts to suppress the mud's normal formatting. You can get more information on colour and text-formatting codes in control.txt.

type ITEM_NOTE
A note is just another of the items defined in vme.h. Letters, signs, and so forth should be of this item type.

*/

/* ****************************** */

%reset

door cluttered_room DOWN {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN}
door death_room UP {EX_OPEN_CLOSE, EX_CLOSED}

load human_sacrifice into cluttered_room max 1
{
equip blue_robe position WEAR_ABOUT
equip ugly_sword position WEAR_WIELD
load death_key
}

load tiamat into death_room local 1

%end

/* ****************************** */

/*
%reset
This call labels the reset section and tells the compiler that we will be defining how the zone resets. The file dmc.txt contains extensive information about zone resets.

door cluttered_room DOWN {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN}
door death_room UP {EX_OPEN_CLOSE, EX_CLOSED}
These two lines define how the ONE door works which seperates the two rooms named here. In general, you will always need two door statments for every one door you want. The syntax for a door statement is:

door room_name direction {open flags go here}

Direction can be (UP, DOWN, NORTH, SOUTH, EAST, WEST), and the open flags are the same as defined in the room definition. So you see to make one door, you need to define it in each room it will be in, thus giving a single door two door resets.

load human_sacrifice into cluttered_room max 1
{
equip blue_robe position WEAR_ABOUT
equip ugly_sword position WEAR_WIELD
load death_key
}
Each zone reset we try to load human_sacrifice into cluttered_room. The 'max 1' label says that there may be only one human_sacrifice in the game at any time, thus if there is already one somewhere else, a new one will not be loaded. If we had specified max 3, then as long as there were 0, 1, or 2 such sacrifices in the world, another would be loaded on this zone's reset.

We equip the sacrifice with his robe and sword, each being worn at the respective location. The death key is also loaded into his inventory at each zone reset. If you wished to limit the number of, say, ugly_sword in the game, you could also specify a 'max' value on the sword. Thus, if you set the max at five and there were already five in the game, the human_sacrifice would load without the sword.

load tiamat into death_room local 1
Tiamat has nothing to load or wear, but you notice we use local 1 rather than max 1. This means if there is a Tiamat anywhere else in the world, we can load her here, but if any other Tiamats occupy this room, there will not be another loaded. Can you imagine more than one Tiamat in any room anyhow? *shiver*

%end
One last label, the %end label tells the compiler that it has reached the end of your zone file. That's all!

*/

The aim of this document is to give you a good grounding in how a zone works, and to answer the most frequently encountered difficulties which new zone builders find. We hope this guide helps tie up some of the loose ends with what you got out of the other docs. Keep the other docs handy always, as you will undoubtedly come across something new you wish to try and periodically check the web site for the latest versions, they do pop up often believe it or not (especially new additions to the DIL documentation)! Happy creating!

Iccy, Kira & Eirinn