Introduction
Who should read this book?
This book was designed to be read by anyone who is thinking of writing areas for a VME server. If you have written for other mud servers you will still need to at least skim every chapter because the VME is like no other mud engine and has some very interesting differences. If you have never written a zone then be certain to try out the suggested exercises here and there. You will find it is easy and fun to do.
What does this book cover?
The topics covered in this book are everything to do with writing an area for the VME server. While we do cover using DIL functions to make your monsters, rooms, and objects better and smarter we do not cover how to write the DIL functions covered in the DIL manual. The following are topics covered by this book:
- Compiling and Debugging
- Zone Structure and Building Blocks
- Writing Rooms
- Writing NPCs
- Writing Objects
- Doing the Resets
- Color and Formatting Codes
Credits
The basic zone writing manual you are reading now, didn’t just come flying out of this author’s head. In fact it is a conglomeration of several old texts no longer used. I had first thought about quoting and giving credit to each person who had ever modified or created portions of the first documentation but because of the nature of the way they were built it was impossible to know who did what. I therefore have decided to create a list here of everyone who has ever worked on or had a hand in the development of the basic zone writing documentation and references.
Original DIKU Coding Team
| Name | Contribution |
|---|---|
| Hans Henrik Staerfeldt | Original DIKU development |
| Sebastian Hammer | Original DIKU development |
| Michael Seifert | Original DIKU development |
| Katja Nyboe | Original DIKU development |
| Tom Madsen | Original DIKU development |
| Lars Balker Rasmussen | Original DIKU development |
These are not only the original DIKU mud developers but a few of them designed and developed the VME server. They authored the original documentation texts (abilities.txt, guild.txt, monster.txt, objects.txt, rooms.txt, vmc.txt) that were incorporated into this book.
Contributors
| Name | Contribution |
|---|---|
| Andrew Cowan | Created the first zone tutorial, contributions to DIL language |
| Ryan Holliday | Major updates to the tutorial (version 2) |
| Peter Ryskin | Wrote the original exit definitions explanation |
| John Clare | Major updates to the tutorial (version 3) |
| Marc Bellemare | Combined and revised tutorial and vmc.txt into one document |
| Jennifer Garuba | Created the first shopkeeper documentation |
| Brian Spanton | Converted original vmc.txt to HTML, fixed inconsistencies |
| Kathy Perry | Wrote the original compiler how-to |
| Mark Pringle | Main editor for spelling and grammar |
| Morgan Shafer | Wrote the guild definition primer explaining teachers |
| Karen E. Hannum | Secondary copy editor and manual tester |
General Compiler Information
In order to get your zone onto the MUD you must convert your zone from readable English text to binary form the server can understand. The way you do this is with a compiler. No, don’t freak out! You don’t have to be a skilled programmer to use a compiler. The only thing you have to do is format your rooms, objects, and non-player characters (NPC) in a form which the compiler can understand. The great thing about the VME is you can do all your zone writing in your favorite editor without having to log on to code. For those of you who have coded for other mud servers and are used to coding online, this may be a new experience for you but you will find you can plan out better designed areas offline than you can online.
This chapter will mainly cover the Valhalla Mud Compiler (VMC), how it works, and how the Valhalla Mud Pre Processor (VMC -p) works. We will also throw in some debugging hints but debugging will be covered more as you begin creating parts of your areas in the following chapters.
The Compiler
VMC is the Valhalla Mud Engine Compiler for VME servers. A compiler takes a source file or better described as your areas input file and converts it to a binary file the server can then load and use online. In the VME we call areas you build ‘zones’, therefore the source file for a zone has the extension ‘zon’. In order to make this more clear we will start with our first example.
Let’s say you were making a zone of dragons. You may want to call the file something resembling its contents like, dragon.zon. Notice we have appended the ‘.zon’ extension. The compiler requires all zones to end in ‘.zon’ in order for it to know this is a zone source file.
Now let’s say we have completed writing our first zone and want to compile it. The command is simply: vmc dragon.zon
If the zone compiles correctly it will indicate success by printing a message to the screen and outputting several files with the same root name as the original zone source file but with different extensions. In this case, there would be the following:
- dragon.data - The file holding the binary version of the zone
- dragon.reset - The file containing the reset information for the zone
- dragon.err - Error/warning output file (always created)
- dragon.dot - GraphViz DOT file showing room interconnections (not used by the engine, only for visualizing zone maps)
- dragon.dh - DIL header file with template signatures (only created if zone has a
%dilsection with templates)
If the zone doesn’t compile correctly and you have errors, it prints a list of the errors and where they can be found so you can fix them. The debugging process will be explained more as you learn how to create rooms, monsters, and objects.
The VMC Pre-processor
The VMC Pre-Processor (VMC -p) can be thought of as a powerful search and replace tool used by the compiler before it converts the zone to its binary form. This tool gives you, the builder, the ability to add comments, create short hand expressions for repeated items, include other files in your zone, and even do minor calculations when necessary.
Note: If you have coded in C or C++ before, the Pre Processor the VMC uses is no different and you can skip this section.
Commenting Your Zone
The practice of adding comments to your zone is a good thing to get into so the administrators and other builders can help you with your zone. A well commented zone will help them know what you were trying to do if there are problems. Also, if changes are made later on, it can help you remember what you were doing months or even years ago when you first built the zone. Comments aren’t as important when writing the zone as they will be when you start writing your own special DIL functions but it is important to know how comments work. It is also a good habit to get into in general.
A comment is a block of text the compiler will never see and is there only for you and whoever else reads the source file. In order to make it so the compiler will not see these notes, you must surround it by a set of symbols that tell the Pre-Processor to strip it out before passing the zone on to the compiler. These symbols are the /* and the */ symbols or the // symbols together in front of a single line.
In order to best explain how comments work we will give you a somewhat strange example. First we will start by showing you a very basic line you will see time and time again in rooms.
title "this is a title"
This is a title it will show up in everything from rooms, to objects and even NPCs. Now lets see what a commented line would look like.
//I am going to make a title now
title /* I put the keyword
first*/ "this is a title"/*then the title*/
This of course is very ugly but the point is not to be pretty it is to show you both the first way and the second way will look exactly the same to the compiler because all comments are removed before the compiler ever gets it. A better use of a comment in a zone however would be something like this:
/*
The following ten rooms are the vineyards,
there are 97 rooms in the zone.
*/
//Zone first created 1994
//Mod 1.1 1995 added quest
You will find comments will make coding large zones much easier because you can add text meant just for the builders’ eyes.
Note: You will have to decide if you want a multi-line comment or a single line comment and use the
/**/or the//respectively. The rule of thumb is if the comment is longer than 1 line it is easier to put the/**/around the comment than to comment each individual line.
Macros and What They Can Do For You
When making a zone you will find there are things you use more than once. In fact you may find things you want others to use or things you want to use in multiple zones. It’s true you could block and copy and stick them everywhere. In fact, that is what I did when I first started building. I soon found my zone file was extremely large and hard to upkeep. With a few minor changes and a lot of deleting I used short hand or better known in the world of coding as macros to make my zone readable and to make sure that everything was consistent across zones.
Let’s say you had some flags you were going to set in fifty rooms and you knew they would all be the same. You could type the following line 50 times.
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
With macros, however you could make this much easier by just doing the following at the beginning of your zone.
#define DIRTFLOOR flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
Then where ever you want the flags you just type DIRTFLOOR. You are probably thinking, yeah big deal I can do that with block and copy. True but there is another benefit to this. Let’s say later you wanted to also make these 50 rooms no teleport. All you would have to change is the define like this:
#define DIRTFLOOR flags {UNIT_FL_NO_WEATHER,UNIT_FL_INDOORS,UNIT_FL_NO_TELEPORT}
Now when you recompile, all 50 rooms are changed and you didn’t even have to do a search and replace.
You can also make macros that take arguments. The ability to take arguments is where macros take a leap and a bound out in front of your favorite editor to allow you to do things you can not do easily with search and replace. Let’s say you have an exit descr you want to use in 50 swamp rooms because heck everything looks the same in a swamp when you look one direction to the next.
east to swamp1 descr
"You see the swamp stretch out for miles";
This could be made into a macro like:
#define SEXIT(direction, place) direction to place descr \
"You see the swamp stretch out for miles.";
Then all you need to use it is:
SEXIT(east,swamp1)
SEXIT(north,swamp2)
SEXIT(south,swamp3)
Note: There is no space between ‘SEXIT’ and ‘(’ that is important because the CPP sees ‘SEXIT(’ and ‘SEXIT (’ as two different things. It is also important to notice all defines must start at the beginning of the line and be either one line long or have a
\telling the pre processor that it should continue with the next line as if it were this line.
You can also combine macros together so you have a set of macros like:
#define DIRTFLOOR flags {UNIT_FL_NO_WEATHER,UNIT_FL_INDOORS,UNIT_FL_NO_TELEPORT}
#define DIRTSECT movement SECT_INSIDE \
DIRTFLOOR
You may have noticed I capitalize all macros. This is not necessary however it is suggested so you can easily tell what is a macro and what is not. If you are building for someone else’s MUD, you should check with the Builder Admin to see what naming standards they may have.
Including Other Files in Your Zone
Another function of the VMC Pre Processor, #include, allows you to include other files in your zone file. The VME comes with some basic include files you can use the macros out of and use as examples on how to make your own include files. These files are the composed.h, vme.h, values.h, base.h, liquid.h, and wmacros.h. Including composed.h will include all the rest of the include files into your zone because it has include statements that use all the others.
Note: You will want to include the files at the beginning of your zone file because all defines you use must be defined before you use them.
Doing Minor Calculations
You can also do minor calculations in a macro. Let’s say you wanted to make it so the higher level an NPC was the heavier he was and the taller he was. This would be simple with a macro.
#define MLEVEL(lvl) \
level lvl \
height lvl+72 \
weight lvl*9
This macro would increase the height and weight depending on what level you made the NPC - pretty simple. There is much more a macro can do for you but the Pre Processor and all its uses go far beyond the scope of this manual. If you are really interested in all the neat things it can do type the following command at the ‘$’ prompt on your Linux box: man cpp
The C-Pre Processor is what the VMC Pre Processor is based on and most if not all functions of the CPP work in the VMC.
Zone Source File
In this chapter we will define all the sections of a zone file and go in-depth on the zone information section. Once complete with this chapter you should be able to create an empty yet compilable zone.
A zone source file is split up into 6 sections: a zone-declaration section, a mobile (NPC) section, an object section, a room section, a reset section, and the DIL section. The zone section is the only section that has to be in the file, and they may appear in any order.
Each section is preceded by a section header. These are the six possible headers:
%zone%dil%rooms%mobiles%objects%reset
The first four sections may be considered lists of definitions. The reset section can be considered a program in a simple programming language. And the DIL section is a bit special - it includes the zone templates (DIL functions that can be used from any zone, on anything, as opposed to “specialized” DIL functions placed inside a unit’s definitions). After all sections you are using are defined you must tell the compiler you are done - the special symbol %end must be placed at the end of the zone for this reason.
Definition Types
When creating your zone there are six main building blocks. We call these definition types. Each type represents some kind of data you want the compiler to be able to recognize. These data definitions take the basic form:
field value
Where field is the name of a data field, and value is some value. Values are of one of 6 types:
Integer
A whole number or if you are in practice of using Hex you can use the C style hex numbers in either upper or lower case (i.e. 0X0f3 or 0x0f3).
String
Text enclosed in Double Quotes. The string can span more than one line as it would in a description.
title "The dark dragon altar"
descr
"There are many things you can see and there are many things that
can't be seen but this is still a description none the less."
Stringlist
A set of strings, it can be a single string or multiple depending on your needs. These are used in names, extras, creators, and special keywords all to be defined later in their respective places. These are defined in the following manner:
<fieldname> {"string1","string2","string3", ...}
Intlist
A list of numbers which can be used with an extra. This type works like the stringlist but doesn’t need the quotes.
extra {"mynumberlist"} {1,2,3,4,5,6,7,...}
"This is a number list attached to an extra"
Flags
Like the Intlist the flag is defined with a list of numbers. The list of numbers is not taken literally, however it is combined to create one number by binary ORing the number list together. If that confuses you don’t worry, it takes some getting used to. These types are used for manipulation, flags, and positions.
flags {2,8}
manipulate {8}
In the previous example the ‘flags’ value after this zone compiles would be 10 because binary ORing the two flags together is a lot like adding. The two numbers probably make no sense so most flags you use will have defines; if I used the defines found in vme.h, the previous example would look like this:
flags {UNIT_FL_INVISIBLE,UNIT_FL_BURIED}
manipulate {MANIPULATE_WEAR_BODY}
We will cover this more in-depth later but it was necessary to give a good overview so you understand this field type enough to recognize what it is when you see it.
Symbol
A label you reference from other parts in your zones. Every unit (room, object, NPC) and even the zone itself has a unique label that can be referenced. It is important to make symbol names that are clear so the Administrators of the mud know what each item is when using the online administration commands.
dark_sword /* good symbol */
rm_5892 /* bad symbol */
When loading items online the zone symbol and the item symbol are combined to create a reference to the item. For example if our zone name was ‘dragon’ and our item was ‘dark_sword’ the symbolic name for this item would be dark_sword@dragon. Using symbols will be covered more in the DIL manual and in the administration manuals for loading objects online. For now it is enough to understand symbols must follow the following rules when being defined:
- The first letter of the symbol must be a letter of the alphabet or a
_character - Characters following the first can be numbers, alphabet letters, and
_characters - The name can be no longer than 15 characters
- No reserved keywords can be used as a name (see the appendix on Reserved Keywords)
Note: The end tag that ends all unit definitions is also considered a symbol - it is just a symbol that must be included.
Other Field Types
There are two other field types that can not be defined as a regular field type. These are the function reference and the structure. The function reference can be either a reference to a DIL function or a special function called from the base code.
Note: Special functions are being replaced with DIL for better performance and should only be used when no DIL functions exist to replace them.
The structure field types are a combination of other field types to make a special field type for the unit being defined. A good example of this is an ‘exit’ for a room. The exit has everything from flag, string, stringlist, and even description fields. The exit field will be defined much more in-depth in the chapter on rooms but it is important to know some fields are considered Structure fields because they can have many values. The only two structure fields are the exit and extra fields which will both be defined more later because they can be used differently depending on what you are using them for.
Zone Information Section
The zone information section is the only section that must exist in the source file of your area. Without this section the compiler is unable to create the zone because frankly it doesn’t know what to call it. It is also the easiest of the sections to learn because there are only a few possible fields. The Zone-section defines the global parameters for the current zone. It is usually wise to place this section in the top of the source file to make it easy to find the zone information when editing the file.
Zone Section Fields
| Field | Type | Description |
|---|---|---|
%zone | Symbol | This entry defines the name of the zone. Default is the preceding component of the current filename, minus the trailing “.zon”. Note, the symbol should be added after the %zone tag, which should always be put, even if you do not add a symbol after it. |
title | String | This is the title of the zone, for example “Dragons Nest”, “Dark Station”, “Creators Hide Out”. It is used mainly for the areas command so players can get a list of all the areas in the game. It can however be accessed by the ‘zoneptr’ variable type in DIL. If you have a zone that spans across multiple source files you only need to define the title once. If you put the title in all source files it will show up multiple times in the area listing. You would also leave this blank if the zone should not be on the areas list like an administration zone. |
lifespan | Number | This defines the interval between resets for this zone, in minutes. Default is 60 if this field is left out of the information section. |
reset | Number | This combined with ‘lifespan’ defines if the zone will be reset. This field gives the condition that must be met to reset the zones - you should use the defines in the vme.h: RESET_NOT, RESET_IFEMPTY, and RESET_ANYHOW. Default is RESET_ANYHOW, which means the zone will be reset even if players are present within it. |
creators | Stringlist | This field is where you place the creators of the zone. With this field filled out the Administrators and builders can easily find out who the zone was written by and be able to contact them if there are problems. |
notes | String | This is a plain text description of the zone for administrators and builders. It is often a good idea to include your e-mail address in the notes so you can be reached easily by the administrators. |
weather | Integer | Sets the starting atmospheric pressure for the zone. Valid range is 950-1050; default is 1000. Higher values mean clearer weather, lower values mean stormier. Special values: 900 means climate-locked permanent storms (e.g. a dreary swamp), 1100 means climate-locked permanent clear (e.g. a desert). Optional field. |
help | String | Help text shown to players when they use the zone help command. Optional field. |
Zone Information Examples
The only field that must exist when you go to create the zone information section is the %zone. Leaving the %zone field out will cause an error when you try to compile it. We suggest you not only put the %zone field but you also add a symbol or as I call it a zone name. The following are three legal examples of a Zone information header. You be the judge of which is more informative.
/* wrong */
%zone
/* bad but better than nothing */
%zone bug_planet
/* The way it should be done! */
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
If you felt like it you could add a %end to the preceding examples and compile them. They would create an empty zone so wouldn’t be very exciting but at least it’s possible. We will not go into any compiling until we have at least one unit type to compile because it is pretty useless to do. The next chapters will define the basic unit building blocks you will use for rooms, objects, and NPCs and start you off on compiling.
Unit Building Blocks
When creating your zone you will find some basic structures are used in all three unit types: rooms, objects, and NPCs. In this chapter we will define the main building blocks of all units along with some helpful hints.
No matter which unit type you are dealing with there is a simple basic structure that lets the compiler know not only what unit type it is dealing with but where one unit begins and where it ends. The way the compiler tells what unit type it is dealing with is by the section header %rooms, %objects, and %mobiles. All rooms must be defined under the %rooms header and likewise objects and NPCs under their respective headers. Each unit starts with a symbolic name called the unit symbol and ends with the keyword end. The following would be a legal definition of any unit type:
symbol_name
end
If you define a unit like this when it loads it will be blank. While this is not extremely useful, it is good to know you can leave out any field you don’t feel you need.
Symbol Field
In the last chapter we defined the different field types and rules you must follow when defining a symbol. It is important enough to review these rules here so you do not run into problems when creating your units.
- The first letter of the symbol must be a letter of the alphabet or a
_character - Characters following the first can be numbers, alphabet letters, and
_characters - The symbol can be no longer than 15 characters
- No reserved keywords can be used as a symbol (see the appendix on Reserved Keywords)
Note: It is also important to know currently it is hard to deal with units having capital letters in them. This may be fixed in the future but it is good practice to use all lower case characters in the symbols.
Another thing you should think about when defining your symbol names is to be clear about what the unit is. When you list units on the VME server with wstat the symbolic names are shown. If you were to see the list: i6853 b2419 l1854 you would have no idea what those three items were unless you personally built them recently. Therefore it is a much better coding practice to name things what they are like: long_sword healer_hut dog
Title Field
The title field is probably the easiest field on all units. It is what is shown on the first line of a room when you enter and it is the name shown when you get an object or attack an NPC. There are only two important things to look at when defining titles: punctuation and capitalization. Room titles need to be capitalized and so do proper names but the first letter of an object title or an NPC title do not normally need to be capitalized. This is best explained by some examples:
title "The Dragon's Inn" /* good */
title "a big bull dog." /* bad - has a period at the end */
title "Bill the destroyer" /* good */
title "A long dagger" /* bad - capital 'A' */
Now to show why some of those are good we will demonstrate by some sample output in the game:
prompt: l
The Dragons Inn
You are standing in a moldy inn.
prompt: get A long dagger
You get A long dagger.
prompt: kick dog
You kick a bull dog. in the head.
Notice the ‘A’ and the extra period do not really look right where they end up appearing in the game. These may be minor nitpicky details but if you do it right the first time you won’t have to deal with the English major that just happens to be playing on your mud.
Names Field
The ‘names’ field defines the names everything in the game can use to interact with your unit. For rooms the names are used as teleport or goto points for characters and NPCs or they are sometimes used for special DIL functions on objects to trigger in certain rooms. On NPCs and objects names can be used for anything from poking a player to giving a player an object. The names field is very flexible - it has even been used to store what a container is holding in order to have quick access to the names in the container.
When making rooms it is not necessary to put room names. In fact it is a good way of making sure players can’t teleport to certain rooms because if the room doesn’t have a name the person can’t teleport to it. Objects and NPCs must have names because if you leave names off of them you can not pick them up or kill them depending on which you are dealing with. It is also good practice to use all combinations of the object or NPC’s title so a player will know exactly what to type to use the item. For example:
bad_obj
title "a small dog"
names {"small dog","small","dog"}
end
It is up to you as a builder if you want to use names like ‘small’ in your names list since you would not ‘get small’ in real life - it may not have to be added to the names list. It is important however to define your names from big to small because of how the VME command interpreter handles names of things. For example if you had the following names:
small_item
title "a small item"
names {"small","item","small item"}
When you try to give small item Bill the interpreter would try to give small to item and that would not be what you wanted to do. Don’t worry the compiler will catch this and give you an error something like:
Name order error (or matching names) for 'small' in small_item@zone
Description Field
The description building block is used in many places. You will find description fields on extras, exits, rooms, NPCs, objects, and as you have already seen the help and the notes field of the zone information section are also description fields.
Depending on what you are working on, description fields can mean totally different things to the person looking in the room. A description field on a room can be the inside or outside of the room’s description. A description on extras can be an NPC’s description or an extra description on the room like if you looked at a ‘rug’ or a ‘chair’. On an exit the description field describes what you see when you look in that direction from the room you are in. The important thing right now is no matter where you use them they all work the same.
Description fields like the title field have a tag or unlike the title field can have a set of tags before them like in extras or exits but like titles they are just a string surrounded by quotes. You can make multiple line descriptions - if the description is on an NPC you may not want to since it is the description shown when you walk into the room. The following would be some examples of room descriptions:
descr
"This is how you would define a room descr and as you can see it can
be much longer than a line if you like."
extra {"basic extra"}
"This is a description field on an extra."
extra {"more advanced","extra"} {1,2,3,4,5,6}
"This is still the description field. Like the room description or
any description field for that matter this can be longer than a
line."
east to bathroom descr
"You see one big toilet!";
Extra Fields
The extra field is the work horse for the builder. It is the building block that most brings your zone to life. You can use it to describe body parts or items in a room. When you use DIL you will use extras to store information like quest information or special information you need later. Extras also store the main description on NPCs since the descr field on NPCs is really the long title shown in the room which will be explained later in the chapter on NPCs.
The extra is the first structure definition you have run into so it may take some playing with to figure it out. The extra has actually 4 fields - three of them must be there in some form. The first is the identifier that tells the compiler that this is an extra, the second is a stringlist, the third is an optional Intlist, and the final one is the extra description field. If the extra had all the fields it would look like this:
extra {"small chair","chair"} {1,2,3,4,5} "It's a chair."
If the previous wasn’t an example we would have left out the Intlist because it is not necessary to put the Intlist on a chair unless you want it there for some special DIL you are creating. The Intlist is the only field that can be totally left out but you can leave the stringlist blank when you want to make the extra the default description when the object, room, or NPC is being looked at, like this:
extra {}
"This would be what you see when you look at any of the names in the
names list."
We will go more in-depth into why you want to do this in the following chapters.
You are now ready to put these building blocks to work. You only have to learn how to put these fields to work for each of the three unit types, then you will be off and running.
The Room Section
The previous chapter gave you the basic building blocks that will be used all through creating rooms, NPCs, and objects. If you jumped straight to this chapter without reading about the general building blocks you might want to return to the chapter on Unit Building Blocks first. This chapter will deal with all the fields of rooms - what they are and how to use them; but, without the previous chapter you may get lost.
In order to get started building rooms you should first be aware of the room fields you can use. The following table shows a full listing of all the room fields and their types.
Room Fields and Types
| Field | Type |
|---|---|
| symbolic name | Symbol |
| names | Stringlist |
| title | String |
| descr | String |
| outside_descr | String |
| extra | Structure |
| movement | Integer |
| flags | Integer |
| light | Integer |
| exit | Structure |
| dilbegin/dilcopy | Function pointer |
| end | Symbol |
| minv | Integer |
| key | String |
| spell | Integer |
| manipulate | Integer |
| alignment | Integer |
| weight | Integer |
| capacity | Integer |
| gmap | Structure |
As you can see there are not a whole lot of fields you have to learn in order to make a room. In fact, as you will see shortly, some of these fields are not even used on rooms.
Description of Room Fields
Symbolic Name
The rules of the symbols has been explained in the chapter on Unit Building Blocks, if you didn’t read them yet you may want to review. The important thing to realize with the room symbol is it is always good practice to give the room a symbol resembling the title so administrators and builders can use the goto and the wstat commands to easily goto the room in question.
Title
The room title field should start with a capital and depending on your preference the compiler will not complain if you add punctuation at the end. The following are good examples of a room title:
title "The Post Office"
title "The deep dark jungle floor:"
title "The Dragon Station control room"
It is really up to you whether you want to use punctuation or not, it is more administrator personal opinion than anything.
Names
The names field on the rooms are not that important and only should be used if the builder wishes the room to be accessed by the players by a teleport command. If the room has no names no one will be able to teleport to it. On some muds there will be no teleport spell, so the only use for this field will be for DIL functions the administrator creates. If a builder wants the room to be accessible by teleport then the names should match the title since that is what the player will try to teleport to. A few good examples of names on a room would look as follows:
title "The Post Office"
names {"post office","office"}
title "the throne room"
names {"throne room","throne"}
Description (descr)
The description field is what the player sees when walking into the room or when looking with no arguments.
Outside Description (outside_descr)
This field is what is shown to a character if the room is loaded inside another room. For example if you had a room linked inside another room and called a barrel this would be the description that lets the character know it is a barrel. An example would be like:
outside_descr "a big old barrel is laying here on its side."
This allows a builder to make a room that looks like an object inside another room.
Movement
The movement field defines the endurance cost to a character when moving through this room. Currently all movement fields are constants and are defined in vme.h. The following is the movement sector types and their values:
| Symbol | Name | Endurance Cost |
|---|---|---|
| SECT_INSIDE | inside | 1 |
| SECT_CITY | city | 1 |
| SECT_FIELD | field | 2 |
| SECT_FOREST | forest | 3 |
| SECT_HILLS | hills | 4 |
| SECT_MOUNTAIN | mountain | 6 |
| SECT_DESERT | desert | 8 |
| SECT_SWAMP | swamp | 8 |
| SECT_WATER_SWIM | water-swim | 4 |
| SECT_WATER_SAIL | water-sail | 50 |
| SECT_UNDER_WATER | under-water | 8 |
| SECT_SNOW | snow | 8 |
| SECT_SLUSH | slush | 6 |
| SECT_ICE | ice | 10 |
The movement is simply defined by placing the ‘movement’ keyword first followed by the type of sector you desire. For example:
movement SECT_FOREST
movement SECT_HILLS
Note: Only one movement is needed for a room. If you put more than one the last one added will be the one used.
Graphical Map Coordinates (gmap)
The gmap field sets coordinates for positioning the room on a graphical map display.
gmap(x, y)
If not specified, both default to -1 (unset). These coordinates are accessible in DIL via the .mapx and .mapy fields.
Example:
gmap(100, 50)
Flags
This field on a room is used to set special attributes in order to make the room private or no-teleportable and many others. The following is the list of possible already defined flags:
| Flag | Description |
|---|---|
| UNIT_FL_PRIVATE | When this flag is set on a room it marks it as a private room. Commands that honor the private flag will not let more than 2 players into this room. Commands like goto and direction commands honor this flag. |
| UNIT_FL_INVISIBLE | Makes unit invisible |
| UNIT_FL_NO_BURY | Makes a hard floor so items can’t be buried |
| UNIT_FL_BURIED | Makes unit buried when loaded |
| UNIT_FL_NO_TELEPORT | Makes unit so no one can teleport to it |
| UNIT_FL_NO_MOB | Makes it so no mobile will enter the unit |
| UNIT_FL_NO_WEATHER | Keeps weather and natural light out of unit |
| UNIT_FL_INDOORS | Makes unit inside and doesn’t affect weather |
| UNIT_FL_TRANS | Makes unit transparent |
| UNIT_FL_NOSAVE | Makes it so you can’t save with unit |
| UNIT_FL_SACRED | Makes unit a double gain unit |
| UNIT_FL_MAGIC | Marks a unit to be magic |
Extra
Extras are the work horse of the VME. Extras are used in everything from DIL to just normal extra descriptions on rooms. The first job for an extra was to hold extra description information on a room. For example, if you had a computer room and you described it might look something like this:
descr
"This small room houses the computer power of the VME development team.
All four walls are lined with various pieces of computer equipment old pizza
boxes and plenty of empty soda cans."
The problem is as a player if you saw this description you might want to know what kind of pizza we eat or maybe you would want to see what kind of soda we drink. Or heaven forbid you might want to know what kinds of computer equipment is scattered about the room. In the VME servers we do this by adding extra descriptions to the room. In this case the builder of the zone may do something like this:
descr
"This small room houses the computer power of the VME development team.
All four walls are lined with various pieces of computer equipment old pizza
boxes and plenty of empty soda cans."
extra {"soda cans", "cans", "soda", "can"}
"These cans are all Canadian blue. Maybe the Valhalla team hates American
beer. Strange all of them look to have strange indentations."
extra {"strange indentations", "strange indentation","indentation"}
"They are human bite marks. Is this what happens when code doesn't work right?"
extra {"pizza boxes","pizza","boxes","box"}
"Dominos could make a fortune from all these boxes and probably already have
from the VME team. You notice all the boxes are empty at least they finish what
they start."
extra {"computer pieces","computer parts", "equipment","hardware", "pieces", "parts"}
"I bet you thought you would see what we have running. Yeah right, you might come
over and rob us if we told you that. All you see is an old XT."
extra {"xt"}
"It's a hunk of junk really!"
There is a lot to notice in the previous examples. First we will start with extras when defined on rooms, NPCs, and objects must be in length order for the names. There are a few reasons for this but let’s just say the most important reason is we wanted it this way. If you don’t put them in order the VMC will give you a fatal error and will not compile your zone.
The next thing you should notice is we have used an extra to describe something in another extra. We actually did this twice - once for the beer cans and once for the computer parts. That way you can actually give quest information but make the person really have to explore your rooms’ descriptions to find it.
Special Extras
The previous example is what we consider normal extras in a room. There are also extras that hold information for DIL functions. These special extras can have extra fields and they can be hidden to the players’ eyes. Here are some examples of special extras:
extra {"$rockcount"}
"5"
extra {"$playerkill"}
"0"
extra {"$coke","$milk","$water"} {1,5,10}
"Drinks and amounts"
These extras all have the ‘$’ sign appended to the front of the names in order to tell the look command the player shouldn’t be able to look at the extra. If you have not already seen DIL coding you may not understand why you would want extras players can’t see. The DIL language can manipulate these extras by reading and writing them in order to change the way a command or another function works. For example, the last DIL could be used for a shopkeeper to tell how many of each type of drink he has. Notice the drink extra also has an added integer list after the namelist. All extras can have these but only extras being used with DIL functions really need them.
The $get Extra
There is only one special extra already supported for rooms and that would be the $get. As we have previously mentioned the extras that start with a dollar sign are not seen by the players. This one however is shown to the player when the person types get on the other names in the extras list. This is easier to describe in an example:
extra {"$get", "statues", "statue"}
"You attempt to pick up a statue but quickly discover your feeble
attempts will never work."
extra {"$get", "red roses", "roses"}
"You bend down to pick a rose, but then decide to leave the beautiful
flower to itself."
With this one special extra we have made it so you don’t need to make millions of items so the person can act upon them. You can just make the acts as if the items were in the room.
Exits
Every room has ten possible exits: North, East, South, West, Northeast, Southeast, Southwest, Northwest, Up and Down. To enable mobile use of these commands, you must specify these exits as outlined below:
<direction> to <destination> [descr <description>] [open {<infoflags>}]
[key <keyname>] [keyword {<keywords>}] [difficulty <value>];
Exit Components
<direction>
The direction the exit leads, i.e. one of north, south, east, west, northeast, southeast, southwest, northwest, up, down.
to <destination>
The symbolic reference to the room you want this exit to lead to. If you reference a room within another zone, append the name with @<zone name>:
to myotherroom
to hisotherroom@hiszone
open <info flags>
These flags describe the state of the door:
- EX_OPEN_CLOSE - Set this if you can open and close this exit, be it a door, gate or otherwise.
- EX_CLOSED - Set this if you want the exit to be closed at boot time.
- EX_LOCKED - Set this if you want the exit to be locked at boot time.
Note: An interesting aspect is, if you do not specify a key, you can only unlock this door with the ‘pick’ skill, ‘unlock’ spell or from DIL with UnSet().
- EX_PICKPROOF - Using this flag renders the ‘pick’ skill and ‘unlock’ spell unusable on the lock of this exit.
- EX_HIDDEN - If this bit is set, the exit is hidden until the player has successfully searched for it using the ‘search’ command. Use with the
difficultyfield to set search difficulty. - EX_CLIMB - Indicates the exit requires climbing (uses climbing skill).
- EX_FALL_THIS_WAY - Used with EX_CLIMB to mark the direction characters fall when they fail a climb check. Characters continue falling through rooms with this flag until reaching one without it.
difficulty <value>
Sets the skill difficulty for picking locks or searching for hidden exits (0-250). Higher values make it harder to pick or find. If not specified, defaults to 25.
key <keyname>
The symbolic name of a key object used for unlocking this exit:
key mykey@myzone
keyword { <stringlist> }
This stringlist holds all the names of the exit you specify to manipulate the exit. If the exit is a hidden exit, these are the keywords the mobile or player can search for:
keyword {"wooden door","door"}
keyword {"hidden door","door","hatch","floor"}
descr <description>
This string is the description of what you see if you look in the direction of the exit.
;
Every exit statement needs to be terminated with a semi-colon.
Note: Even though you do not need an exit in all directions, you can use it to place descriptions of the direction:
north descr "An insurmountable mountain blocks your way.";
Minv
This field is rarely used on rooms. It could however be used to make a room invisible inside another room. Or it could be used to store numbered values on a room. If the room is going to be inside another room and you don’t want it visible the following would make it invisible to all players below the level of 20:
minv 20
Key, Manipulate, Alignment, Weight, Capacity
These fields are not used normally on a room. They exist because they are part of the base object all unit pointers (rooms, objects, and NPCs) are derived from. They can be used for anything you desire.
Light
This field sets the light on a room. Normally this is not done directly, instead it is set using macros defined in wmacros.h:
| Define | Light Value | Affect |
|---|---|---|
| ALWAYS_LIGHT | 1 | Room is always light no matter time of day |
| IN_ALWAYS_DARK | -1 | When an inside room is always dark - both inside and outside |
| OUT_DARK_NON_NOON | -1 | Always a dark room, except when it is high noon |
| OUT_ALWAYS_DARK | -2 | Always a Dark room, no matter the time of day |
To set natural light that changes depending on the time of day nothing is needed to be put in the light field - the compiler will default to ‘0’. You will also notice there are two macros that set the light to the exact same value. This is for compatibility with older code base.
This is probably one of the simplest fields you will have to deal with in the rooms. In order to set it all that is needed is to place the macro or the light and value on a line in the room:
// To set always light with macro
ALWAYS_LIGHT
// To set always light without macro
light 1
DIL Functions (dilbegin or dilcopy)
The DIL functions are what give VME servers the edge over all other muds. We will only give some examples here and leave it up to the DIL manual to teach you how to create your own functions that will make your rooms, NPCs, and objects more than special.
There are currently three room functions that come standard with a VME in the function.zon. There are much more in the zones released with the VME but you will have to hunt for those. The three that come standard are Safe room, Death room, and forced move. The safe room makes it impossible for players to kill each other, the death room is a function that lets you make things like rock slides and quick sand, and the forced move lets you make an easy river.
Since these are just DILs written by builders for the Valhalla mud all you have to do is use the dilcopy keyword in the room with the function name you want to use and the arguments the function requires. For example, using the death room function:
dilcopy death_room@function(PULSE_SEC*60, 25, "Flames shoot from the floor burning your rear.");
This says to copy the DIL from zone function with the arguments: PULSE_SEC*60 ticks (60 seconds), damage 25 hit points, and act as shown. Pretty simple!
Building Your First Room
Now you are ready! With all you have learned about room fields you know everything you need to build your first room. I personally like dragons and I like space so I have chosen to make a dragon station. We will first do a simple room and build on to it in the next sections. In this section we will walk you through creating a basic room and why we choose what we do where we do.
When making rooms you create the zone source file first as shown in the Zone Source File chapter. If you only have rooms you do not need the %reset, %objects, and %mobiles. For the examples in this chapter we will use the zone we created in that chapter and add the %room tag where we will put all the rooms. At the end of the chapter we will have the entire zone so you can see it all together.
The first part of all rooms is the symbolic name. It is good to always pick a name that will match the title so you can use the administrator command goto to easily get to the room. The reason is when you use the command wstat it will only show you a list of the rooms by symbolic name. For example if you type wstat zone dragon room you will get the following:
List of rooms in zone Dragon:
chamber portal office
If you didn’t make it clear what the rooms were by the symbolic name it might look like this:
List of rooms in zone Dragon:
st_rm1 st_rm2 st_rm3
While this might be great when you first start, imagine trying to remember what all one hundred rooms are.
The first room we will create will be a simple chamber with nothing special. We can build on to it later if we need to.
chamber
end
Pretty easy so far. Now let’s add some life to it. The room needs a title and a description. The title should be a one line description of a room as if you were walking someone around your house and telling them what each room was, like this is ‘My house’s big bathroom’ or maybe this is ‘The computer room’.
The description should be something you would tell an interior decorator you were talking to on the phone and asking for advice. He would want to know everything about the room you can see like furniture, the shape, size and windows.
chamber
title "The middle chamber of the station"
descr
"This chamber seems to have the entire station rotating around it.
Small human size ornate chairs with dragon designs scrawled on the
arms and back are arranged in a triangle like setting with one large
chair at the front. This must be where all station meetings are held.
large pictures cover the walls depicting dragons in all kinds of
situations. Small passages lead off to the west and the east."
end
It is a matter of taste if you want the descriptions of the exits in your description or not but I like them so I put them. Now if you gave this description to the interior designer, they might ask you what is on the pictures or maybe even what exactly do the chairs look like, so we better take care of that by adding some extras to our room.
extra {"chairs","chair"}
"The chairs are made of some metal you don't recognize and every inch
is covered with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture.
In the center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair
watching you."
Normally we could put a movement type for the amount of endurance lost when a person is moving through the area but we will leave it blank and go with the default which is SECT_CITY since with the fake gravity that is the closest we could come with the sector types available. The last thing we need to finish our room is the two exits leading to the other rooms.
west to portal descr "You see a small room.";
east to office descr "You see what looks to be an office.";
That’s it - that is all there is to making a room. In the next couple of sections we are going to add some more rooms with more advanced features and give some debugging hints for compiling your rooms but if you understand everything so far you’re going to have no problem. Let’s take a look at our entire finished first room:
chamber
title "The middle chamber of the station"
descr
"This chamber seems to have the entire station rotating around it.
Small human size ornate chairs with dragon designs scrawled on the
arms and back are arranged in a triangle like setting with one large
chair at the front. This must be where all station meetings are held.
large pictures cover the walls depicting dragons in all kinds of
situations. Small passages lead off to the west and the east."
extra {"chairs","chair"}
"The chairs are made of some metal you don't recognize and every inch
is covered with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture.
In the center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair
watching you."
west to portal descr "You see a small room.";
east to office descr "You see what looks to be an office.";
end
Compiling and Debugging Your First Room
It is time we put the zone header information together with your first zone and compile it into a format the VME server can use. This is done by using the VMC compiler. Depending on if you are doing this on your own Linux server or if you are building for a VME already set up you will have to use the compiler access method they have defined. No matter if you are compiling by email, ftp, or at the command line with VMC the error messages will all be the same. Since I have no idea how your particular set up is designed I will explain the errors that the compiler will return and you will have to ask your system administrator how to access the compiler. The rest of this section is written assuming you have your own VME running on your own Linux box using the VMC at the command line.
When you are working on your first zone it is always a good idea to start with one or two rooms and compile them instead of writing all the rooms and then trying to compile. The reason is the more rooms you have the more confused you can make the compiler if you have a lot of errors and you may not be able to figure out where your first mistake was easily. In our case we only have our first room and the header information for the zone so let’s put it together now and try and compile it.
#include composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOw
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%rooms
chamber
title "The middle chamber of the station
descr
"This chamber seems to have the entire station rotating around it.
Small human size ornate chairs with dragon designs scrawled on the
arms and back are arranged in a triangle like setting with one large
chair at the front. This must be where all station meetings are held.
Large pictures cover the walls depicting dragons in all kinds of
situations. Small passages lead off to the west and the east."
extra {"chairs","chair"}
"The chairs are made of some metal you don't recognize and every inch is
covered with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture.
In the center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair
watching you."
west to portal descr "You see a small room.";
east to office descr "You see what looks to be an office.";
end
%end
We added the %room tag to our zone header, stuck our room in and now it’s ready to be compiled and put into the VME server for you to be able to look at it in the game. If you downloaded our example zones for this document you can compile this zone along with us and fix the errors as we do for practice. The filename is debug_rm.zon. Just so you know the errors in this zone are intentional so please don’t write me an email telling me there are errors in it.
The command to compile the zone is VMC debug_rm.zon. Here is what we get when we first try and compile the zone:
VMC 3.0 for Muspelheim
Compiling 'debug_rm.zon'
<debug_rm.zon> @ 2: Bad include argument
<debug_rm.zon> @ 49: EOF in string
Fatal error compiling in preprocessor stage in file 'debug_rm.zon'.
Don’t worry if this looks scary, it really is much easier to read than it looks like. The first thing you need to realize about compiling is always fix one error and compile again because it might fix two or three errors after with one fix. The reason is once a compiler hits something it doesn’t understand it gets confused with the rest of the file. It is sort of like if you thought the word ‘water’ meant ‘fire’ and you tried to read a book it would get confusing really fast. So you have to correct the definition of ‘water’ to understand the rest of the book.
Let’s take the first error with this in mind. The first error shows up on line three of the error file it says:
<debug_rm.zon> @ 2: Bad include argument
This line is not really cryptic - reading it in a more English form would sound like: In file ‘debug_rm.zon’ you have an error at line 2, the argument to the include statement is not correct. Not all errors will be this clear but the compiler does its best to get you close to the error. Now if you look at line two in debug_rm.zon, you will find we forgot to put in the ‘<’ symbol. If you fix the line to look like:
#include <composed.h>
Then recompile you will have fixed your first error and get a whole new set to play with. The following is the errors we got after fixing line two:
VMC 3.0 for Muspelheim
Compiling 'debug_rm.zon'
<debug_rm.zon> @ 49: EOF in string
v: debug_rm.zon: 5: syntax error
Token: 'RESET_ANYHOw'
v: debug_rm.zon: 22: syntax error
Token: 'This'
v: debug_rm.zon: 27: syntax error
Token: 'and'
v: debug_rm.zon: 27: syntax error
Token: '.'
Grave errors in file 'debug_rm.zon'.
Now this looks to be a much more interesting error file than the previous one. Remember we mentioned you should always fix the first error first so the compiler doesn’t get confused. In this error file the first line is not the first error we need to fix. We have to do some logical reasoning here. The first error the compiler came across was the one on line 5 that shows up around line 4 of the error file. The lines before it are letting you know somewhere else in the file there is a missing quote. If we clean up the first error however we might be able to find this missing quote much easier.
So let’s start by looking at line 5 which is saying the compiler doesn’t understand what the token ‘RESET_ANYHOw’ is. This makes sense - the token should be ‘RESET_ANYHOW’ and the compiler is case sensitive. So all we need to do to fix this one is capitalize the ‘w’ and the error should be cleared up. Let’s try that and recompile and see what the errors look like. With that line fixed the following is the errors we get:
VMC 3.0 for Muspelheim
Compiling 'debug_rm.zon'
<debug_rm.zon> @ 49: EOF in string
v: debug_rm.zon: 22: syntax error
Token: 'This'
v: debug_rm.zon: 27: syntax error
Token: 'and'
v: debug_rm.zon: 27: syntax error
Token: '.'
Grave errors in file 'debug_rm.zon'.
Again we must figure out which error message we should deal with first. As before we need to deal with the lowest number error. The error we need to fix first then is the one on line ‘22’. If you go to line ‘22’ you will notice the line looks fine. When you run into an error like this where the error is not exactly on the line, scroll up to the field before the one in question and you should find the problem. In this case we forgot a ‘“’ on the ‘title’ line and confused the compiler because it thought the ending quote was the one after the ‘descr’ field. Therefore the compiler didn’t understand the ‘This’ as a field. This is one of the harder errors to find but once you get used to it will come naturally and the compiler does try to get you close. Now if we add the ‘”’ we are missing and recompile the following is the output we get:
VMC 3.0 for Muspelheim
Compiling 'debug_rm.zon'
VMC Done.
Notice there are no errors and it says ‘VMC done’, this means you have now successfully compiled the zone. I want you to look at the last error file and the fact that we only changed a quote to go from it to no errors. This is why you always deal with one error at a time. Sometimes fixing one error can fix a lot of the weird errors that make no sense. In fact I have seen one quote cause as much as 50 errors so if you jump around trying to fix errors that look like they make sense you may end up making more work for yourself.
Now that you have a compiled zone you should check and make sure all the files are there. When you compile a zone you will end up with three extra files. The files will have the same filename as your zone with a new extension - in this case you should have the following:
debug_rm.data
debug_rm.err
debug_rm.reset
debug_rm.zon
If you have all of these you are all set to go. If not then there is something seriously wrong and you may want to write the VME staff for help. To get your new zone in the mud all that is needed is to make sure your zone is in the zonelist in the VME etc directory and copy these files into your zone directory. Then reboot the mud. You should be able to log on your builder character and goto your zone by typing goto chamber@dragonst.
There you go - you have now compiled your first zone. It’s not much to look at but with what you already know you could make a full zone of very basic rooms. The next few sections will teach you some of the more interesting things you can do when making your rooms.
DIL Functions for Rooms
The DIL language is the language a builder can use to make his own special functions on rooms, NPCs, objects, PCs, and much more. This manual is for basic zone writing and therefore will not go into how to write your own DIL functions. The VME however is released with many functions for you as an Administrator and your builders to use to make special rooms, NPCs, and objects. The following is a list of all room functions released with the VME server.
Death Room
This function is a simple function that allows you to create a room to do damage to a player. The death_room can kill them slowly like a fire cave would or it can kill them quickly as if you stuck them in a microwave - it is all up to how you set the arguments. It also lets you set the acts the players see so this function can be used on any number of death style rooms. There is no need to understand how the function works, just how to use it. The following is the function’s header:
// In function.zon
dilbegin death_room(tick: integer, damage: integer, act_s: string);
As with any function all you have to do is ‘dilcopy’ the function onto your room with the correct zone name and arguments and it will do the rest. In this DIL you have three arguments to pass. The first is the ‘tick’ or time which in this DIL is broken down into ‘ticks’ which are 4 ticks per second. Thus if you wanted to get something to do damage every minute you would put ‘60*4’ in that spot. The next is the amount of damage you want done per your time. If for example you want ‘60’ hit points damage done each round you just put ‘60’ as that argument. Finally is the act shown to the character as a string in quotes. So a finished death room on your room would look like this:
dilcopy death_room@function(PULSE_SEC*60, 60,
"Flames shoot up from the floor burning your butt.");
Climb
The climb system uses exit flags to require players to use the climb command instead of normal movement.
To create a climbable exit:
- Set the
EX_CLIMBflag on the exit - Optionally add a
$climb_<direction>extra to configure fall damage
When a player tries to walk normally through an EX_CLIMB exit, they are prompted to use the climb command instead. The climb command performs a skill check using SKI_CLIMB against ABIL_DEX. On failure, the player falls and takes damage.
Example:
up to hawk_nest descr "A rope dangles down from the crow's nest."
keyword {"rope", "up"} open {EX_CLIMB};
extra {"$climb_up"} {10}
""
The integer value in the extra sets fall damage per 10 points of skill check failure. If no $climb_ extra is present, fall damage defaults to 5.
Chained Falls:
To make players fall through multiple rooms (like down a cliff face), set EX_FALL_THIS_WAY on exits. When a player fails a climb, they continue falling through each room that has this flag until reaching a room without it.
// cliff_top - climbable exit, fall continues down on failure
up to cliff_top open {EX_CLIMB};
down to cliff_mid open {EX_FALL_THIS_WAY};
// cliff_mid - falling continues through here
down to cliff_bottom open {EX_FALL_THIS_WAY};
// cliff_bottom - no EX_FALL_THIS_WAY, so falling stops here
down to cliff_base open;
In this example, a player who fails the climb at the top will tumble through cliff_mid and land at cliff_bottom, taking accumulated damage.
Force Move
This function allows you to move a player or NPC from a room to another room without having the player or NPC type or do anything.
The following is the definition of the force move DIL:
dilbegin force_move(tick: integer, strings: string, random: integer);
The ‘tick’ parameter is how fast you want the force move to be triggered. The ‘tick’ is in 1/4 second increments so to get a one second wait you would place a four. The second parameter is a single string containing the room and act separated by “!”: the part before “!” is the symbolic name of the room you are forcing the character to, and the part after “!” is the act shown to the player or NPC when moved. The final parameter is either a one or a zero. The one stands for true and it would make the timer trigger randomly fifty percent of the time, while a zero would make it not random.
The following is what the force move would look like if you wanted it to trigger every 30 seconds and give acts of a river:
dilcopy force_move@function(PULSE_SEC*30, "river2@riverzon!You float down the river.", 0);
Safe Room
This function creates a safe room where combat is not allowed. The following is the definition and an example of how to use it:
// Safe room DIL definition
dilbegin safe_room();
// Example use of Safe room
dilcopy safe_room@function();
A More Complex Set of Rooms
In the last section you learned to make basic rooms. In this section we will build on what you already know to allow you to make much more fancy rooms. In this section we will give a much better view of the exits and what can be done with them including doors, hidden doors and rooms inside other rooms. We will also show some examples of the room DIL functions being used that were described in the previous section. Finally we will pull it all together in a completed zone for you to compile and play with.
Exits with Doors
When we first defined exits we included the ‘keyword’ and ‘open’ fields on a door. In this section we will give an example of two rooms linked together with a door. There is no new information you have not already encountered so we will start with an example:
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
One important thing you should notice is, whatever you put as a keyword, along with the direction, is what a person must use to open the door. To make sure the door closes at reset time you will have to add the doors reset to the ‘%reset’ section. The door resets will be explained in the Reset Section chapter. Notice also in this example we have a direction both in the room you are going to and the room you came from. This means you need a ‘west’ direction for every ‘east’ direction leading to it. If you do not put both you will end up with a one way direction.
Locked Exits
Now that you have making a door down, you may find that it is not safe to leave your doors unlocked. Well the VME is ready for you. You have already seen the ‘keyword’ and ‘open’ sections and what you can set in them. Now let’s use the ‘EX_LOCKED’ field with them and the ‘difficulty’ field to set how hard the lock is to pick.
The difficulty field sets the skill difficulty (0-250) for picking the lock. If not specified, it defaults to 25. Higher values make the lock harder to pick.
Now let’s add the difficulty and the locked flag to the exits and create the room:
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
end
The only thing you may be wondering about in this example is the ‘key’ field. I have picked ‘nokey’ as my value of the key. There is no key in this zone so all this does is create a key hole. If you leave the ‘key’ field out totally the only way you can open the lock is by a magical spell. It is also important that you read about resets of door locks in the Reset Section chapter.
Hidden Exits
Locking the doors may not be enough. In fact sometimes you may not want to lock the door but you might want to hide it. You can do both or either by using the EX_HIDDEN flag and the difficulty field on the exit.
The difficulty field (0-250) sets how hard it is to find the hidden exit with the ‘search’ command. Higher values make it harder to find. If not specified, it defaults to 25.
Now let’s put it all together and link two rooms together with a hidden door:
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station..."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
south to portal_room descr
"You see what looks to be a portal room."
keyword {"air lock door","air lock","staff","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN};
end
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
end
Rooms Inside of Rooms
Now that you have normal exits down it’s time to take a look at something a bit different. Let’s say you wanted to put a barrel in a room that is also a room that has exits to other rooms. Or maybe in my case I want to put a transporter pad in the room that is also a room so you can exit back into the room you came from. In the case of the teleporter I could use an object but as you will find it is much easier to deal with a room for this than an object.
To put a room in a room it is much different than using the normal exit fields. The only thing needed is the ‘in’ keyword and the room you are linking the current room into. There is no need for a semi-colon. The following is what the line would look like:
in <room that room is in>
Not too hard. The following are two rooms, one in the other:
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"green field","field"}
"The field looks to be a green fog shifting and churning as you watch.
if you are nuts you could probably enter it."
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
open {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED};
//A link to the portal is also here
end
room_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in portal_room
end
Note: After adding a room in a room you should note the room in the description or put an ‘outside_descr’ on the room inside it. In our example we have chosen to add the description into the room instead of using the ‘outside_descr’. Also doors and locks work the same way as before - you can even hide this exit.
A Room Using Force Move
Sometimes you will want to help players along their path. This could be for a river that flows strongly enough to force a player’s raft downstream or maybe for a room of quick sand that sucks the player into another room. In these situations we need to use the force move DIL, explained in the previous section. Here we have built two rooms linked only by a forced move:
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"green field","field"}
"The field looks to be a green fog shifting and churning as you watch.
if you are nuts you could probably enter it."
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
open {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED};
//A link to the portal is also here
end
ship_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in ship
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"portal_room@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
A Death Room
As a final touch to our example zone, I want to create a room that will kill a player instantly. I will use the DIL function death_room and the room would simply look as follows:
deathspace
title "Open space"
descr
"You see the ship and the station far off in the distance and you are
in Space!"
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy death_room@function (
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//damage
400,
//act for the damage.
"You realize too late that was the trash disposal transporter and you
feel your lungs explode.");
end
Putting the Rooms Together
Using all you have learned so far and putting it all together into one zone, you end up with a very interesting space station with some secret rooms and traps. The full zone all together looks like this:
#include <composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%rooms
chamber
title "The middle chamber of the station"
descr
"This chamber seems to have the entire station rotating around it. It is
unbelievably large the ceiling seems to be a good 200 meters high and
the room is perfectly cubic. Small human size ornate chairs with dragon
designs scrawled on the arms and back are arranged in a triangle like
setting with one large chair at the front. This must be where all
station meetings are held. Large pictures cover the walls depicting
dragons in all kinds of situations. Large passages lead off to the west
and the east."
extra {"chairs","chair"}
"The chairs are made of some metal you don't recognize and every inch
is covered with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture.
In the center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair
watching you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to disposal_room descr
"You see a small room.";
east to hallway descr
"You see what looks to be a hallway.";
end
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom. The hallway seems to be dust free. The
walls and the floors seem to be made out of the same sterile
metal-plastic that all space agencies uses. There are large plate glass
windows that open up into space. The hallway is filled with a dim light
that seems to come from everywhere yet no where all at once. You notice
a glimmer of bright light coming from the windows. To the east you see
an air lock and to the west the hallway opens up into a larger room."
extra {"windows","window"}
"Your eyes are drawn to a large ship lit up with running lights sitting
about 1 kilometer from the station."
extra {"floor","walls","wall"}
"Well what can be said it looks to be in perfect condition. What else
would you want to know?"
extra {"large ship" ,"ship"}
"The ship looks really big and is shaped like a dragon. The scales
sparkle and seem to be multiple colors."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station. The room
is as large as the other rooms big enough for dragons to lounge while
still having a desk in one corner small enough for a humanoid. The
floor along the north wall is lined with some kind of fabric and seems
very soft to walk on, it may be some kind of dragon lounge judging by
how large an area it covers. There is a passage to the west."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"paintings","painting"}
"The paintings are of many dragons and riders in all kinds of tasks from
combat to look out. All the figures seem to be staring at a staff
being held by a depiction of a wizard on the south wall."
extra {"wizard","staff"}
"The wizard has his hand stretched out and it seems there is a place
you can almost grab the staff. Maybe if you searched the staff you would
find it."
extra {"desk"}
"It's a desk alright but there doesn't seem to be any drawers and it
seems totally empty."
extra {"fabric"}
"Wussshhhhh you bound across the comfortable floor wasn't that fun."
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
south to portal_room descr
"You see what looks to be a portal room."
keyword {"air lock door","air lock","staff","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN};
end
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"green field","field"}
"The field looks to be a green fog shifting and churning as you watch.
if you are nuts you could probably enter it."
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
//A link to the portal is also here from room_port
end
ship_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in ship
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"portal_room@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
room_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in portal_room
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"ship@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
disposal_room
title "Red field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a red field right in the center.
there is a door that leads to another room to the east."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"red field","field"}
"The field looks to be a red fog shifting and churning as you watch.
if you are nuts you could probably enter it."
east to chamber descr
"You see the main chamber.";
//A link to the portal is also here from dis_port
end
dis_port
names {"red field","field"}
title "Red field"
descr
"Red Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room to force move to and act
"deathspace@dragonst!You feel your body dissolving for lack of a better
description.",
//true or false random move or not
0);
in disposal_room
end
ship
title "War dragon"
descr
"Blue light softly glows from con duets that line the walls of this ship.
The floors beside the east and west wall have what looks to be soft
fabric covering. The south wall has small controls that seem to be made
for humanoids with two small chairs that look to be pilot seats. View
portals are about 50 meters up the side of the ship on the west and east
wall and some kind of electronic screen covers the south wall. The ship
seems to be a one room ship but there is a green field by the north
wall."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"view port"}
"Sorry you're not 50 meters tall maybe it is made for a dragon?"
extra {"view screen","screen"}
"It seems to be the pilots view screen but you can't seem to see a way
to turn it on."
extra {"controls","control"}
"The controls are in some weird language and you're afraid if you start
pushing buttons you might rocket in to the station or worse slam into
a planet."
extra {"soft fabric","fabric"}
"It looks to be a dragon lounge area."
//A link to the portal is also here from ship_port
end
deathspace
title "Open space"
descr
"You see the ship and the station far off in the distance and you are
in Space!"
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy death_room@function (
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//damage
400,
//act for the damage.
"You realize too late that was the trash disposal transporter and you
feel your lungs explode.");
end
%end
Suggested Room Exercises
-
Create a door between the Disposal room and the main chamber of the station. Make the new door pick-proof and magic-proof.
-
Create another hallway to the south of the main chamber that leads to a ship attached by an airlock. You will need a door before the hallway and before the ship so no one gets sucked out in space. You will need two more rooms for this - one for the hallway and one for the ship.
-
Using the Dragon station zone as a guide, create your own zone with eight rooms. Don’t worry too much about descriptions and extras. Link all eight of the rooms to each of the other rooms. This means each room should have seven exits. If you were to map this it would look like a cube marked with ‘X’ on the sides.
-
Make a 3 room cliff that uses the climb DIL function to climb from the bottom to top.
The NPC Section
In the previous chapters you were given the basic building blocks and they were demonstrated with rooms. This chapter will deal with all the fields of NPCs - what they are and how to use them. You may want to review the Unit Building Blocks chapter if you skipped it.
When looking at NPC fields you will find that some of them are the same as what you learned with rooms. For example: extra, alignment, flags, and more. These fields work the exact same way as they do on rooms so when you run across them they will be briefly reviewed with an emphasis on NPC-specific details.
NPC Fields and Types
| Field | Type |
|---|---|
| symbolic name | Symbol |
| names | Stringlist |
| title | String |
| descr | String |
| extra | Structure |
| minv | Integer |
| key | String |
| spell | Integer |
| romflags | Integer |
| sex | Integer |
| race | Integer |
| attack | Integer |
| defense | Integer |
| position | Integer |
| manipulate | Integer |
| alignment | Integer |
| flags | Integer |
| weight | Integer |
| capacity | Integer |
| light | Integer |
| money | Structure |
| exp | Integer |
| level | Integer |
| height | Integer |
| abilities | Structure |
| weapons | Structure |
| spells | Structure |
| special | Structure |
| dilbegin/dilcopy | Function pointer |
| end | Symbol |
NPC Field Descriptions
Symbolic Name
The rules of the symbols have been explained in the Unit Building Blocks chapter. The important thing to realize with NPC symbols is they are shown in all administration commands when dealing with NPCs. So it is good to make the symbol resemble the title, and as we explained in Unit Building Blocks, the symbol must start with an alphabetic character or underscore and should be no more than 15 characters.
Title
With NPCs the title will be shown when fighting and interacting with your NPC. For example, if the title is ‘the large dog’ and you try to kick it you will get the message:
You kick the large dog in the head.
Putting a period on the end of a title will look funny and putting a capital letter at the beginning of the title will also look strange since the title is used in sentences.
Names
As in all units, the names field is a stringlist including all the names that will be associated with the NPC to be used to interact with it. These names should be everything in the title along with some extras. The names should go from most descriptive to least. For example:
names {"large ugly dog","large dog","ugly dog","dog"}
title "a large ugly dog"
Description (descr)
Unlike descriptions in rooms this description is shown when you walk into the room and see the NPC. It should not be the description of the NPC, that goes in the extras described later. This description should be what the NPC is doing or just a statement that the NPC is there. Some examples are:
descr "A small dog is chasing its tail here."
descr "An ugly child is throwing rocks at the wall."
Extra
The extras on NPCs work like on all unit types but on NPCs they have a much greater role. The default extra on an NPC is shown when the player looks at the NPC. The following is what this would look like:
extra {}
"The small girl looks around as if she were waiting for someone."
You can add an extra description that players see when they look at the NPC. Use either an empty-named extra or one matching the NPC’s first name. If neither exists, players see “You see nothing special.” You can also create body parts and equipment:
extra {}
"A small sickly child watches you wearily. The child is dressed in
torn dirty clothes that don't look like they have been washed in years."
extra {"head"}
"A normal looking human head."
Alignment
Alignment on an NPC is a value between -1000 and +1000. You should choose an alignment on your NPC that matches the overall theme of the NPC. If your NPC is a mean killer then it probably shouldn’t be +1000 alignment, which is the highest possible good alignment. You may think alignment is not a big deal but once you assign quests to your NPCs, which can make a player good or evil, then these values really start to matter.
Flags
The flags field is the same as explained with rooms. On NPCs you may want to flag them as already buried so when they are loaded they are buried. You may also want to set them INVISIBLE or SACRED. All of the other flags are rarely set on an NPC.
Romflags (Character Flags)
The character flags are an addition to the normal flags. These flags are found in vme.h and are prefixed with ‘CHAR_’. There are many of these flags and some of them would be hard to explain without a lot more DIL or base code knowledge. Here are the most common character flags:
| Flag | Description |
|---|---|
| CHAR_PROTECTED | Attacking this char is treated as murder and triggers guard responses |
| CHAR_LEGAL_TARGET | Internal flag after illegal actions. Will not persist in zones |
| CHAR_OUTLAW | Killing this char is not treated as a crime |
| CHAR_GROUP | Char is in a group. Will not persist in zones |
| CHAR_BLIND | Sets the char as blind |
| CHAR_HIDE | Sets the char as hiding |
| CHAR_MUTE | Sets the char as mute, can not speak |
| CHAR_SNEAK | Sets the char as sneaking |
| CHAR_DETECT_ALIGN | Char can detect alignment. Pointless for NPCs |
| CHAR_DETECT_INVISIBLE | Char can see invisible units |
| CHAR_DETECT_MAGIC | Char can detect magic. Pointless for NPCs |
| CHAR_DETECT_POISON | Char can detect poison. Pointless for NPCs |
| CHAR_DETECT_UNDEAD | Char can detect undead. Pointless for NPCs |
| CHAR_DETECT_CURSE | Char can detect curses. Pointless for NPCs |
| CHAR_DETECT_LIFE | Char can detect life. Pointless for NPCs |
| CHAR_WIMPY | Makes the char flee when low on HP |
| CHAR_SELF_DEFENCE | Temporary flag when the char is not the initiator in combat. Pointless for NPC definitions. |
| CHAR_PEACEFUL | Aggressive NPCs will not attack this character |
| CHAR_KILL_SELF | Set when a PC kills themselves (will not stick) |
An example of setting a romflag on an NPC:
romflags {CHAR_PROTECTED}
Sex
In zones you use symbols to define the sex of your NPC. All symbols are prefixed with SEX_ and are found in vme.h:
| Symbol | Value | Description |
|---|---|---|
| SEX_NEUTRAL | 0 | Neither male nor female |
| SEX_MALE | 1 | Male |
| SEX_FEMALE | 2 | Female |
To set the sex on an NPC:
sex SEX_MALE
Race
In zones you also use symbols to define the race of the NPC. All symbols are prefixed with RACE_ and are found in values.h. Some common race defines are:
| Symbol | Description |
|---|---|
| RACE_HUMAN | Human |
| RACE_ELF | Elf |
| RACE_DWARF | Dwarf |
| RACE_HALFLING | Halfling |
| RACE_GNOME | Gnome |
| RACE_HALF_ORC | Half-orc |
| RACE_HALF_OGRE | Half-ogre |
| RACE_HALF_ELF | Half-elf |
| RACE_BROWNIE | Brownie |
| RACE_GROLL | Groll |
| RACE_DARK_ELF | Dark Elf |
Example:
race RACE_HUMAN
Height
The height of your NPC is set in centimeters. For example, a 6-foot NPC would be set as:
height 182
Weight
The weight of your NPC is set in pounds. For example, a 200-pound NPC:
weight 200
Position
The position of an NPC is the way it is positioned when loaded. This can be good if you want the NPC to be asleep or prone. The following defines are from vme.h:
| Symbol | Description |
|---|---|
| POSITION_DEAD | NPC is dead |
| POSITION_MORTALLYW | NPC is mortally wounded |
| POSITION_INCAP | NPC is incapacitated |
| POSITION_STUNNED | NPC is stunned |
| POSITION_SLEEPING | NPC is sleeping |
| POSITION_RESTING | NPC is resting |
| POSITION_SITTING | NPC is sitting |
| POSITION_FIGHTING | NPC is fighting |
| POSITION_STANDING | NPC is standing |
Example:
position POSITION_SLEEPING
Level
The level sets the overall power of the NPC. When you set the level it sets the experience the NPC gives and sets the starting HP. The level sets a lot of default values that can be changed after you set them so always set this field first. The level on NPCs can be anything from 1 to 199.
Example:
level 10
Experience (exp)
Experience is automatically calculated from the level and all other settings. It is, however, possible to adjust experience by setting the exp field. If you set experience as a positive number it adds that to the calculated experience. If set to a negative number it will subtract experience from the NPC.
Example:
exp -500
Attack
The attack type defines the message shown when the NPC attacks during combat. If you set the default with ‘NATURAL_DEF’, discussed later, you won’t need this field. The attack type is one of the defines found in values.h prefixed with WPN_.
Example:
attack WPN_BITE
Defense
The defense type is the amount of protection the NPC has based on an armor type. The define is also from vme.h prefixed with ARM_. Normal armor types include: clothes, leather, hleather, chain, plate.
Example:
defense ARM_PLATE
Money
Money is the amount of currency a NPC is carrying. This is set with the special money syntax. Defines IRON_PIECE, COPPER_PIECE, SILVER_PIECE, GOLD_PIECE, and PLATINUM_PIECE can be used:
money 5 SILVER_PIECE, 2 COPPER_PIECE
Abilities
Abilities are set on NPCs using a macro because they must add up to exactly 100%. The defines are in wmacros.h and the one for abilities is MSET_ABILITY.
The MSET_ABILITY macro takes 8 arguments corresponding to: Strength, Dexterity, Constitution, Hitpoints, Brain, Charisma, Magic Ability, and Divine Power. All must add to 100.
MSET_ABILITY(20, 10, 14, 21, 10, 5, 10, 10)
Weapons
Weapons and Spells are combined into 100% because they’re both used in combat. The values represent the percentages in weapon categories (axes, swords, clubs, etc.) and spell spheres. The weapon macro MSET_WEAPON takes 6 arguments for weapon groups:
MSET_WEAPON(10, 10, 10, 10, 10, 5)
Spells
The spell macro MSET_SPELL takes 11 arguments for spell spheres. When combined with weapons, the total must equal 100:
MSET_SPELL(0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 35)
Special
The special field is a special function handler passed to base code. This is only used for backwards compatibility and will be removed when all specials are replaced by DIL. Example usage for a banker:
special SFUN_BANK
Minv, Key, Light, Manipulate, Capacity
These fields are not normally set on NPCs but can be used for storing information or creating unique behavior.
NPC Macros
The file composed.h provides macros that simplify NPC creation. These define race-specific defaults and help standardize NPC building.
The Attack and Armour Macro
The natural attack and armour fields allow you to set the NPC to do damage like a certain type of weapon and to defend like a certain type of armour respectively. Let’s say you had a metal cougar; it would have an attack type of claw and an armour type of plate while a normal dog would have an armour type of leather and an attack type of bite. The NATURAL_DEF macro is what allows you to set these fields. This macro is defined in wmacros.h and looks like this:
#define NATURAL_DEF(weapon_category, armour_category) \
armour armour_category \
attack weapon_category
The word “natural” can sometimes be a little confusing since you can set any of the weapon types you like on the NPC. It doesn’t exactly make sense to have a dog that attacks as if it uses a long sword but if you wish it you can do it. The following is a short list of just the natural weapon types but you can find a full list in the appendix or in the values.h of your mud:
#define WPN_FIST 34
#define WPN_KICK 35
#define WPN_BITE 36
#define WPN_STING 37
#define WPN_CLAW 38
#define WPN_CRUSH 39
Again you don’t have to use leather for dogs - as we have already mentioned with our metal cat idea you could make a cloth dragon if you really want but it’s up to you to keep some sanity on your VME. The following is the list of armour types that can be set:
#define ARM_CLOTHES 0 /* Same as a Human in jeans and a T-shirt */
#define ARM_LEATHER 1 /* A soft flexible leather base armour */
#define ARM_HLEATHER 2 /* A hard inflexible leather base armour */
#define ARM_CHAIN 3 /* A flexible armour composed of interlocking rings */
#define ARM_PLATE 4 /* An inflexible plate armour */
Now that you have the defines to work with we will return to our metal cat and normal dog. The definitions for them would look something like this:
// Metal Cat
NATURAL_DEF(WPN_CLAW, ARM_PLATE)
// Normal dog
NATURAL_DEF(WPN_BITE, ARM_LEATHER)
You should know that the weight of the monster determines the maximum amount of damage it can give when using a natural attack. The weight is categorized as follows:
| LBS | Size |
|---|---|
| 0 - 5 | Tiny |
| 6 - 40 | Small |
| 41 - 160 | Medium |
| 161 - 500 | Large |
| 501 and up | Huge |
By default monsters are medium. So make sure you take this into account when you are creating your NPC.
The Defense and Offense Bonus Macro
There comes a time when you may want to make your NPC supernaturally powerful. It is for those times that the offense and defense fields are available for you to set. Normally they default to 0 but you can set them from -1000 to +1000. The higher you set the offense number the harder you will hit people you are in combat with. The higher you set the defense the harder it will be for people to hit your NPC. The following macro allows you to set both the offense and defense:
#define ATTACK_DEFENSE(attack, defense) \
offensive attack \
defensive defense
Using this macro is rather easy - you just put the value you want for each and you’re all done:
// A really hard hitting, hard to kill NPC
ATTACK_DEFENSE(1000, 1000)
The NPC Abilities Macro
All abilities are in the range [1..250]. Players usually have a maximum of around 150, modified by magic. When creating a monster you can not directly specify the size of the abilities, instead you specify a percentage distribution of points. The amount of points are then distributed by the computer according to the specified level. The MSET_ABILITY macro is available for this purpose:
#define MSET_ABILITY(str, dex, con, hpp, bra, cha, mag, div) \
ability[ABIL_STR] str \
ability[ABIL_DEX] dex \
ability[ABIL_CON] con \
ability[ABIL_HP] hpp \
ability[ABIL_BRA] bra \
ability[ABIL_MAG] mag \
ability[ABIL_DIV] div \
ability[ABIL_CHA] cha
Note: The sum of the ability values must be 100%. This is therefore an example of an ability distribution:
MSET_ABILITY(25, 15, 10, 15, 10, 5, 10, 10) /* Sum is 100% */
The amount of points distributed depends directly upon the level of the monster and the percentage. If the percentage is too high and the level is also set high some ability points may be lost since an NPC gets all abilities over 250 cut off. For example a level 199 monster with an ability percentage a bit above 20% will make an ability above the 250 points maximum. Each spell has a realm (magic or divine) and uses the corresponding ability - if an NPC casts both divine and magic spells, they need points in both ‘mag’ and ‘div’.
The NPC Weapon and Spell Macros
NPCs know about weapons and spells but not at the same detailed level as the player. For NPCs the spell and weapon groups are used. Thus the axe/hammer category defines all defense and all attack for all kinds of axes and hammers, whereas the player would have to train individually in each axe and hammer type. The same is true for spells.
When you define weapon and spell skills (monsters have no skill skills) you also define these as percentages, and the program automatically distributes the points. Use the pre-defined macros:
#define MSET_WEAPON(axe_ham, sword, club_mace, pole, unarmed, special) \
weapon[WPN_AXE_HAM] axe_ham \
weapon[WPN_SWORD] sword \
weapon[WPN_CLUB_MACE] club_mace \
weapon[WPN_POLEARM] pole \
weapon[WPN_UNARMED] unarmed \
weapon[WPN_SPECIAL] special
| Argument | Description |
|---|---|
| axe_ham | Any hammer or axe |
| sword | Any sword-like weapon, including dagger and rapier, etc. |
| club_mace | Any club or mace-like weapon, flails, morning star, etc. |
| polearm | Any spear or pole-like weapon: spear, trident, sickle, scythe, etc. |
| unarmed | Any bite, claw, sting or other natural attack |
| special | Any very peculiar weapon, currently only whip |
#define MSET_SPELL(div, pro, det, sum, cre, min, hea, col, cel, int, ext) \
spell[SPL_DIVINE] div \
spell[SPL_PROTECTION] pro \
spell[SPL_DETECTION] det \
spell[SPL_SUMMONING] sum \
spell[SPL_CREATION] cre \
spell[SPL_MIND] min \
spell[SPL_HEAT] hea \
spell[SPL_COLD] col \
spell[SPL_CELL] cel \
spell[SPL_INTERNAL] int \
spell[SPL_EXTERNAL] ext
| Argument | Description |
|---|---|
| div | Covers all divine sphere spells |
| pro | Covers all protection sphere spells |
| det | Covers all detection sphere spells |
| sum | Covers all summoning spells |
| cre | Covers all creation spells |
| min | Covers all mind spells |
| hea | Covers all heat spells (fireball, etc.) |
| col | Covers all cold spells (frostball, etc.) |
| cel | Covers all cell (electricity) spells (lightning bolt, etc.) |
| int | Covers all internal (poison) spells (toxicate, etc.) |
| ext | Covers all external (acid) spells (acid ball, etc.) |
Note: If you’re not sure what your weapon or spell is categorized as you can look in the
weapons.defor thespells.deffor your VME server.
The sum of all spell and weapon skills must be 100%. For example, the following would be a legal setting of weapons and spells:
// 75% Total, Club/Mace is primary
MSET_WEAPON(10, 10, 20, 5, 15, 5)
// 25% Total, Fire is primary
MSET_SPELL(8, 0, 0, 3, 0, 3, 2, 3, 3, 3, 3)
Remember that the groups define both attack and defense. So if you make an orc that has 0% in the flail group it can only use its dexterity to defend itself. Likewise with spell groups. For this reason the groups are both “resistance” as well as attack groups.
Using the composed.h
The file composed.h contains many standard monsters. It is a good idea to study these definitions, as they form the basis of many different monsters. Note that the definitions by no means are perfect, but we are hoping to make a more or less complete monster compendium. If you create certain (general) monsters, please design it as a macro so it can be incorporated in the file. The more monsters created by using these macros the easier it will be for your builders to create NPCs. If you think you have a really all-inclusive composed.h and want to share it with the rest of the VME servers running out there on the internet, feel free to submit it to the VME staff and we will put it in the contribution directories on our release site.
Race Macros
There are many race macros available. For example, M_AVG_HUMAN sets all the default values for an average human:
M_AVG_HUMAN(level, sex)
The zone distributed with VME has many race macros including: M_AVG_GOBLIN, M_AVG_HOBGOBLIN, M_DRAGON_BLACK_OLD, and many more.
Building Your First NPC
Now you know all the fields and what they are used for - let’s put all the knowledge together and build an NPC. Since this is a dragon station, we will create a dragon.
We need: a symbol, title, description, names, default extra description, race, sex, height, weight, level, natural defense, and the ability/weapon/spell macros.
bldragon
title "a black dragon"
descr "A big ugly black dragon is clawing the ground here."
names {"big ugly black dragon","ugly black dragon","big black dragon",
"black dragon","dragon"}
extra {}
"The black dragons scales glitter like black granite that has been
polished for years by water. He has a large neck and huge bat like
wings. His eyes watch you as you stand before him. One claw seems to be
tapping slightly on the ground as if the dragon is waiting for
something."
extra {"eye","eyes"}
"The dragons eyes seem to follow you no matter where you go in the room
nothing seems to escape the dragons attention."
extra {"claws","claw"}
"The claw is big black and it looks very deadly. It seems like the
dragon has two sets of 4 large claws and 2 sets of 4 smaller claws which
means the claws are about the size of short swords and long swords."
extra {"scales","scale"}
"It's a scale! Haven't you ever seen a dragon before!"
extra {"bat wings","wings"}
"The dragon sees you looking and flaps his wings creating one heck of a
wind blast."
race RACE_DRAGON_BLACK
sex SEX_MALE
height 625
weight 1250
level 70
NATURAL_DEF(WPN_CLAW, ARM_PLATE)
alignment -900
MSET_ABILITY(20, 12, 12, 12, 12, 12, 20, 0)
MSET_WEAPON(10, 10, 10, 5, 30, 5)
MSET_SPELL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30)
end
Compiling and Debugging Your First NPC
As mentioned in the room compilation section, it’s always a good idea to build one or two things and then compile to make finding errors easy. Here’s the zone with just one NPC:
#include <composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%mobiles
bldragon
title "a black dragon"
descr "A big ugly black dragon is clawing the ground here."
names {"big ugly black dragon","ugly black dragon","big black dragon",
"black dragon","dragon"}
extra {}
"The black dragons scales glitter like black granite that has been
polished for years by water. He has a large neck and huge bat like
wings. His eyes watch you as you stand before him. One claw seems to be
tapping slightly on the ground as if the dragon is waiting for
something."
extra {"eye","eyes"}
"The dragons eyes seem to follow you no matter where you go in the room
nothing seems to escape the dragons attention."
extra {"claws","claw"}
"The claw is big black and it looks very deadly. It seems like the
dragon has two sets of 4 large claws and 2 sets of 4 smaller claws which
means the claws are about the size of short swords and long swords."
extra {"scales","scale"}
"It's a scale! Haven't you ever seen a dragon before!"
extra {"bat wings","wings"}
"The dragon sees you looking and flaps his wings creating one heck of a
wind blast."
race RACE_DRAGON_BLACK
sex SEX_MALE
height 625
weight 1250
level 70
NATURAL_DEF(WPN_CLAW, ARM_PLATE)
alignment -900
MSET_ABILITY(20, 12, 12, 12, 12, 12, 20, 0)
MSET_WEAPON(10, 10, 10, 5, 30, 5)
MSET_SPELL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30)
end
%end
Common NPC compilation errors include:
- Missing
{}on extra declarations - MSET_ABILITY not adding to 100
- MSET_WEAPON + MSET_SPELL not adding to 100
When you compile successfully, you’ll get the .data, .err, and .reset files. Load your NPC with load bldragon@dragonst.
DIL Functions for NPCs
The DIL language allows builders to create special functions. The VME is released with many functions for NPCs:
Mercenary
Makes an NPC hirable by players. Players can type contract <character name> and the mob will hunt that character for a fee.
dilcopy mercenary_hire@function();
Obey
Makes an NPC obey its master. Players can tell the NPC to perform commands.
dilcopy obey@function();
Evaluate
Allows an NPC to evaluate items for a fee:
dilcopy evaluate@function(4*GOLD_PIECE);
Guard Direction
Guards a direction, optionally allowing certain players or NPCs to pass:
dilcopy guard_dir@function("south", {"papi"}, {"guard"}, "");
Combat Magic
Allows NPCs to cast spells during combat:
| Argument | Type | Description |
|---|---|---|
| atk_spl | string | Attack spell, e.g., “fireball” or “” for none |
| def_spl | string | Defense spell, e.g., “heal” or “” for none |
| def_pct | integer | HP percentage when defense spell is cast |
| spd | integer | Speed of attack magic (1=every round, 5=every 5 rounds) |
dilcopy combat_mag@function("harm", "heal", 25, 2);
Fido
Turns an NPC into a corpse/food eating mobile:
dilcopy fido@function("$1n slowly devours $2n, crunching the bones.",
"$1n grabs $2n and hungrily munches it.");
Wander Zones
Allows a mob to wander across multiple zones:
| Argument | Type | Description |
|---|---|---|
| zones | string | Zone names separated by spaces |
| spd | integer | Speed in seconds (minimum 5) |
| doors | integer | Can open/close doors (0=false, 1=true) |
| lckd_doors | integer | Can open locked doors (0=false, 1=true) |
dilcopy wander_zones@function("halfzon haon_dor", 5, 1, 1);
Global Wander
Like wander_zones but moves through all zones:
dilcopy global_wander@function(60, 1, 1);
Teamwork
Makes an NPC assist other specified NPCs in combat:
dilcopy teamwork@function("jesper/enver");
Rescue
Makes an NPC rescue other specified NPCs when attacked:
dilcopy rescue@function("jesper/enver");
Aggressive
Makes an NPC hostile under configurable conditions:
| Argument | Type | Description |
|---|---|---|
| sx | integer | 0=any sex, 1=opposite, 2=male, 3=female, 4=neutral |
| rce | integer | Race to attack (-1 for any) |
| opp | integer | 0=non-specific, 1=attack specified race, 2=attack all except |
| levl | integer | Level threshold (positive=above, negative=below, 0=any) |
| sanc | integer | 0=ignore, 1=obey sanc, 2=obey soothe, 3=obey both |
| tme | integer | Time to wait before attacking (ticks) |
| tar | integer | Target selection (-2=last, -1=weakest, 0=random, 1=strongest, 2=first) |
| align | string | “ANY”, “GOOD”, “EVIL”, “NEUTRAL”, “OPPOSITE”, “SALIGN”, “DALIGN” |
| attack | stringlist | Two messages: room message and victim message |
dilcopy aggressive(3, 2, 1, 20, 2, PULSE_SEC*10, 0, "EVIL",
{"$1n savagely attacks $3n with his big axe!",
"$1n attacks you!"});
Janitors
Picks up items from the room and sends them to a designated donation room:
dilcopy janitor@clashut("jandonate@myzone");
Shop Keeper
Creates a shop. This is one of the more complex functions. Here’s the complete setup:
Step 1 - Define Products:
#define TAVERN_PROD \
{"grain_alcohol@gobtown1 15 20", \
"pretzels@gobtown1 10 15", \
"tuborg@udgaard 15 20"}
Each product string contains: symbolic_name daily_restock max_stock
Step 2 - Define Messages (10 responses):
#define TAVERN_MSG \
{"$1n says, 'I don't sell that!'", \
"$1n says, '$3n, you don't have that!'", \
"$1n says, 'I don't trade in $2n!'", \
"$1n says, '$3n, you can't afford $2n.'", \
"$1n says, 'Thank you, here are %s for $2n.'", \
"$1n says, 'Thank you, $3n.'", \
"$1n says, 'I don't have that many.'", \
"$1n says, 'I'm closed, come back later.'", \
"$1n says, 'I have no use for $2n.'", \
"$1n says, 'I can't afford to buy that.'"}
Step 3 - Define Open Times:
#define TAVERN_OPEN_TIMES {"1","23"}
Step 4 - Define Trade Types:
#define TAVERN_ITEM_TYPE "19"
Item types: 1=LIGHT, 5=WEAPON, 9=ARMOR, 10=POTION, 15=CONTAINER, 17=DRINKCON, 19=FOOD, etc.
Step 5-7 - Define Costs:
#define TAVERN_MAX_CASH 81920
#define TAVERN_SELL_PROFIT 110
#define TAVERN_BUY_PROFIT 50
Step 8 - Apply to NPC:
dilcopy shopkeeper@function(TAVERN_PROD, TAVERN_MSG, TAVERN_OPEN_TIMES,
TAVERN_ITEM_TYPE, TAVERN_SELL_PROFIT,
TAVERN_BUY_PROFIT, TAVERN_MAX_CASH, "", "");
A More Complex Set of NPCs
Magic Casting NPC
Add combat magic to make the dragon more interesting:
bldragon
...
M_DRAGON_BLACK_OLD(SEX_MALE)
dilcopy combat_mag@function("acid breath", "", 25, 2);
end
Or using the race macro to simplify:
bldragon
title "a black dragon"
descr "A big ugly black dragon is clawing the ground here."
names {"big ugly black dragon","ugly black dragon","big black dragon",
"black dragon","dragon"}
extra {}
"The black dragons scales glitter like black granite..."
M_DRAGON_BLACK_OLD(SEX_MALE)
end
A Wandering Janitor
janitor
names {"ugly janitor", "janitor", "hobgoblin"}
title "an ugly janitor"
descr "an ugly janitor is walking around, cleaning up."
extra {}
"This ugly green thing looks more goblin than hobgoblin but he seems
intent on cleaning everything around him."
M_AVG_HOBGOBLIN(6, SEX_MALE)
alignment 900
money 5 IRON_PIECE
dilcopy janitor@clashut("disposal_room@dragonst");
dilcopy wander_zones@function("dragonst", 20, 1, 1);
end
Creating a Teacher
Setting up teachers requires stricter formatting. The ‘special’ field is used with SFUN_TEACH_INIT.
Note: Using TAB characters in teacher definitions will cause the mud to crash!
The format begins with the entity type (abilities, spells, skills, or weapons):
special SFUN_TEACH_INIT
"&labilities;0;
Then seven act messages for various situations, followed by the teaching definitions:
$1n tells you, 'I have never heard of such an ability.';
$1n tells you, 'I do not know how to teach this ability.';
$1n tells you, 'You haven't got %s for me.';
$1n tells you, 'You haven't got %d ability points.';
$1n tells you, 'I can not teach you any more.';
$1n tells you, 'You must be unaffected by magic.';
$1n tells you, 'Remove all equipment, please.';
Each teaching line has fields: guild_level; max_percent; name; min_cost; max_cost; points; 0;
0; 100; Strength ; 4; 4000; 8; 0;
0; 90; Dexterity ; 14; 14000; 12; 0;
Complete teacher example:
jones
names {"blacksmith", "smith", "Jones"}
title "Jones the blacksmith"
descr "The venerable Jones Blacksmith is here."
extra {}
"The smith is old but his arms still retain the strength of his youth."
flags {UNIT_FL_NO_TELEPORT}
romflags {CHAR_PROTECTED}
M_HUMAN_WARRIOR_AXE(80, SEX_MALE)
exp -100
dilcopy guild_basis@guilds("Udgaard Fighter");
dilcopy members_only@guilds("Udgaard Fighter", "$1n says, 'Buggar ye off.'");
special SFUN_TEACH_INIT
"&labilities;0;
$1n tells you, 'I have never heard of such an ability.';
$1n tells you, 'I do not know how to teach this ability.';
$1n tells you, 'You haven't got %s for me.';
$1n tells you, 'You haven't got %d ability points.';
$1n tells you, 'I can not teach you any more';
$1n tells you, 'You must be unaffected by magic.';
$1n tells you, 'Remove all equipment, please.';
0; 100; Strength ; 4; 4000; 8; 0;
0; 90; Dexterity ; 14; 14000; 12; 0;
0; 90; Constitution ; 14; 14000; 9; 0;
0; 100; Hitpoints ; 4; 4000; 11; 0;
"
end
Guild Master Functions
Guild masters need three DIL functions from guilds.zon:
guild_basis- Combat detection; banishes guild members who attack the NPCguild_master- Handles join/leave commandsguild_titles- Time-based title system (titles awarded based on time in guild)
dilcopy guild_basis@guilds("Udgaard Fighter");
dilcopy guild_master@guilds(
"Udgaard Fighter", // guild_name
{"Fighter Proven"}, // enter_quests - quests required to join
640, // enter_cost - iron cost to join
{"Wimp proven"}, // leave_quests - quests required to leave
3200, // leave_cost - iron cost to leave
{"Udgaard Fighter Quitter"} // exclude_quests - quests that prevent joining
);
dilcopy guild_titles@guilds(
"Udgaard Fighter",
{"the %s Swordpupil", "the %s Swordpupil", // male/female pair
"the %s Recruit", "the %s Recruit",
...}
);
The %s in titles is replaced with the player’s race name. Titles come in male/female pairs.
NPC Banker
The simplest special function:
bob
names {"Bob"}
title "Bob"
descr "Bob the Banker is here, sitting behind the counter."
extra {}
"He has a very serious look on his face."
M_SHOP_KEEPER(4, SEX_MALE, RACE_HUMAN)
exp -500
flags {UNIT_FL_NO_TELEPORT}
special SFUN_BANK
end
Suggested NPC Exercises
-
Using the teamwork DIL function, create a guard that will help all other guards.
-
Using the rescue DIL function, add to your guard from exercise one and make it so it will now rescue as well as help.
-
Using the shop keeper function, make a shop keeper that sells two types of food. The shop keeper should make 5 of them a day and should only buy items of the food type.
-
Turn your shop keeper from exercise three into a global wandering sales person.
-
Using the aggressive DIL function, create a Dwarf aggressive to any Orc that walks into the room.
The Objects Section
The previous chapters would be enough for you to create an entire game of nudists with no technology and no items of any kind. This of course would be a very boring game of naked people fighting with no weapons. Don’t worry, the VME has a solution to this - you can build objects to dress up the NPCs and to fill the rooms with cluttered junk.
In order to get started building objects you should first be aware of the object fields you can use.
Object Fields and Types
| Field | Type |
|---|---|
| symbolic name | Symbol |
| names | Stringlist |
| title | String |
| descr | String |
| inside_descr | String |
| extra | Structure |
| minv | Integer |
| alignment | Integer |
| flags | Integer |
| weight | Integer |
| capacity | Integer |
| light | Integer |
| manipulate | Integer |
| spell | Integer |
| value | Integer |
| cost | Integer |
| rent | Integer |
| type | Integer |
| open | Integer |
| key | String |
| affect | Affect function |
| dilbegin/dilcopy | Function pointer |
| end | Symbol |
Many of the same fields you found in rooms and NPCs can also be found in objects. The fields do not always have exactly the same use when coding rooms, NPCs, and objects but they are normally set in the same manner. It is very important that you read and understand the differences of each field as they pertain to rooms, objects, and/or NPCs.
Description of Object Fields
symbolic name
The rules of symbols have been explained in the Unit Building Blocks chapter, if you didn’t read them yet you may want to review. The important thing to realize with the object symbol is it is always good practice to give the object a symbol that resembles the title and description so administrators and builders can use the load and wstat commands to easily locate, examine, and load the object in question.
title
The object title is what is shown if the object is being picked up, dropped, given to someone, when you do the inventory command, or being used in combat. There should be no punctuation in the object title because of how it is used in the VME server. If you add punctuation or forget to capitalize something that the VMC thinks you should, it will give you a warning when you compile.
title "a big rock"
title "the flame tongue"
title "a lap top"
title "a garbage bag"
title "an oval hover car"
descr
The description field is what the player sees when walking into the room or when looking with no arguments. It is good practice to make this no longer than one line not counting the ‘descr’ tag.
descr
"a green bloody sword is laying here."
descr
"A massive wooden round table sits here."
descr
"a funny looking hammer is laying here."
names
The object names are as important as the NPC names. They are what you act on when picking the object up, dropping it, throwing it - just about anything you do to objects uses these name fields. On drink containers you add the liquid name at the end, so people can drink the liquid. You always need to make sure you put every possible name that the player may use to examine or take your item. The rule of thumb is if it is in the title or description it should be in the names list. Conversely, if it is not in the title or description it shouldn’t be in the names list because the players will not use it if they don’t know about it.
title "a big rock"
descr "a big rock is here blocking the road."
names {"big rock","rock"}
title "an old twisted staff"
descr "An old twisted staff has been discarded here."
names {"old twisted staff","twisted staff","old staff","staff"}
inside_descr
The inside description is what a player sees if it is inside the object. This is used for things like coffins or boxes or boats that a player can climb inside. The inside description is defined the same way the normal description is but you can make it as many lines as you want like you would with a room description.
inside_descr
"You are inside a black coffin with a red velvet padding - scary!"
inside_descr
"You are inside the pink time machine. A small control panel is on the
floor and seems to be operated by stepping on it."
extra
The extras on the object, like the NPC, can be used to do many things. It can be used to store information for DIL programs or it can be used to show a part of the object like the room extras show a part of the room. They can even be used to create new acts when a person picks the item up, drops, or enters it. There is also a special extra that is the object’s description when you look at it with the look <object> command.
If you use an extra with no names list it will become the object’s description when you look at any of the names on it:
extra {}
"It's just a rock nothing special about it."
extra {}
"The ice cube is about 40 meters perfectly cubed. It seems to be
melting slightly but waiting for it to finish would be sort of like
waiting for the ice age to end."
You can also use extras to show parts of the object:
extra {"crack"}
"There is a big crack in the side of the ice cube. Maybe if you mess
with the crack you will be able to open it or something."
extra {"bed post","post"}
"It's a big gold bed post don't you wish you could get this sucker off it
would make you a rich adventurer indeed."
Object Special Action Extras
| Extra | Description |
|---|---|
$wear_s | A message shown to activator when wearing (+wield/grab/hold) an item |
$wear_o | A message shown to others when wearing an item |
$rem_s | A message shown to activator when removing worn stuff |
$rem_o | A message shown to others when removing an item |
$get_s | A message shown to activator when getting an item |
$get_o | A message shown to others when getting an item |
$drop_s | A message shown to activator when dropping an item |
$drop_o | A message shown to others when dropping an object |
$enter_s | A message shown to activator when entering an item |
$enter_o | A message shown to others when entering an item |
$exit_s | A message shown to activator when leaving an item |
$exit_o | A message shown to others when leaving an item |
In the following example of an ice cube, $1n is the activator and $2n is the unit in question:
extra {"$get_s"}
"You pick up the $2N, it is very cold and begins to melt in your hands."
extra {"$get_o"}
"$1n picks up the $2N, you notice that a drop of water hits the ground as
it begins to melt in $1s hand."
manipulate
This field defines the things that can be done to the object. For example a piece of armour should be able to be taken and worn, while a fountain should be able to be entered but not taken unless it’s some magical portable fountain.
Take and Enter Flags:
| Manipulate | Description |
|---|---|
MANIPULATE_TAKE | Set this flag if the unit can be taken (picked up/moved about) |
MANIPULATE_ENTER | Set this flag if it is possible to enter a unit (e.g., a coffin) |
Wear Position Flags:
| Flag |
|---|
MANIPULATE_WEAR_FINGER |
MANIPULATE_WEAR_NECK |
MANIPULATE_WEAR_BODY |
MANIPULATE_WEAR_HEAD |
MANIPULATE_WEAR_LEGS |
MANIPULATE_WEAR_FEET |
MANIPULATE_WEAR_HANDS |
MANIPULATE_WEAR_ARMS |
MANIPULATE_WEAR_SHIELD |
MANIPULATE_WEAR_ABOUT |
MANIPULATE_WEAR_WAIST |
MANIPULATE_WEAR_WRIST |
MANIPULATE_WIELD |
MANIPULATE_HOLD |
MANIPULATE_WEAR_EAR |
MANIPULATE_WEAR_BACK |
MANIPULATE_WEAR_CHEST |
MANIPULATE_WEAR_ANKLE |
MANIPULATE_WEAR_FACE |
MANIPULATE_WEAR_SHOULDERS |
MANIPULATE_WEAR_HALO (not for general use) |
MANIPULATE_WEAR_AURA (not for general use) |
MANIPULATE_WEAR_BONUS (not for general use) |
Currently you can only set one of the worn position flags on an item at a time. You can set both enter and take on an item with a position or just one or the other.
// An earring
manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_EAR}
// A backpack
manipulate {MANIPULATE_TAKE, MANIPULATE_ENTER, MANIPULATE_WEAR_BACK}
// Strange but legal - an earring pack
manipulate {MANIPULATE_TAKE, MANIPULATE_ENTER, MANIPULATE_WEAR_EAR}
flags
This field on an object is used to set special attributes in order to make the object able to be buried or not, no-teleportable, and many others.
| Flag | Description |
|---|---|
UNIT_FL_PRIVATE | Currently has no effect on an object |
UNIT_FL_INVISIBLE | Makes unit invisible |
UNIT_FL_NO_BURY | Makes it so you can create objects that can not be buried |
UNIT_FL_BURIED | Makes unit buried when loaded |
UNIT_FL_NO_TELEPORT | Makes it so you can not teleport into this object (containers only) |
UNIT_FL_NO_MOB | Currently has no effect on an object |
UNIT_FL_NO_WEATHER | Currently has no effect on an object |
UNIT_FL_INDOORS | Currently has no effect on an object |
UNIT_FL_TRANS | Makes unit transparent - you can see NPCs inside it |
UNIT_FL_NOSAVE | Makes it so a PC can’t save with this unit |
UNIT_FL_SACRED | Currently has no effect on an object |
UNIT_FL_MAGIC | This flag is used by spells to tell if the object is magic |
manipulate {MANIPULATE_TAKE}
flags {UNIT_FL_NOSAVE}
type
This field is what you use to set the object’s type. The type field is used when spells are cast or commands are executed on the object.
| Type | Description |
|---|---|
ITEM_LIGHT | Can be lighted and extinguished |
ITEM_SCROLL | Can be read as a magical scroll |
ITEM_WAND | Can be used with the use command |
ITEM_STAFF | Can be used with the tap command as a magical staff |
ITEM_WEAPON | Used as weapons |
ITEM_FIREWEAPON | Not currently supported |
ITEM_MISSILE | Not currently supported |
ITEM_TREASURE | Of great value to sell but nothing else |
ITEM_ARMOR | Can be worn or used as armour |
ITEM_POTION | Can be used with the quaff command |
ITEM_WORN | Can be worn but not normally used for armour - more for clothing |
ITEM_OTHER | For items that don’t fit any other type |
ITEM_TRASH | Usually junk or broken equipment |
ITEM_TRAP | Not currently supported |
ITEM_CONTAINER | Can be used as containers |
ITEM_NOTE | Can be used to write on like paper or slates |
ITEM_DRINKCON | Can carry liquids |
ITEM_KEY | Can be used as a key |
ITEM_FOOD | Can be eaten |
ITEM_MONEY | Can be spent as currency |
ITEM_PEN | No longer supported |
ITEM_BOAT | Can be used as a water craft |
ITEM_SPELL | Not currently supported |
ITEM_BOOK | Not currently supported |
ITEM_SHIELD | Can be used as a shield |
ITEM_SKIN | Not currently supported |
ITEM_BOARD | Used for public communications |
ITEM_ALC_TOOL | Tool used for alchemy crafting |
ITEM_ALC_REAGENT | Reagent used in alchemy recipes |
Unlike flags and manipulate fields, only one item type can be set on an object at a time:
type ITEM_BOARD
weight
The weight is the weight of the object in pounds.
// 80 lbs.
weight 80
capacity
This field sets the size of a container object. If the object does not have the manipulate enter flag set then this field doesn’t have to be set. The capacity is currently by pounds since the weight of objects is set in pounds.
capacity 600
key
The key field sets the key name of the key that will open the item. This field should be set to the symbolic name of the key that opens the item it is on. If the item is in the same zone as the key then you do not need to put the zone extension on the key name.
// If object and key are in same zone
key brasskey
// If key and object are in same zone (explicit)
key brasskey@zonename
// If key and object are not in same zone
key brasskey@otherzonename
cost
This is the field you set to add a cost to your object. If you leave this field out it will default to no cost and will not be able to be sold at stores. The system for setting cost on an item is the same as setting money on a NPC.
IRON_PIECE
COPPER_PIECE
SILVER_PIECE
GOLD_PIECE
PLATINUM_PIECE
cost 5*GOLD_PIECE
// Multiple coin types
cost 5*GOLD_PIECE, 20*IRON_PIECE
rent
This field tells how much it costs you to keep an item while you’re offline. The rent is not always taken if the VME server is set up to not take any rent.
rent 5*GOLD_PIECE, 20*IRON_PIECE
minv
This field is the administrator invisible level of the object it is set on. This means that if you set the ‘minv’ to 200 it will make it so the object can not be seen by anyone below the administrator level of 200.
minv 239
alignment
The object alignment is not currently used. It is an integer value that can be set on an object to be used with any DIL functions. The value is set from -1000 to +1000.
alignment -250
open
The open field is used if you want to give your object the ability to be opened, closed, and/or locked. If you add the open flags you need to also add a key field.
| Flag | Description |
|---|---|
EX_OPEN_CLOSE | Set this if you can open and close this object |
EX_CLOSED | Set this if you want the object to be closed when loaded |
EX_LOCKED | Set this if you want the object to be locked when loaded |
EX_PICKPROOF | Renders the ‘pick’ skill and ‘unlock’ spell unusable |
EX_INSIDE_OPEN | Enables opening and locking from inside (containers only) |
Note: If you do not specify a key, you can only unlock this door with the ‘pick’ skill, ‘unlock’ spell or from DIL with
UnSet().
// Simple open/close
open {EX_OPEN_CLOSE}
// Locked and closed with a key
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
key brass_key
spell
The spell field is the power of the object’s defense against spells. You can set it from zero all the way to 200% which means a person who has 100% in a spell will fail almost all the time.
// Spell resistance at 150%
spell 150
value
The object values are used for just about any special item from armour to drink containers. They should not be set directly unless you have a reason to do so. There are five values that can be set to any integer:
value[0] 5
value[1] 16
value[2] -2
value[3] -10
value[4] 12
affect
The affect field should not be set directly, instead you should use the macros defined in the Object Macros section.
dilbegin or dilcopy
DIL functions are what give VME servers the edge over all other MUDs. There are several object functions that come standard with the VME:
- Guild restrict
- Anti-guild restrict
- Quest restrict
- Quests restrict
- Alignment restrict
- Level restrict
- Virtual level restrict
- Race restrict
- Ability restrict
- Skill restrict
- Spell restrict
- Weapon restrict
- Gender restrict
- Player restrict
- Message board
- Tuborg (drink bonus)
Object Macros
To make the creation of some objects easier we have provided a set of macros. The macros range from general armour and weapons macros to macros that help you create special affects on all items.
Weapon and Armour Craftsmanship
The craftsmanship is a way of expressing the overall quality of a piece of armour or weapon. The quality on the VME servers currently means the amount of hit points given to an item. The craftsmanship ranges from 25 to -25 and the hit points range from 125 to 6000.
| Craftsmanship | Hit Points |
|---|---|
| 25 | 6000 |
| 20 | 5000 |
| 15 | 4000 |
| 10 | 3000 |
| 5 | 2000 |
| 0 | 1000 |
| -5 | 825 |
| -10 | 650 |
| -15 | 475 |
| -20 | 300 |
| -25 | 125 |
It is suggested the higher the craftsmanship the higher the cost of the weapon should be.
Magical Modifier
The magical modifier can be said to modify damage done to an opponent. In combat the damage is calculated and then the magical bonuses on armour or weapons is added in. The magical modifier ranges from 25 to -25.
For example: If you were about to give 25 hit points of damage to a person and your sword has a plus 25% in magical bonus, the bonus is added to your damage to make it a total of 50 hit points of damage. If the player you are hitting has a +25% magical bonus on his armour, that will reduce the damage back to its 25 hit points originally done.
Setting Weapon Fields
To create a weapon you only need three pieces of information: the weapon’s craftsmanship, magical modifier, and the weapon type.
#define WEAPON_DEF(weapon_category, craftsmanship, magic_bonus)
#define WEAPONSZ_DEF(weapon_category, craftsmanship, magic_bonus, hgt)
The first macro uses the second macro - the only difference is the first one sets the height field.
// A flail of non-pure iron, a little better than average craftsmanship
WEAPON_DEF(WPN_FLAIL, +2, 0)
// A rusty mean sacrificial dagger by a skilled smithy, magically enchanted
flags {UNIT_FL_MAGIC}
WEAPON_DEF(WPN_DAGGER, 0, +5)
// An old shaky wooden stick made for a 400 cm tall person
WEAPONSZ_DEF(WPN_CLUB, -5, 0, 400)
// A wooden bastard sword (poor craftsmanship due to material)
WEAPON_DEF(WPN_BROAD_SWORD, -15, 0)
Setting Armour Fields
When designing armour there are five main armour types:
ARM_CLOTHESARM_LEATHERARM_HLEATHERARM_CHAINARM_PLATE
The armour type defines how different weapons and spells are defended against.
#define ARMOUR_DEF(atype, craftsmanship, magic_bonus)
#define ARMOURSZ_DEF(atype, craftsmanship, magic_bonus, hgt)
Example:
flags {UNIT_FL_MAGIC}
ARMOUR_DEF(ARM_PLATE, +15, +5)
There are also convenience macros that combine the type and ARMOUR_DEF:
ARMOUR_CLOTHES(craftsmanship, magic_bonus)
ARMOUR_LEATHER(craftsmanship, magic_bonus)
ARMOUR_HRD_LEATHER(craftsmanship, magic_bonus)
ARMOUR_CHAIN(craftsmanship, magic_bonus)
ARMOUR_PLATE(craftsmanship, magic_bonus)
Example using the convenience macro:
flags {UNIT_FL_MAGIC}
ARMOUR_PLATE(+15, +5)
Setting Shield Fields
There are three shield types categorized by size:
SHIELD_SMALLSHIELD_MEDIUMSHIELD_LARGE
The larger the shield the better chance of blocking an attack.
#define SHIELD_DEF(shield_type, craftsmanship, magic_bonus)
#define SHIELDSZ_DEF(shield_type, craftsmanship, magic_bonus, hgt)
Example:
flags {UNIT_FL_MAGIC}
SHIELD_DEF(SHIELD_SMALL, 0, +5)
Setting Material Types
Currently material types are not used greatly in spells or skills but in the future we hope to add more functionality.
MATERIAL_WOOD("a hard oak")
MATERIAL_METAL("fine steel")
MATERIAL_STONE("granite")
MATERIAL_CLOTH("silk")
MATERIAL_LEATHER("cow hide")
MATERIAL_SKIN("dragon skin")
MATERIAL_ORGANIC("soft plastic")
MATERIAL_GLASS("crystal")
MATERIAL_FIRE("flames")
MATERIAL_WATER("liquid")
MATERIAL_EARTH("clay")
MATERIAL_MAGIC("pure energy")
Drink Container Macros
There are pre-defined macros for common drinks in liquid.h:
LIQ_WATER(WEIGHT, CAPACITY, INSIDE, POISON)
LIQ_BEER(WEIGHT, CAPACITY, INSIDE, POISON)
LIQ_WINE(WEIGHT, CAPACITY, INSIDE, POISON)
LIQ_COFFEE(WEIGHT, CAPACITY, INSIDE, POISON)
Arguments:
- weight: How heavy the container is when empty (in pounds)
- capacity: Maximum liquid weight the container can hold. Set to -1 for infinite
- inside: How much liquid the container starts with (should not exceed capacity)
- poison: The amount of poison in your drink (0-10, with 10 being extreme)
// A simple small glass of water
LIQ_WATER(1, 2, 2, 0)
The player’s thirst ranges from -24 (dying of thirst) to +24 (full). A barrel with capacity 24 when full can take a person from zero thirst to full.
For exotic drinks, use the full macro:
#define LIQ_DEF(color, wgt, max_cap, inside, thirst, full, drunk, poison)
Arguments:
- color: Color of the liquid shown when you look at it
- wgt: Weight of the empty container
- max_cap: Maximum capacity
- inside: Starting amount of liquid
- thirst: Thirst quenching power per pound (0-10, water is 10)
- full: Fullness added per pound (0-10, like milk around 5)
- drunk: Drunkenness added per quantity (0-10, vodka is 10)
- poison: Poison factor (0-10+)
// Silicone oil for aliens
LIQ_DEF("blue", 5, 10, 10, 5, 1, 0, 0)
// Creating your own easy macro
#define LIQ_SILICONE(WEIGHT, CAPACITY, INSIDE, POISON) \
LIQ_DEF("blue", WEIGHT, CAPACITY, INSIDE, 5, 1, 0, POISON)
The Food Macros
The food macro is simpler than drink containers:
#define FOOD_DEF(food_amount, poison_factor)
// Fill a player entirely in one bite
FOOD_DEF(50, 0)
It is recommended to set the value between 1 and 10 so players have to eat a bit as if they were eating in the real world.
Light Object Macro
#define LIGHT_DEF(hours, how_bright)
- hours: Duration in mud hours (about 5 minutes per mud hour)
- how_bright: 1=small torch, 2=large torch, 3=lantern
Container Macro
#define CONTAINER_DEF(max_capacity)
Remember that capacity is in weight, not size. If someone’s corpse weighs 230 pounds, you need a container with capacity of 230 to fit it.
// A coffin that can carry any normal human corpse
CONTAINER_DEF(300)
Money Macro
#define MONEY(coin_type, coins)
Coin types: IRON_PIECE, COPPER_PIECE, SILVER_PIECE, GOLD_PIECE, PLATINUM_PIECE
platinum_piece
MONEY(PLATINUM_PIECE, 0)
end
platinum_pile
MONEY(PLATINUM_PIECE, 80)
extra {}
"Holy cow that's a stash."
end
Cursed Objects Macro
CURSED_OBJECT
When you set this macro on an object it adds an affect that can only be removed by the ‘set’ command or by the ‘remove curse spell’.
Potion, Wand, and Staff Macros
#define POTION_DEF(power, spell1, spell2, spell3)
#define SCROLL_DEF(power, spell1, spell2, spell3)
#define WAND_DEF(power, charge, spell1, spell2)
#define STAFF_DEF(power, charge, spell1, spell2)
- power: The spell power (1-200)
- charge: Number of charges (wands/staffs only)
- spell#: The spells to cast (set unused to 0)
Magical Transfer Macros
CHAR_FLAG_TRANSFER(_MFLAGS)
SKILL_TRANSFER(skill, amount)
WEAPON_TRANSFER(weapon, amount)
SPELL_TRANSFER(spell, amount)
STR_TRANSFER(amount)
DEX_TRANSFER(amount)
CON_TRANSFER(amount)
CHA_TRANSFER(amount)
BRA_TRANSFER(amount)
MAG_TRANSFER(amount)
DIV_TRANSFER(amount)
HIT_TRANSFER(amount)
SPEED_TRANSFER(newspeed)
SLOW_TRANSFER(amount)
The skill, weapons, spells, and ability macros transfer the amount of percentage you put. If you give a negative percentage it will take that much away. The speed transfer adds or subtracts speed (valid range 4-200, with 12 being default and lower values being faster).
Building Your First Object
Now that you have learned how to make rooms and NPCs it’s time to make the objects for your little world. As always we will start with something I like - dragons. So the first object we will make is a dragon head.
The first part of all object definitions is the symbolic name. It is good to always pick a name that will match the name of the object so it will be easy to load. When you use the command wstat zone dragon objects you will see:
List of objects in zone Dragon:
claw info_board dragon_head
versus unclear names like:
List of objects in zone Dragon:
obj1 a_obj2 o3
Let’s get started with our dragon head:
dragon_head
title "a gold dragon head"
descr "A large golden dragon head is laying here looking sad."
names {"large golden dragon head","large gold dragon head",
"golden dragon head","large dragon head","gold dragon head",
"dragon head","large head", "sad head","head"}
extra {}
"The head is large and beautiful, at least as beautiful as a dead
dragon head can be. There is an extreme look of sorrow on the dragons
face and it seems to be for much more than its own death."
extra {"gold dragon head face","dragon head face","head face","face"}
"Looking into the dragons face your eyes are drawn to the eyes of the
dead dragon. Could there be something there?"
extra {"eyes","eye"}
"A world of blue skies and no storms is visible through the eyes and it
seems to be moving as if you were watching the world from space."
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD}
// 20 feet (1 inch = 2.54 cm)
height 33
// 566 KG (1 lb. = .45359 kg)
weight 50
extra {"$get_s"}
"You suddenly feel very sad for a world that you don't even know."
extra {"$get_o"}
"A strange look of sadness crosses $1ns face."
extra {"$drop_s"}
"You feel much happier but you remember a feeling of great sorrow."
extra {"$drop_o"}
"$1n seems to cheer up a bit."
end
Compiling and Debugging Your First Object
As we have previously mentioned, it is always a good idea to build one or two things and then compile to make finding errors easy. The following is what the zone looks like when it has only one object:
#include <composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%objects
dragon_head
title "a gold dragon head"
descr "A large golden dragon head is laying here looking sad."
names {"large golden dragon head","large gold dragon head",
"golden dragon head","large dragon head","gold dragon head",
"dragon head","large head", "sad head","head"}
// ... rest of object definition ...
end
%end
The command to compile the zone is VMC debug_obj.zon. Here are some common errors you might encounter:
Missing ‘s’ on creators:
debug_obj.zon: 5: parse error
Token: '{'
The compiler is pointing at ‘{’ but the real problem is creator instead of creators.
Missing quote:
debug_obj.zon: 25: parse error
Token: 'golden'
This usually means a missing quote somewhere before line 25.
Missing braces on manipulate:
debug_obj.zon: 42: parse error
Token: ','
The manipulate field needs {} around its values.
When you see VMC Done, you have successfully compiled the zone.
DIL Functions for Objects
The DIL language is what a builder can use to make special functions on rooms, NPCs, objects, PCs, and much more. The following sections contain the object functions released with the VME server.
Restriction Functions
The restrict functions were designed to allow only certain groups of players to wear some items. They can be used alone or together to make a greater restricted item.
All restrict functions have this format:
dilcopy <function name> (arg1, <max damage>, <percentage>, <Optional DIL>);
max damage and percentage: These set the damage done when the wrong player wears an object.
- Both set to 0: No damage done
- Second arg set to number, third to 0: Exact damage (can kill)
- Second arg to 0, third to number: Percentage damage
- Both set: Percentage damage up to max amount
Optional DIL: Pass in a custom DIL for custom messages, or "" for default.
Guild Restrict
Restricts an object to players in certain guild(s).
dilbegin guild_restrict
(guilds:stringlist, damage:integer, percent:integer, action:string);
// Example: Only Paladins and Sorcerers
dilcopy guild_restrict@function ({"Midgaard Paladin",
"Midgaard Sorcerer"}, 0, 25, "");
Anti-guild Restrict
Restricts an object from players in certain guild(s).
dilbegin anti_guild
(guilds:stringlist, damage:integer, percent:integer, action:string);
// Example: Anyone except Paladins and Sorcerers
dilcopy anti_guild@function ({"Midgaard Paladin",
"Midgaard Sorcerer"}, 0, 25, "");
Quest Restrict
Restricts an object to players who have done a certain quest.
dilbegin quest_restrict
(qst:string, damage:integer, percent:integer, action:string);
dilcopy quest_restrict@function ("Eagles quest complete", 0, 25, "");
Quests Restrict
Restricts an object to players who have done ALL listed quests.
dilbegin quests_restrict
(qsts:stringlist, damage:integer, percent:integer, action:string);
dilcopy quests_restrict@function ({"Eagles quest complete",
"Feather fall quest complete"}, 0, 25, "");
Alignment Restrict
Restricts an object to players within a certain alignment range.
dilbegin ali_restrict
(max:integer, min:integer, damage:integer, percent:integer, action:string);
// Only good players (350 to 1000)
dilcopy ali_restrict@function (1000, 350, 0, 25, "");
Level Restrict
Restricts to players at or above a certain level (1-50 for mortals).
dilbegin level_restrict
(lvl:integer, damage:integer, percent:integer, action:string);
// Administrators only
dilcopy level_restrict@function (51, 0, 25, "");
Virtual Level Restrict
Restricts to players at or above a certain virtual level (1 to infinity).
dilbegin vlevel_restrict
(lvl:integer, damage:integer, percent:integer, action:string);
dilcopy vlevel_restrict@function (5000, 0, 25, "");
Race Restrict
Restricts from players of a certain race.
dilbegin race_restrict
(rc:integer, damage:integer, percent:integer, action:string);
// Humans cannot use
dilcopy race_restrict@function (RACE_HUMAN, 0, 25, "");
Gender Restrict
Restricts to players of a certain gender.
#define SEX_NEUTRAL 0
#define SEX_MALE 1
#define SEX_FEMALE 2
dilbegin sex_restrict
(sx:integer, damage:integer, percent:integer, action:string);
dilcopy sex_restrict@function (SEX_FEMALE, 0, 25, "");
Player Restrict
Restricts to a specific player name.
dilbegin ply_restrict
(pname:string, damage:integer, percent:integer, action:string);
dilcopy ply_restrict@function ("Whistler", 0, 25, "");
Ability Restrict
Restricts to players with minimum ability.
dilbegin abi_restrict
(abi:integer, min_abi:integer, damage:integer, percent:integer, action:string);
// Requires 50% strength
dilcopy abi_restrict@function (ABIL_STR, 50, 0, 25, "");
// Multiple abilities
dilcopy abi_restrict@function (ABIL_DIV, 50, 0, 25, "");
dilcopy abi_restrict@function (ABIL_BRA, 30, 0, 25, "");
Ability types: ABIL_MAG, ABIL_DIV, ABIL_STR, ABIL_DEX, ABIL_CON, ABIL_CHA, ABIL_BRA, ABIL_HP
Skill, Spell, and Weapon Restrict
Similar to ability restrict:
dilcopy ski_restrict@function (SKI_TURN_UNDEAD, 50, 0, 25, "");
dilcopy sp_restrict@function (SPL_LOCK, 50, 0, 25, "");
dilcopy weap_restrict@function (WPN_BATTLE_AXE, 50, 0, 25, "");
Tuborg Function
The VME has a tuborg function that makes a drink give endurance and health when drunk.
dilbegin tuborg (s:string);
dilcopy tuborg@function ("");
The argument is not used yet - just pass an empty string.
Message Board
Every game needs a way for administrators and players to exchange ideas.
dilbegin board
(idxfile:string, l_res:string, r_res:string, p_res:string, bmax:integer);
Arguments:
- idxfile: Board index filename (unique identifier for this board)
- l_res: DIL for look restrictions (
""for none,"admin_res@boards"for admin only) - r_res: DIL for remove restrictions (
""for none,"rem_res@boards"for admin only) - p_res: DIL for post restrictions (
""for none) - bmax: Maximum number of posts
// Free for all board
dilcopy board@boards("citizen", "", "", "", 50);
// Only admins can remove posts
dilcopy board@boards("citizen", "", "rem_res@boards", "", 100);
More Complex Objects
Making a Communication Board
info_board
title "a merchant information board"
descr "A merchant information Board is mounted on a wall here."
names {"merchant information board","information board","merchant board","board"}
extra {}
"A large flashy black steel board."
MATERIAL_METAL("A very fine quality black steel")
type ITEM_BOARD
dilcopy board@boards("info", "", "rem_res@boards", "", 100);
end
Making a Container
wpn_locker
title "a weapons locker"
names {"weapons locker","weapon locker","locker"}
descr "a small weapons locker hangs on the wall here."
extra {}
"It is an ordinary weapons locker that looks like it holds any illegal
weapons that are taken on the station."
MATERIAL_METAL("A very fine quality steel")
manipulate {MANIPULATE_ENTER}
CONTAINER_DEF(500)
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
key black_key
end
Notice we didn’t make the item MANIPULATE_TAKE because we don’t want people to walk off with our weapons locker.
Creating Drinks
The drink container has special rules:
- title and descr: Should NOT have the liquid name (it might change if refilled)
- names: MUST have the drink name as the LAST name (it gets removed/added when emptied/refilled)
liq_ration
names {"red bag", "bag", "wine"}
title "a red bag"
descr "A red bag has been gently placed here."
extra {}
"A small label reads Tassel Grove's finest. Year 321"
MATERIAL_ORGANIC("a soft plastic")
manipulate {MANIPULATE_TAKE}
LIQ_WINE(1, 2, 2, 0)
cost 2 IRON_PIECE
extra {"$identify"}
"It's the special wine from Tassel grove a small halfling village on the
planet Valhalla. It seems like a great vintage wine."
end
Creating Food
Food is very simple - just a regular item with the food macro:
beef_stick
title "a tough leathery stick"
descr "A tough leathery looking stick is laying here."
names {"tough leathery stick","tough leather stick","leathery stick",
"leather stick","tough stick","stick"}
extra {}
"This has the word BEEF burnt into it."
manipulate {MANIPULATE_TAKE}
FOOD_DEF(5, 0)
weight 1
cost 1 COPPER_PIECE
MATERIAL_ORGANIC("tough beef")
end
Making a Weapon
w_stiletto
title "a stiletto"
names {"deadly looking stiletto","deadly stiletto","stiletto", "dagger"}
descr "A deadly looking stiletto has been left here."
extra {}
"This looks like a thieves dream come true."
MATERIAL_METAL("A very fine quality steel")
manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
WEAPON_DEF(WPN_DAGGER, 1, 2)
SKILL_TRANSFER(SKI_BACKSTAB, 2)
dilcopy abi_restrict@function (ABIL_DEX, 10, 0, 25, "");
weight 2
cost 2 GOLD_PIECE
rent 1 COPPER_PIECE
extra {"$identify"}
"The stiletto looks magical in nature and seems really sharp. You can
tell if you wield it you would be able to backstab someone really easy."
extra {"$improved identify"}
"The stiletto gives you a magical bonus of +1 and has a quality of +2.
It also raises your back stabbing skill by 2%. You have to have at
least 10% in dex before you can wield this magical weapon."
end
Making Armour
Only seven wear positions count as armour:
| Position | Define |
|---|---|
| head | MANIPULATE_WEAR_HEAD |
| hands | MANIPULATE_WEAR_HANDS |
| arms | MANIPULATE_WEAR_ARMS |
| body | MANIPULATE_WEAR_BODY |
| legs | MANIPULATE_WEAR_LEGS |
| feet | MANIPULATE_WEAR_FEET |
| cloak | MANIPULATE_WEAR_ABOUT |
Note:
MANIPULATE_WEAR_SHIELDalso works as armour but uses a different define.
pol_plate
names {"polished breast plate","polished plate","breast plate","plate"}
title "a polished breast plate"
descr "A polished breast plate has been left here."
extra {}
"This is one shiny plate it seems to be made out of one perfect piece of
metal. There doesn't even seem to be any markings of ownership."
MATERIAL_METAL("A high luster silver colored metal")
manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_BODY}
ARMOUR_DEF(ARM_PLATE, 5, 9)
dilcopy abi_restrict@function (ABIL_STR, 40, 0, 25, "");
cost 2 GOLD_PIECE
rent 3 COPPER_PIECE
weight 25
extra {"$identify"}
"This is a high quality plate with a magical feeling."
extra {"$improved identify"}
"The plate has a magical bonus to your defence of a +5 and a quality of
+9. You need 40% in strength to be able to wear it."
end
Making Non-Armour Worn Objects
Non-armour positions:
| Position | Define |
|---|---|
| ear | MANIPULATE_WEAR_EAR |
| neck | MANIPULATE_WEAR_NECK |
| wrist | MANIPULATE_WEAR_WRIST |
| finger | MANIPULATE_WEAR_FINGER |
| chest | MANIPULATE_WEAR_CHEST |
| back | MANIPULATE_WEAR_BACK |
| waist | MANIPULATE_WEAR_WAIST |
| ankle | MANIPULATE_WEAR_ANKLE |
Note: Positions like ear, neck, wrist, and ankle can have two on a player. Any bonuses you give can be doubled if the player gets two of them.
maskwa
names {"maskwa platinum ring", "platinum ring","maskwa ring","maskwa","ring"}
title "a Maskwa ring"
descr "A Maskwa platinum ring is laying here."
MATERIAL_METAL("Platinum, and other precious metals")
extra {}
"The ring has a large bear head. Could this be the legendary head of
Maskwa? Any thing formed with its head on it is said to strengthen the
wearer."
type ITEM_WORN
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD, MANIPULATE_WEAR_FINGER}
cost 100 COPPER_PIECE
rent 50 IRON_PIECE
weight 1
STR_TRANSFER(+1)
end
Note: The item type for non-armour worn items is
ITEM_WORN.
Dragon Station with Rooms, NPCs, and Objects
Now we will add the objects we have built to the zone from the previous chapter. This is still not complete while it does compile and you can log into your zone, you still have to load your NPCs and objects but they do not load themselves and they are not dressed with their armour. This will be taken care of in The Reset Section and you will finally have a finished zone. The following is the source file so far.
#include <composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%rooms
chamber
title "The middle chamber of the station"
descr
"This chamber seems to have the entire station rotating around it. It is
unbelievably large the ceiling seems to be a good 200 meters high and
the room is perfectly cubic. Small human size ornate chairs with dragon
designs scrawled on the arms and back are arranged in a triangle like
setting with one large chair at the front. This must be where all
station meetings are held. Large pictures cover the walls depicting
dragons in all kinds of situations. Large passages lead off to the west
and the east."
extra {"chair","chairs"}
"The chairs are made of some metal you don't recognize and every inch is covered
with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture. In the
center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair watching you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to disposal_room descr
"You see a small room.";
east to hallway descr
"You see what looks to be a hallway.";
end
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom. The hallway seems to be dust free. The
walls and the floors seem to be made out of the same sterile
metal-plastic that all space agencies uses. There are large plate glass
windows that open up into space. The hallway is filled with a dim light
that seems to come from everywhere yet no where all at once. You notice
a glimmer of bright light coming from the windows. To the east you see
an air lock and to the west the hallway opens up into a larger room."
extra {"windows","window"}
"Your eyes are drawn to a large ship lit up with running lights sitting
about 1 kilometer from the station."
extra {"floor","walls","wall"}
"Well what can be said it looks to be in perfect condition. what else would
you want to know?"
extra {"large ship" ,"ship"}
"The ship looks really big and is shaped like a dragon. The scales
sparkle and seem to be multiple colors."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station. The room
is as large as the other rooms big enough for Dragons to lounge while
still having a desk in one corner small enough for a humanoid. The
floor along the north wall is lined with some kind of fabric and seems very
soft to walk on, it may be some kind of dragon lounge judging by how large an
area it covers. There is a passage to the west."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"paintings","painting"}
"The paintings are of many dragons and riders in all kinds of tasks from
combat to look out. All the figures seem to be staring at a staff
being held by a depiction of a wizard on the south wall."
extra {"wizard","staff"}
"The wizard has his hand stretched out and it seems there is a place
you can almost grab the staff. Maybe if you searched the staff you would
find it."
extra {"desk"}
"It's a desk alright but there doesn't seem to be any drawers and it
seems totally empty."
extra {"fabric"}
"Wussshhhhh you bound across the comfortable floor wasn't that fun."
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
south to portal_room descr
"You see what looks to be a portal room."
keyword {"air lock door","air lock","staff","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN};
end
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"green field","field"}
"The field looks to be a green fog shifting and churning as you watch.
if you are nuts you could probably enter it."
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
//A link to the portal is also here from room_port
end
ship_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in ship
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"portal_room@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
room_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in portal_room
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"ship@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
disposal_room
title "Red field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a red field right in the center.
there is a door that leads to another room to the east."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"red field","field"}
"The field looks to be a red fog shifting and churning as you watch.
if you are nuts you could probably enter it."
east to chamber descr
"You see the main chamber.";
//A link to the portal is also here from dis_port
end
dis_port
names {"red field","field"}
title "Red field"
descr
"Red Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room to force move to and act
"deathspace@dragonst!You feel your body dissolving for lack of a better
description.",
//true or false random move or not
0);
in disposal_room
end
ship
title "War dragon"
descr
"Blue light softly glows from con duets that line the walls of this ship.
The floors beside the east and west wall have what looks to be soft
fabric covering. The south wall has small controls that seem to be made
for humanoids with two small chairs that look to be pilot seats. view
portals are about 50 meters up the side of the ship on the west and east
wall and some kind of electronic screen covers the south wall. The ship
seems to be a one room ship but there is a green field by the north
wall."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"view port"}
"Sorry you're not 50 meters tall maybe it is made for a dragon?"
extra {"view screen","screen"}
"It seems to be the pilots view screen but you can't seem to see a way
to turn it on."
extra {"controls","control"}
"The controls are in some weird language and you're afraid if you start
pushing buttons you might rocket in to the station or worse slam into
a planet."
extra {"soft fabric","fabric"}
"It looks to be a dragon lounge area."
//A link to the portal is also here from ship_port
end
deathspace
title "Open space"
descr
"You see the ship and the station far off in the distance and you are in Space!"
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy death_room@function (
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//damage
400,
//act for the damage.
"You realize to late that was the trash disposal transporter and you feel
your lungs explode.");
end
%mobiles
bldragon
title "a black dragon"
descr "A big ugly black dragon is clawing the ground here."
names {"big ugly black dragon","ugly black dragon","big black dragon",
"black dragon","dragon"}
extra {}
"The black dragons scales glitter like black granite that has been
polished for years by water. He has a large neck and huge bat like
wings. his eyes watch you as you stand before him. One claw seems to be
tapping slightly on the ground as if the dragon is waiting for
something."
extra {"eye","eyes"}
"The dragons eyes seem to follow you no matter where you go in the room
nothing seems to escape the dragons attention."
extra {"claws","claw"}
"The claw is big black and it looks very deadly. It seems like the
dragon has two sets of 4 large claws and 2 sets of 4 smaller claws which
to say means the claws are about the size of short swords and long
swords."
extra {"scales","scale"}
"It's a scale! Haven't you ever seen a dragon before!"
extra {"bat wings","wings"}
"The dragon sees you looking and flaps his wings creating one heck of a
wind blast."
M_DRAGON_BLACK_OLD(SEX_MALE)
end
janitor
names {"ugly janitor", "janitor", "hobgoblin"}
title "an ugly janitor"
descr "an ugly janitor is walking around, cleaning up."
extra {}
"This ugly green thing looks more goblin than hobgoblin but he seems intent on
cleaning everything around him."
M_AVG_HOBGOBLIN(6, SEX_MALE)
// he is sort of good for cleaning so much
alignment 900
//give him some money
money 5 IRON_PIECE
dilcopy janitor@clashut("disposal_room@dragonst");
// only want him cleaning the station
dilcopy wander_zones@function("dragonst", 20, 1, 1);
end
bob
names {"Bob"}
title "Bob"
descr "Bob the Banker is here, sitting behind the counter."
extra {}
"He has a very serious look on his face."
// define from composed.h
M_SHOP_KEEPER(4, SEX_MALE, RACE_HUMAN)
//discourage people from killing banker
exp -500
flags {UNIT_FL_NO_TELEPORT}
special SFUN_BANK
end
%objects
info_board
title "a merchant information board"
descr "A merchant information Board is mounted on a wall here."
names {"merchant information board","information board","merchant board","board"}
extra {}
"A large flashy black steal board."
MATERIAL_METAL("A very fine quality black steel")
type ITEM_BOARD
dilcopy board@boards("info","","rem_res@boards","",100);
end
w_stiletto
title "a stiletto"
names {"deadly looking stiletto","deadly stiletto","stiletto", "dagger"}
descr "A deadly looking stiletto has been left here."
MATERIAL_METAL("A very fine quality steel")
manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
WEAPON_DEF(WPN_DAGGER, 1, 2)
weight 2
cost 2 GOLD_PIECE
rent 1 COPPER_PIECE
SKILL_TRANSFER(SKI_BACKSTAB, 2)
dilcopy abi_restrict@function (ABIL_DEX,10,0,25,"");
extra {}
"This looks like a thief dream come true. "
extra {"$identify"}
"The stiletto looks magical in nature and seems really sharp. You can
tell if you wield it you would be able to backstab someone really easy."
extra {"$improved identify"}
"The stiletto gives you a magic bonus of +1 and has a quality of +2.
It also raises your back stabbing skill by 2%. You have to have at
least 10% in dex before you can wield this magical weapon."
end
wpn_locker
title "a weapons locker"
names {"weapons locker","weapon locker","locker"}
descr "a small weapons locker hangs on the wall here."
manipulate {MANIPULATE_ENTER}
CONTAINER_DEF(500)
open {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED}
weight 400
MATERIAL_METAL("A very fine quality steel")
extra {}
"It is an ordinary weapons locker that looks like it holds any illegal
weapons that are taken on the station."
end
pol_plate
names {"polished breast plate","polished plate","breast plate","plate"}
title "a polished breast plate"
descr "A polished breast plate has been left here."
extra {}
"This is one shiny plate it seems to be made out of one perfect piece of
metal. There doesn't even seem to be any markings of owner ship."
MATERIAL_METAL("A high luster silver colored metal")
manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_BODY}
ARMOUR_DEF(ARM_PLATE,5,9)
dilcopy abi_restrict@function (ABIL_STR,40,0,25,"");
cost 2 GOLD_PIECE
rent 3 COPPER_PIECE
weight 25
extra {"$identify"}
"This is a high quality plate with a magical feeling."
extra {"$improved identify"}
"The plate has a magical bonus to your defence of a +5 and a quality of
+9. You need 40% in strength to be able to wear it."
end
liq_ration
names {"red bag", "bag", "wine"}
title "a red bag"
descr "A red bag has been gently placed here."
MATERIAL_ORGANIC("a soft plastic")
manipulate {MANIPULATE_TAKE}
LIQ_WINE(1,2,2,0)
cost 2 IRON_PIECE
extra {}
"A small label reads Tassel Grove's finest. Year 321"
extra {"$identify"}
"It's the special wine from Tassel grove a small halfling village on the
planet Valhalla. It seems like a great vintage wine."
end
beef_stick
title "a tough leathery stick"
descr "A tough leathery looking stick is laying here."
names {"tough leathery stick","tough leather stick","leathery stick",
"leather stick","tough stick","stick"}
extra {}
"This has the word BEEF burnt into it."
manipulate {MANIPULATE_TAKE}
FOOD_DEF(5,0)
weight 1
cost 1 COPPER_PIECE
MATERIAL_ORGANIC("tough beef")
end
maskwa
names {"maskwa platinum ring", "platinum ring","maskwa ring","maskwa","ring"}
title "a Maskwa ring"
descr "A Maskwa platinum ring is laying here."
MATERIAL_METAL("Platinum, and other precious metals")
extra {}
"The ring has a large bear head. Could this be the legendary head of
Maskwa? Any thing formed with its head on it is said to strengthen the
wearer."
type ITEM_WORN
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD, MANIPULATE_WEAR_FINGER}
cost 100 COPPER_PIECE
rent 50 IRON_PIECE
weight 1
STR_TRANSFER(+1)
end
%end
Suggested Object Exercises
-
Using information about craftsmanship, magical modifier, and shield fields, create a large shield.
-
Using information about non-armour worn objects and magical transfer macros, create a ring that gives a person 5% strength bonus and removes 5% magic ability.
-
Using information from drink container macros, create a beer or soda from your local area.
-
Using information about light object macros, make an object that gives off a bright light and will never run out.
-
Using the container, food, drink, and money macros, create a chest that can be locked that contains food, drink, a pile of silver pieces, and a pile of iron pieces.
The Reset Section
Once you have learned to build rooms, objects and NPCs, you will find one main missing thing - while you have created NPCs and objects they don’t exist in the game unless you load them. When developing the VME we found that logging on and loading everything for the players to interact with became a very difficult thing to do when we got over 30 items. After many seconds of thought we came up with the idea of a reset section that would do all of this work for us. In fact the reset takes care of closing doors after players have opened them, loading NPCs and their equipment, loading objects by themselves in rooms or even loading objects in objects.
Everything inside the reset section activates once at boot time and then again when the reset time is up and the reset flag is true. These two fields were described in the Zone Source File chapter and are included in the zone header. The reset section is denoted by the symbol %reset and can be placed anywhere but we try to keep it at the end of our zone files. There is no set order you must reset your doors, objects, and NPCs in but I like to do doors first, special reset commands second, objects in rooms third, objects with objects in them fourth, and finally NPCs. You may find that you have a better way of sorting them and again it is up to you.
Door Resets
To show how the door resets work we will revisit an old room example from the Rooms chapter. The following two rooms are linked with a door and at boot time they are reset to closed. When the mud boots the door flags set on the room are the door flags that are used. After boot up time the reset section is where the VME gets its information about what to do with the door.
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station...."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
Now that we have two rooms let’s define the reset command and how it works. All reset commands have a keyword and then a set of arguments. The door reset command is simply door followed by a set of arguments that tell the VME where the door is, which door in that location, and what you want to do with the door. The command looks like this:
door <room symbol> <Direction number> {<door flags>}
Door Argument Explanation
room symbolic: As the name indicates this is the room that the door is located in. If you are resetting a door not in the zone the reset command is in you will need to use a full symbolic name with the zone extension.
// room symbolic in this zone
door myroom ...
// room symbolic in another zone
door out_room@frogwart ...
direction number: The direction number can be one of the pre-defined direction numbers in the file vme.h:
#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3
#define UP 4
#define DOWN 5
#define NORTHEAST 6
#define NORTHWEST 7
#define SOUTHEAST 8
#define SOUTHWEST 9
door flags: These flags, surrounded by {}, describe the state of the door after the reset:
| Flag | Description |
|---|---|
EX_OPEN_CLOSE | Set this if you can open and close this exit, be it a door, gate or otherwise |
EX_CLOSED | Set this if you want the exit to be closed at reset time |
EX_LOCKED | Set this if you want the exit to be locked at reset time |
EX_PICKPROOF | Using this flag renders the ‘pick’ skill and ‘unlock’ spell unusable on the lock |
EX_HIDDEN | If this bit is set, the exit is hidden until the mobile has successfully searched for it |
Note: If you do not specify a key, you can only unlock this door with the ‘pick’ skill, ‘unlock’ spell or from DIL with
UnSet().
Now that we have all the information we need we can close the door after the reset time expires. For our two rooms the door reset would look like this:
door hallway EAST {EX_OPEN_CLOSE, EX_CLOSED}
door office WEST {EX_OPEN_CLOSE, EX_CLOSED}
Note: As you can see from the example it is very important to close both sides of the door. If you do not close both sides you will get very weird and undefined errors when players are trying to open and close them.
Another thing that you can do with the door reset command is change the door’s status. In our previous example we reset the door to its status that it has when it first is loaded into the game. If however we wanted to change the door to a locked door we could do that by adding the locked flag like this:
door hallway EAST {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
door office WEST {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
Loading Objects and NPCs
Time to start loading your zone with its life and all the other strange things you have built. There are two commands that do all the loading and equipping of objects. Oddly enough the commands are called load and equip. The format of the commands are almost the same but equip must be used inside a NPC grouping. With that in mind let’s start with simple loads and work our way up.
The command to load an object or an NPC into a room is as follows:
load <object or NPC> [into] [<room>] [<load amount>]
[{Other loads and equip commands}]
Load Command Arguments
object or NPC: The first argument to the load command is the object or NPC symbolic name that you want to load. The first argument is the only one that must be included in all load commands.
into: This is just a symbol that tells the reset that we are loading the object or NPC into some other unit.
object, NPC, and room: The third argument is the symbolic name of the place where you are loading the object and the NPC.
load amount: The fourth argument is an optional argument that tells the reset how many of the objects are allowed in the world, zone, or locally. The possible values for this field are:
| Modifier | Description |
|---|---|
max <num> | At reset time the entire world is scanned for occurrences of the loaded unit - only if the currently existing number is less than <num> will the command be executed |
local <num> | At reset time the location where the unit is to be loaded is scanned for occurrences - only if the currently existing number is less than <num> will the command be executed |
zonemax <num> | At reset time the entire zone being reset is scanned for occurrences - only if the currently existing number is less than <num> will the command be executed |
Optional grouping: Any reset command may be followed by a pair of curly brackets {} containing more reset commands. The commands inside the brackets will only be executed in case the associated command was successful.
Load Examples
Don’t be alarmed if this sounds a bit hard. It all gets much more clear as some examples are explained.
load udgaard/fido into midgaard/temple max 1
This example is pretty simple - it says load the fido into the temple only if there isn’t already 1 in the world. Now let’s get a bit more complicated:
load udgaard/fido into midgaard/temple max 1
{
load bone
load excrement into midgaard/temple
}
Now we have said again load the fido into the temple if there is not already one in the world. Then if fido loads fill his inventory with a bone and load excrement into the temple as well.
We can get even more complicated but still just using the load commands by doing the following:
load udgaard/fido into midgaard/temple max 1
{
load bone
load excrement into midgaard/temple
load bag
{
load apple max 1
}
}
Now we still have the fido loading if there isn’t one already in the world then the bone and the excrement and finally we load a bag. If there isn’t an apple already in the world we load the bag with an apple in it otherwise the bag will be empty.
The Equip Command
The equip command works a lot like load but has much simpler arguments. The equip command is as follows:
equip <symbol> position [load amount <num>]
symbol: The first argument is just the symbolic name of the item being worn by the NPC.
position: The position is any of the positions available in vme.h:
| Position | Define(s) |
|---|---|
| head | WEAR_HEAD |
| hands | WEAR_HANDS |
| arms | WEAR_ARMS |
| body | WEAR_BODY |
| legs | WEAR_LEGS |
| feet | WEAR_FEET |
| cloak | WEAR_ABOUT |
| shield | WEAR_SHIELD |
| hold | WEAR_HOLD |
| wield | WEAR_WIELD |
| ear | WEAR_EAR_R and WEAR_EAR_L |
| neck | WEAR_NECK_1 and WEAR_NECK_2 |
| wrist | WEAR_WRIST_R and WEAR_WRIST_L |
| finger | WEAR_FINGER_R and WEAR_FINGER_L |
| chest | WEAR_CHEST |
| back | WEAR_BACK |
| waist | WEAR_WAIST |
| ankle | WEAR_ANKLE_R and WEAR_ANKLE_L |
| face | WEAR_FACE |
| shoulders | WEAR_SHOULDERS |
| halo | WEAR_HALO (not for general use) |
| aura | WEAR_AURA (not for general use) |
load amount: The optional load amount works the same as with the load command (max, local, zonemax).
Equip Examples
Now with the equipment command you can now get your NPCs dressed and ready for battle:
load guard into jail
{
equip helmet WEAR_HEAD
equip plate WEAR_BODY
equip pants WEAR_LEGS
equip specialsword WEAR_WIELD max 1
load brass_key
}
This is how you would equip a NPC with all items from the current zone. As you can see we didn’t need full symbolics because the server knows to grab the items from the zone the resets are in.
load guard into safe_room max 2
{
equip plate WEAR_BODY
load powersword max 1
{
load silver_pile into safe_room
}
}
In this example we only load the silver pile if the guard loads and if the power sword loads which may or may not happen since there is only a max of one sword allowed while there is a max of 2 guards allowed. What will happen in this case is at the first reset there will be one guard and one pile of silver. The next reset there will still only be one pile of silver but now there will be two guards.
Special Reset Functions
Now that we have gone over the basic load and equip commands we have some special commands that you can add to them to make them do more interesting things. Sometimes when doing resets you don’t always want items or NPCs to load or sometimes you want them to load but only if a certain amount of other things correctly load. There are also times you want to clear the rooms or reload an entire object after removing the old one. All these things and more can be accomplished with the reset section.
The Complete Directive
The load and equip commands have one more argument that can be placed at the end of them to make them act a bit differently - the complete directive. In the case where this directive is placed at the end of a load or equip command, the unit is only loaded in case all immediate commands inside its nesting are executed successfully. In other words, if one item does not load when the complete directive is used, then nothing will load on that item.
load captain into jail_room complete
{
equip magic_sword WEAR_WIELD max 1
load bag
{
load ruby_ring max 1
}
}
In this case the captain is only loaded if the objects magic_sword and bag are successfully loaded. If the ruby_ring is not loaded, it will have no affect on the complete directive. To make the ruby_ring affect the captain’s complete directive, the bag must also have specified a complete directive (because the bag would then not be complete, and thus the captain would not be complete).
The Follow Command
Once you load a NPC you may want that NPC to follow another NPC. That is what the follow command is for:
follow <symbol> <load amount #> <complete>
symbol: The first argument to the follow command is the symbolic name of the NPC to follow the NPC of the outer grouping.
load amount: The optional load amount works the same as with other commands.
complete: This only makes the NPC follow if all the other things in the grouping finish completely.
The follow command is always used nested inside a loaded NPC to force the NPC <symbol> to follow the NPC of the outer grouping:
load captain into jail
{
follow guard max 4
{
equip guard_helmet WEAR_HEAD
equip guard_plate WEAR_BODY
equip guard_legs WEAR_LEGS
equip guard_boots WEAR_FEET
}
follow guard max 4
{
equip guard_helmet WEAR_HEAD
equip guard_plate WEAR_BODY
equip guard_legs WEAR_LEGS
equip guard_boots WEAR_FEET
}
}
This example would load two guards that are fully dressed and they would start following the captain which is also loaded.
The Purge Command
There are times when you want to clean up a room. This can be done very easily by using the purge command:
purge <symbol>
The symbol is the room you want to empty of all objects and NPCs. If you wanted to get rid of all objects and NPCs from a room with the symbolic name of jail it would look like this:
purge jail
The Random Command
If you ever want to load something only some of the time, there is a built-in random command that allows you to pick the percentage of the time that the item will load:
random <num>
{group or single set of resets}
It is important to point out this is done by a random percentage chance where 1% of the time would be almost not at all and 100% of the time would be all the time. If we wanted to load a group of things only 80% of the time it would look like this:
random 80
{
load captain into jail_room complete
{
equip magic_sword WEAR_WIELD max 1
load bag
{
load ruby_ring max 1
}
}
}
The Remove Command
Many times players take items out of containers like chests or steal items from your NPCs and leave them naked. If the NPC is not dead the resets don’t reload them therefore, your NPCs will stand there empty and so will your chests. This is fine, if that is what you want, but sometimes you want them to get dressed or refilled again at reset time. That is what the remove command is for:
remove <symbol1> in <symbol2>
Again, the remove command is a simple command and it only has two arguments - the item and where it is to remove it from. If you wanted to have a cabinet that at every reset would have a knife and a bag of sugar in it, it would look like this:
remove cabinet in kitchen
load cabinet into kitchen
{
load sugarbag
load knife
}
Reset Walk Through
The dragon station is almost finished. All you have to do now is create the resets for it. We don’t have a lot of stuff in the zone but we have enough to make a decent example of how the resets work. As I mentioned at the start of the chapter on resets I like to do the doors first, the objects in rooms second, then the NPCs. Again this is nothing we force you to do but I find it helps me keep track of my items and NPCs.
Door Resets Example
With that in mind, we will start by resetting our doors. In the zone there are two doors. One is a regular door that is closed when the mud reboots and the other is a hidden and locked door when the mud reboots. The resets for these doors would look like this:
// Office door reset
door hallway EAST {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
door office WEST {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
// Secret door reset
door office SOUTH {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN}
door portal_room NORTH {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED}
Note: Both sides of the door don’t have to have the exact same flags - the door in the office is hidden but the one on the ship is not.
Object Resets Example
The next thing to build resets for is the two items we are loading directly into rooms and their contents if they have any. The two items we are loading into rooms are the board and the weapons locker. I am just going to stick the board in the main chamber and the weapons locker in the office. The reset for these two items looks like this:
load info_board into chamber
load wpn_locker into office
{
load w_stiletto
}
Notice we also loaded a stiletto into the weapons locker and it will only load once a reboot since the cabinet will never be removed and unless the cabinet reloads the stiletto will not reload.
NPC Resets Example
Finally we get to the NPCs and their equipment. We only have 3 NPCs in our zone so it shouldn’t be any problem especially since we don’t have that much clothes. I am going to load the dragon into the ship on a percentage chance basis and then load the Janitor into the station so he can get to cleaning it up. Finally I will load Bob into the office so he can sit and count his money.
load bob into office
{
equip pol_plate WEAR_BODY
}
load janitor into chamber
{
equip pol_plate WEAR_BODY
}
random 50
{
load bldragon into ship
{
load maskwa
}
}
Only a couple final things to point out. It doesn’t matter if you load the same type of plate or same type of clothing on every NPC. It would look pretty silly if everyone was wearing the same clothes but I wanted to make sure you understood you didn’t have to make one set for everyone. Also you don’t have to equip wearable things - you can load them into the inventory like we did with the ring on the dragon. That about covers it all. The resets are now done and we can now put them all together with the zone and complete our dragon station.
The Complete Dragon Station
#include <composed.h>
%zone dragonst
lifespan 20
reset RESET_ANYHOW
creators {"whistler"}
notes
"This is the dragon station I shortened it to dragonst for ease in
loading. If you have any questions email me at admin@example.com"
help
"Not sure what could help you now. You are stuck on one of the
weirdest space stations you have ever seen and you smell burning
sulfur."
%rooms
chamber
title "The middle chamber of the station"
descr
"This chamber seems to have the entire station rotating around it. It is
unbelievably large the ceiling seems to be a good 200 meters high and
the room is perfectly cubic. Small human size ornate chairs with dragon
designs scrawled on the arms and back are arranged in a triangle like
setting with one large chair at the front. This must be where all
station meetings are held. Large pictures cover the walls depicting
dragons in all kinds of situations. Large passages lead off to the west
and the east."
extra {"chair","chairs"}
"The chairs are made of some metal you don't recognize and every inch is covered
with some kind of dragon."
extra {"dragon picture","picture"}
"Thousands of dragons dot the skies of this rather life like picture. In the
center you see something move. It looks to be a little green dragon."
extra {"green dragon","dragon","green"}
"An intelligent looking dragon is sitting perched on a large chair watching you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to disposal_room descr
"You see a small room.";
east to hallway descr
"You see what looks to be a hallway.";
end
hallway
title "Module tunnel"
descr "The hallway is about 50 meters long and around 100 meters from
side to side and top to bottom. The hallway seems to be dust free. The
walls and the floors seem to be made out of the same sterile
metal-plastic that all space agencies uses. There are large plate glass
windows that open up into space. The hallway is filled with a dim light
that seems to come from everywhere yet no where all at once. You notice
a glimmer of bright light coming from the windows. To the east you see
an air lock and to the west the hallway opens up into a larger room."
extra {"windows","window"}
"Your eyes are drawn to a large ship lit up with running lights sitting
about 1 kilometer from the station."
extra {"floor","walls","wall"}
"Well what can be said it looks to be in perfect condition. What else would
you want to know?"
extra {"large ship" ,"ship"}
"The ship looks really big and is shaped like a dragon. The scales
sparkle and seem to be multiple colors."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
west to chamber descr
"The hallway opens up into a chamber.";
east to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
end
office
title "The station office"
descr
"Large paintings fill the walls of this part of the station. The room
is as large as the other rooms big enough for Dragons to lounge while
still having a desk in one corner small enough for a humanoid. The
floor along the north wall is lined with some kind of fabric and seems
very soft to walk on, it may be some kind of dragon lounge judging by
how large an area it covers. There is a passage to the west."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"paintings","painting"}
"The paintings are of many dragons and riders in all kinds of tasks from
combat to look out. All the figures seem to be staring at a staff
being held by a depiction of a wizard on the south wall."
extra {"wizard","staff"}
"The wizard has his hand stretched out and it seems there is a place
you can almost grab the staff. Maybe if you searched the staff you would
find it."
extra {"desk"}
"It's a desk alright but there doesn't seem to be any drawers and it
seems totally empty."
extra {"fabric"}
"Wussshhhhh you bound across the comfortable floor wasn't that fun."
west to hallway descr
"You see what looks to be a hallway."
keyword {"air lock door","air lock","door"}
open {EX_OPEN_CLOSE, EX_CLOSED};
south to portal_room descr
"You see what looks to be a portal room."
keyword {"air lock door","air lock","staff","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED, EX_HIDDEN};
end
portal_room
title "Green field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a green field right in the center.
there is a door that leads to another room to the north."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"green field","field"}
"The field looks to be a green fog shifting and churning as you watch.
if you are nuts you could probably enter it."
north to office descr
"You see what looks to be an office."
keyword {"air lock door","air lock","door"}
key nokey
difficulty 50
open {EX_OPEN_CLOSE, EX_CLOSED, EX_LOCKED};
//A link to the portal is also here from room_port
end
ship_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in ship
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"portal_room@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
room_port
names {"green field", "field"}
title "Green field"
descr
"Green Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
in portal_room
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room and act
"ship@dragonst!You feel your body dissolving for lack of a better
description.&nYou appear on the deck of a ship.",
//True or False for randomizing or not
FALSE);
end
disposal_room
title "Red field room"
descr
"Like the other rooms on the station this one is large enough for
dragons to comfortably fit in. The strange thing about this room though
is it is totally empty except for a red field right in the center.
there is a door that leads to another room to the east."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"red field","field"}
"The field looks to be a red fog shifting and churning as you watch.
if you are nuts you could probably enter it."
east to chamber descr
"You see the main chamber.";
//A link to the portal is also here from dis_port
end
dis_port
names {"red field","field"}
title "Red field"
descr
"Red Mist swirls about you."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy force_move@function(
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//room to force move to and act
"deathspace@dragonst!You feel your body dissolving for lack of a better
description.",
//true or false random move or not
0);
in disposal_room
end
ship
title "War dragon"
descr
"Blue light softly glows from con duets that line the walls of this ship.
The floors beside the east and west wall have what looks to be soft
fabric covering. The south wall has small controls that seem to be made
for humanoids with two small chairs that look to be pilot seats. View
portals are about 50 meters up the side of the ship on the west and east
wall and some kind of electronic screen covers the south wall. The ship
seems to be a one room ship but there is a green field by the north
wall."
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
extra {"view port"}
"Sorry you're not 50 meters tall maybe it is made for a dragon?"
extra {"view screen","screen"}
"It seems to be the pilot's view screen but you can't seem to see a way
to turn it on."
extra {"controls","control"}
"The controls are in some weird language and you're afraid if you start
pushing buttons you might rocket in to the station or worse slam into
a planet."
extra {"soft fabric","fabric"}
"It looks to be a dragon lounge area."
//A link to the portal is also here from ship_port
end
deathspace
title "Open space"
descr
"You see the ship and the station far off in the distance and you are in Space!"
movement SECT_INSIDE
ALWAYS_LIGHT
flags {UNIT_FL_NO_WEATHER, UNIT_FL_INDOORS}
dilcopy death_room@function (
//Time in ticks (PULSE_SEC*seconds), minimum 12 ticks (3 sec)
PULSE_SEC*4,
//damage
400,
//act for the damage.
"You realize too late that was the trash disposal transporter and you feel
your lungs explode.");
end
%mobiles
bldragon
title "a black dragon"
descr "A big ugly black dragon is clawing the ground here."
names {"big ugly black dragon","ugly black dragon","big black dragon",
"black dragon","dragon"}
extra {}
"The black dragons scales glitter like black granite that has been
polished for years by water. He has a large neck and huge bat like
wings. His eyes watch you as you stand before him. One claw seems to be
tapping slightly on the ground as if the dragon is waiting for
something."
extra {"eye","eyes"}
"The dragon's eyes seem to follow you no matter where you go in the room
nothing seems to escape the dragon's attention."
extra {"claws","claw"}
"The claw is big black and it looks very deadly. It seems like the
dragon has two sets of 4 large claws and 2 sets of 4 smaller claws which
to say means the claws are about the size of short swords and long
swords."
extra {"scales","scale"}
"It's a scale! Haven't you ever seen a dragon before!"
extra {"bat wings","wings"}
"The dragon sees you looking and flaps his wings creating one heck of a
wind blast."
M_DRAGON_BLACK_OLD(SEX_MALE)
end
janitor
names {"ugly janitor", "janitor", "hobgoblin"}
title "an ugly janitor"
descr "an ugly janitor is walking around, cleaning up."
extra {}
"This ugly green thing looks more goblin than hobgoblin but he seems intent
on cleaning everything around him."
M_AVG_HOBGOBLIN(6, SEX_MALE)
// he is sort of good for cleaning so much
alignment 900
//give him some money
money 5 IRON_PIECE
dilcopy janitor@clashut("disposal_room@dragonst");
// only want him cleaning the station
dilcopy wander_zones@function("dragonst", 20, 1, 1);
end
bob
names {"Bob"}
title "Bob"
descr "Bob the Banker is here, sitting behind the counter."
extra {}
"He has a very serious look on his face."
// define from composed.h
M_SHOP_KEEPER(4, SEX_MALE, RACE_HUMAN)
//discourage people from killing banker
exp -500
flags {UNIT_FL_NO_TELEPORT}
special SFUN_BANK
end
%objects
info_board
title "a merchant information board"
descr "A merchant information Board is mounted on a wall here."
names {"merchant information board","information board","merchant board","board"}
extra {}
"A large flashy black steal board."
MATERIAL_METAL("A very fine quality black steel")
type ITEM_BOARD
dilcopy board@boards("info","","rem_res@boards","",100);
end
w_stiletto
title "a stiletto"
names {"deadly looking stiletto","deadly stiletto","stiletto", "dagger"}
descr "A deadly looking stiletto has been left here."
MATERIAL_METAL("A very fine quality steel")
manipulate {MANIPULATE_TAKE, MANIPULATE_WIELD}
WEAPON_DEF(WPN_DAGGER, 1, 2)
weight 2
cost 2 GOLD_PIECE
rent 1 COPPER_PIECE
SKILL_TRANSFER(SKI_BACKSTAB, 2)
dilcopy abi_restrict@function (ABIL_DEX,10,0,25,"");
extra {}
"This looks like a thieves dream come true. "
extra {"$identify"}
"The stiletto looks magical in nature and seems really sharp. You can
tell if you wield it you would be able to backstab someone really easy."
extra {"$improved identify"}
"The stiletto gives you a magical bonus of +1 and has a quality of +2.
It also raises your back stabbing skill by 2%. You have to have at
least 10% in dex before you can wield this magical weapon."
end
wpn_locker
title "a weapons locker"
names {"weapons locker","weapon locker","locker"}
descr "a small weapons locker hangs on the wall here."
manipulate {MANIPULATE_ENTER}
CONTAINER_DEF(500)
open {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED}
weight 400
MATERIAL_METAL("A very fine quality steel")
extra {}
"It is an ordinary weapons locker that looks like it holds any illegal
weapons that are taken on the station."
end
pol_plate
names {"polished breast plate","polished plate","breast plate","plate"}
title "a polished breast plate"
descr "A polished breast plate has been left here."
extra {}
"This is one shiny plate it seems to be made out of one perfect piece of
metal. There doesn't even seem to be any markings of owner ship."
MATERIAL_METAL("A high luster silver colored metal")
manipulate {MANIPULATE_TAKE, MANIPULATE_WEAR_BODY}
ARMOUR_DEF(ARM_PLATE,5,9)
dilcopy abi_restrict@function (ABIL_STR,40,0,25,"");
cost 2 GOLD_PIECE
rent 3 COPPER_PIECE
weight 25
extra {"$identify"}
"This is a high quality plate with a magical feeling."
extra {"$improved identify"}
"The plate has a magical bonus to your defence of a +5 and a quality of
+9. You need 40% in strength to be able to wear it."
end
liq_ration
names {"red bag", "bag", "wine"}
title "a red bag"
descr "A red bag has been gently placed here."
MATERIAL_ORGANIC("a soft plastic")
manipulate {MANIPULATE_TAKE}
LIQ_WINE(1,2,2,0)
cost 2 IRON_PIECE
extra {}
"A small label reads Tassel Grove's finest. Year 321"
extra {"$identify"}
"It's the special wine from Tassel grove a small halfling village on the
planet Valhalla. It seems like a great vintage wine."
end
beef_stick
title "a tough leathery stick"
descr "A tough leathery looking stick is laying here."
names {"tough leathery stick","tough leather stick","leathery stick",
"leather stick","tough stick","stick"}
extra {}
"This has the word BEEF burnt into it."
manipulate {MANIPULATE_TAKE}
FOOD_DEF(5,0)
weight 1
cost 1 COPPER_PIECE
MATERIAL_ORGANIC("tough beef")
end
maskwa
names {"maskwa platinum ring", "platinum ring","maskwa ring","maskwa","ring"}
title "a Maskwa ring"
descr "A Maskwa platinum ring is laying here."
MATERIAL_METAL("Platinum, and other precious metals")
extra {}
"The ring has a large bear head. Could this be the legendary head of
Maskwa? Any thing formed with its head on it is said to strengthen the
wearer."
type ITEM_WORN
manipulate {MANIPULATE_TAKE, MANIPULATE_HOLD, MANIPULATE_WEAR_FINGER}
cost 100 COPPER_PIECE
rent 50 IRON_PIECE
weight 1
STR_TRANSFER(+1)
end
%reset
//Office door reset
door hallway EAST {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED}
door office WEST {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED}
//secret door reset
door office SOUTH {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED,EX_HIDDEN}
door portal_room NORTH {EX_OPEN_CLOSE, EX_CLOSED,EX_LOCKED}
load info_board into chamber
load wpn_locker into office
{
load w_stiletto
}
load bob into office
{
equip pol_plate WEAR_BODY
}
load janitor into chamber
{
equip pol_plate WEAR_BODY
}
random 50
{
load bldragon into ship
{
load maskwa
}
}
%end
Color and Formatting Codes
Now that you have a handle on how to build rooms, objects, and NPCs, let’s see how to make text look the way you want it to. You can format and color it. Currently the VME doesn’t support all the ASCII characters but if we get enough people wanting this ability it will be added.
The Escape Character
There are always two parts to a formatting command. The first part we call the escape character which is the & character. Thus all formatting and color commands would look as follows:
&<color or formatting command>
Formatting Codes
As you may have noticed, the string fields on the VME are formatted in an English paragraph style. What that means is all text is formatted with the following rules:
- All leading blanks are stripped away. For room descriptions three leading spaces are added. This way, we ensure a consistent formatting of the displayed room descriptions.
- Spaces and blanks (newlines) are contracted to single spaces yielding a correctly ‘wrapped’ text for any sentence.
- If a ‘.’ is encountered followed by a blank, a total of two spaces are inserted after the ‘.’.
These formatting rules are great for normal descriptions and extras; but, what if you want to make a sign or a map? You don’t always want wrapped text. If the server wrapped your sign it would turn out looking like a jumble of punctuation in the form of a paragraph.
Formatting and Color Codes Summary
| Code | Description |
|---|---|
&& | Used to make an ampersand & character instead of an escape code |
&l | Text from this point forward will not be formatted by the server. It will be interpreted literally with newlines, spaces, etc. Useful when making a sign or a map |
&f | Text from this point forward will be formatted by the server. This option is the reverse of &l and is default on any section of text |
&s<#> | Force a single space character (or <#> if specified, may come in handy instead of having to toggle formatting) |
&n | Force a new line, very handy instead of toggling the &l formatting switch |
&h | Clears the screen if the terminal of the user supports it |
&x | A file new line used for split so that you can split a file into lines |
&c<color> | Set the foreground color |
&b<color> | Set the background color |
&[<color>] | Set a preset foreground and background color |
&{w} | Start web-only content block (only shown to web client users) |
&{/w} | End web-only content block |
Formatting Code Descriptions and Examples
&&
If you want a single & you must let the VME know that you don’t want a formatting or a color code. You do this by doubling the & sign. Here are a couple examples:
| Text | Result |
|---|---|
&& | & |
&&&& | && |
&&&&&& | &&& |
&l
When you want to turn off the formatting you use this formatting code. Everything after the &l will be shown exactly as you put it in the string.
&l
* *
* *
* *
*
* *
* *
* *
&f
The formatted text as we have already said is default. If you want to turn the formatted text back on after some literal text like a sign or a map you just use the &f code. The following is an example of some literal text followed by a short bit of formatted text.
&l
* *
* *
* *
*
* *
* *
* *
&fThe X marks the spot!
&s<#>
If you want to input extra spaces in a sentence without using the &l you can add them one at a time or multiple by using the &s code.
This sentence has 10 spaces&s10before the first word before.
&n
If you want to input some blank lines without using the literal code you can add a &n for each line you want.
This sentence&n&n&n would look like this:
This sentence
would look like this:
&x
The line break is made for use with the DIL language. You will not need it to do regular text formatting. It was added so a DIL could split a string that is loaded from a file. If you don’t understand the following example don’t worry it is explained more in the DIL reference.
mystrlist := split(string, "&x");
&h
On terminals that can handle it the &h will clear the screen. If you wanted a sign that would clear the screen before displaying when a character looked at it would look like this:
&h&l
* *
* *
* *
*
* *
* *
* *
&fThe X marks the spot!
&{w} and &
These codes create web-only content blocks. Text between &{w} and &{/w} is only shown to players using the web client - telnet users will not see it.
This is useful for adding clickable links, images, or other HTML-specific content that wouldn’t work on telnet clients.
extra {}
"A notice board hangs on the wall.
&{w}
<a href='https://example.com/rules'>Click here for guild rules</a>
&{/w}"
Telnet users see only “A notice board hangs on the wall.” while web users also see the clickable link.
Color Code Descriptions and Examples
&c and &b
In order to allow you to change the colors there are two codes. One is for the foreground color (&c) and the other is for the background color (&b). Both support an optional modifier for brightness or variation. They have the forms as follows:
&c<modifier><color>
&b<modifier><color>
It is important to set both the foreground and background color because if a player has their default background color set to blue and you use blue as a foreground color it will make the letters invisible to the player. It is also important to set the colors back to the default color when done. This is done by using the following command:
&[default]
Note: The
&[default]command will be described in the next section. It is enough to know for now that it will return the player’s colors to their default colors.
Before we give some color examples we should define the symbols for brightness and the symbols for each color and what they are.
Color Codes
| Code | Color |
|---|---|
n | Black |
r | Red |
g | Green |
y | Yellow |
b | Blue |
m | Magenta |
c | Cyan |
w | White |
o | Orange |
p | Pink |
Modifier
+= Bright-= Variation (an alternative shade of the color)- No prefix = Normal
Sample Color Codes
| Code | Description |
|---|---|
&cb&bw | Blue foreground on white background |
&c+g&bn | Bright green foreground on black background |
&c+w&br | Bright white foreground on red background |
&c+w&bn | Bright white foreground on black background |
&c-r&bn | Variation red foreground on black background |
Xterm 256 Color Support
For more precise color control, xterm 256 colors are supported:
| Code | Description |
|---|---|
&c#NNN | Foreground xterm 256 color by number (0-255) |
&b#NNN | Background xterm 256 color by number (0-255) |
&c[name] | Foreground by xterm 256 color name |
&b[name] | Background by xterm 256 color name |
Example: &c#196 or &c[cherrytomato] for bright red foreground.
See the Xterm 256 Color Reference for a complete list of color codes and names.
Note: Players on ANSI terminals that do not support xterm 256 colors will automatically receive the nearest ANSI 16-color equivalent. No special handling is required in zone files.
&[<color>]
As we have said in the previous section, if you’re not careful you can make your text not visible to the player by inadvertently setting the foreground to the same color as the player’s background. To make it easy for you to change how the color looks and even match it with the way players have their colors set already, we created colors that the players can set and you can use. The VME comes with a default list of colors which can be added to by either the color.def or even by a DIL program online. The default colors are as follows:
| Color Name |
|---|
| death |
| default |
| exit |
| group |
| hit_me |
| hit_opponent |
| hit_other |
| immort_descr |
| immort_title |
| log |
| mail_header |
| miss_me |
| miss_opponent |
| miss_other |
| nodam_me |
| nodam_opponent |
| nodam_other |
| npc_descr |
| npc_title |
| obj_descr |
| obj_title |
| paging |
| pc_descr |
| pc_title |
| prompt |
| respond |
| room_descr |
| room_title |
| say_other |
| say_self |
| shield_me |
| shield_opponent |
| shield_other |
| shout_other |
| shout_self |
| social_other |
| social_self |
| spells |
| tell_group |
| tell_imm |
| tell_other |
| tell_self |
| time |
| weather |
| whisper |
| who |
| who_guild |
| who_inv |
| who_name |
| who_title |
| wiz |
| xpgain |
To use these colors all you have to do is use the following formatting command:
&[color]
The color that will be shown is the color that the player has set for the color in question. If for example the player has his or her ‘death’ color set to bright red with a black background and you have a description as follows:
descr
"This is a &[death]death&[room_descr] room"
The description would be in the player’s ‘room_descr’ color while the word death would be in his or hers ‘death’ color. You should note we had to set the color back to the room description color so that the rest of the description was not in the ‘death’ color.
To change the player’s color to the default output color (which is the color that is used when no color is specified by the server) then you use default. You probably won’t use this in normal zone building but it is very important to know it exists when you start making spells, skills, and commands with DIL.
VMC Command Line Options
The argument string is processed from left to right. Options may appear between filenames, but it should be noted that an option only takes effect when it is encountered. In most cases, options should be placed to the left of the filename arguments.
| Option | Description |
|---|---|
-m | Make option. Only compile source files if they have been modified more recently than the corresponding output files. |
-s | Suppress the generation of output files. |
-v | Verbose compiler output shows much more information about objects and NPCs. |
-l | Treat warnings as fatal errors. |
-p | Preprocess the file only, output to stdout. |
-q | Quiet compile (suppress messages). |
-h | Show help. |
-I<dir> | Add directory to search for include files. |
-d<path> | Specify location of the money file (normally etc/money). |
Reserved Keyword Listing
The following keywords are reserved and cannot be used as symbol names:
| Keyword |
|---|
| ability |
| affect |
| alignment |
| applyf |
| armour |
| attack |
| bits |
| bright |
| capacity |
| complete |
| cost |
| creators |
| data |
| default |
| defensive |
| descr |
| difficulty |
| dilcopy |
| door |
| duration |
| end |
| equip |
| exit |
| exp |
| extra |
| firstf |
| flags |
| follow |
| gmap |
| height |
| help |
| hit |
| id |
| in |
| inside_descr |
| into |
| key |
| keyword |
| lastf |
| level |
| lifespan |
| light |
| link |
| load |
| local |
| mana |
| manipulate |
| max |
| minv |
| money |
| movement |
| names |
| nop |
| notes |
| offensive |
| open |
| outside_descr |
| position |
| purge |
| race |
| random |
| remove |
| rent |
| reset |
| romflags |
| sex |
| special |
| speed |
| spell |
| string |
| tickf |
| time |
| title |
| to |
| type |
| value |
| weapon |
| weather |
| weight |
| zonemax |
Race Definitions in values.h
The following list was extracted from values.h:
#define RACE_MAMMAL_MIN 0
#define MIN_HUMANOID_PC 0
#define RACE_HUMAN 0 /* PC race */
#define RACE_ELF 1 /* PC race */
#define RACE_DWARF 2 /* PC race */
#define RACE_HALFLING 3 /* PC race */
#define RACE_GNOME 4 /* PC race */
#define RACE_HALF_ORC 5 /* PC race */
#define RACE_HALF_OGRE 6 /* PC race */
#define RACE_HALF_ELF 7 /* PC race */
#define RACE_BROWNIE 8 /* PC race */
#define RACE_GROLL 9 /* PC race */
#define RACE_DARK_ELF 10 /* PC race */
#define RACE_PARNON 11 /* PC race */
#define MAX_HUMANOID_PC 49
#define MIN_HUMANOID_NPC 50
#define RACE_DRACONIAN 51
#define RACE_SKAVEN 120
#define RACE_GNOLL 121
#define RACE_GOBLIN 122
#define RACE_HOBGOBLIN 123
#define RACE_KOBOLD 124
#define RACE_NIXIE 125
#define RACE_NYMPH 126
#define RACE_OGRE 127
#define RACE_ORC 128
#define RACE_SATYR 129
#define RACE_FAUN 130
#define RACE_SPRITE 131
#define RACE_DRYAD 132
#define RACE_LEPRECHAUN 133
#define RACE_PIXIE 134
#define RACE_SYLPH 135
#define RACE_HERMIT 136
#define RACE_SHARGUGH 137
#define RACE_GIANT 138
#define RACE_WARDEN 139
#define RACE_TROLL 140
#define RACE_NORSE_GOD 142
#define RACE_MERMAID 145
#define RACE_SIREN 146
#define RACE_NAIAD 147
#define RACE_MERMAN 148
#define RACE_MINOTAUR 149
#define RACE_YETI 150
#define RACE_KINGRAITH 151
#define RACE_TANNARI 153
#define RACE_GIANT_MOB 155
#define RACE_OTHER_HUMANOID 199
#define MAX_HUMANOID_NPC 199
#define RACE_BEE 221
#define RACE_INSECT 226
#define RACE_MANTIS 227
#define RACE_TRIPHID 231
#define RACE_JELLYFISH 301
#define RACE_MINNOW 401
#define RACE_PIRANHA 402
#define RACE_BARACUDA 403
#define RACE_CROCODILE 503
#define RACE_GOOSE 605
#define RACE_PIGEON 607
#define RACE_PEACOCK 608
#define RACE_OSTRICH 609
#define RACE_SEAGULL 611
#define RACE_SWAN 612
#define RACE_TURKEY 613
#define RACE_BEAVER 704
#define RACE_CHIPMUNK 708
#define RACE_HAMSTER 717
#define RACE_MOLE 722
#define RACE_MOOSE 724
#define RACE_MOUNTAIN_LION 725
#define RACE_RACCOON 729
#define RACE_RHINO 731
#define RACE_SHEEP 733
#define RACE_WALRUS 739
#define RACE_WEASLE 740
#define RACE_WARTHOG 745
#define RACE_TUMBLEWEED 902
#define RACE_PEPPER 904
#define RACE_RASPBERRY 905
#define RACE_CARROT 906
#define RACE_BLUEBERRY 908
#define RACE_LOSKA 920
#define RACE_PUMPKIN 922
#define RACE_BEAN 923
#define RACE_STRAWBERRY 924
#define RACE_POTATO 925
#define RACE_TOMATO 926
#define RACE_CABBAGE 927
#define RACE_LETTUCE 928
#define RACE_WHEAT 929
#define RACE_CORN 930
#define RACE_ACIDPLANT 940
#define RACE_PLANT_GROW 942
#define RACE_BEAR 1000
#define RACE_DOG 1001
#define RACE_WOLF 1002
#define RACE_FOX 1003
#define RACE_CAT 1004
#define RACE_RABBIT 1005
#define RACE_DEER 1006
#define RACE_COW 1007
#define RACE_HARE 1008
#define RACE_GOAT 1009
#define RACE_EAGLE 1010
#define RACE_PIG 1011
#define RACE_DUCK 1100
#define RACE_BIRD 1101
#define RACE_RAT 1102
#define RACE_HORSE 1103
#define RACE_BADGER 1104
#define RACE_SKUNK 1105
#define RACE_BOAR 1106
#define RACE_MOUSE 1107
#define RACE_MONKEY 1108
#define RACE_PORCUPINE 1110
#define RACE_ELEPHANT 1112
#define RACE_CAMEL 1113
#define RACE_FERRET 1114
#define RACE_VULTURE 1115
#define RACE_SQUIRREL 1116
#define RACE_OWL 1117
#define RACE_LEMURE 1118 /* Half-monkey (Makier) */
#define RACE_ELK 1119 /* Larger deer (Whapiti-deer) */
#define RACE_LION 1120
#define RACE_TIGER 1121
#define RACE_LEOPARD 1122
#define RACE_LLAMA 1123
#define RACE_SEAL 1124
#define RACE_CHICKEN 1500
#define RACE_TORTOISE 1900
#define RACE_OTHER_MAMMAL 1999
#define RACE_MAMMAL_MAX 1999
#define RACE_TREE 2000
#define RACE_VINE 2001
#define RACE_FLOWER 2002
#define RACE_SEAWEED 2003
#define RACE_CACTUS 2004
#define RACE_OTHER_PLANT 2999
#define RACE_MAGGOT 3000
#define RACE_BEETLE 3001
#define RACE_SPIDER 3002
#define RACE_COCKROACH 3003
#define RACE_BUTTERFLY 3004
#define RACE_ANT 3005
#define RACE_WORM 3006
#define RACE_LEECH 3008
#define RACE_DRAGONFLY 3009
#define RACE_MOSQUITO 3010
#define RACE_OTHER_INSECT 3999
#define RACE_LIZARD 4000
#define RACE_SNAKE 4001
#define RACE_FROG 4002
#define RACE_ALLIGATOR 4004
#define RACE_DINOSAUR 4005
#define RACE_CHAMELEON 4006
#define RACE_SCORPION 4007
#define RACE_TURTLE 4008
#define RACE_BAT 4009
#define RACE_TOAD 4010
#define RACE_WYVERN 4200
#define RACE_WOLFMAN 4201
#define RACE_OTHER_REPTILE 4999
#define RACE_CAVE_WIGHT 5001
#define RACE_UR_VILE 5002
#define RACE_STONE_RENDER 5003
#define RACE_VAMPIRE 5005
#define RACE_SLIME 5006
#define RACE_WYRM 5007
#define RACE_AUTOMATON 5008
#define RACE_UNICORN 5009
#define RACE_DRAGON_MIN 5010
#define RACE_DRAGON_BLACK 5010
#define RACE_DRAGON_BLUE 5011
#define RACE_DRAGON_GREEN 5012
#define RACE_DRAGON_RED 5013
#define RACE_DRAGON_WHITE 5014
#define RACE_DRAGON_SILVER 5015
#define RACE_DRAGON_TURTLE 5016
#define RACE_DRAGON_LAVA 5017
#define RACE_DRAGON_SHADOW 5018
#define RACE_DRAGON_LIZARD 5019
#define RACE_DRAGON_MAX 5020
#define RACE_LESSER_DEMON 5020 /* Approx. Level < 100 */
#define RACE_GREATER_DEMON 5021 /* Approx. Level > 100 */
#define RACE_SERVANT_DEMON 5022 /* Approx. Level < 20 */
#define RACE_PRINCE_DEMON 5023 /* Almost god, max level 149 */
#define RACE_LESSER_DEVIL 5025 /* Approx. Level < 100 */
#define RACE_GREATER_DEVIL 5026 /* Approx. Level > 100 */
#define RACE_SHADOW_DEVIL 5027
#define RACE_ARCH_DEVIL 5028
#define RACE_DRAGON 5029
#define RACE_MEDUSA 5030
#define RACE_WINGED_HORSE 5031
#define RACE_GARGOYLE 5033
#define RACE_GOLEM 5034
#define RACE_YOGOLOTH 5035
#define RACE_MIST_DWELLER 5036
#define RACE_WEREWOLF 5037
#define RACE_WERERAT 5038
#define RACE_GRIFFON 5039
#define RACE_ELEMENTAL_AIR 5040
#define RACE_ELEMENTAL_EARTH 5041
#define RACE_ELEMENTAL_FIRE 5042
#define RACE_ELEMENTAL_FROST 5043
#define RACE_ELEMENTAL_WATER 5044
#define RACE_ELEMENTAL_LIGHT 5045
#define RACE_MARDAGG 5050
#define RACE_STONE_GUARDIAN 5051
#define RACE_HELLHOUND 5090
#define RACE_OOZE 5091
#define RACE_DEVOURER 5600
#define RACE_DANALEK 5601
#define RACE_SLOTH 5602
#define RACE_FAMILIAR 5900
#define RACE_VALHERU_MOUNT 5910
#define RACE_OTHER_CREATURE 5999
#define RACE_ZOMBIE 6000
#define RACE_LICH 6001
#define RACE_GHOUL 6002
#define RACE_SKELETON 6003
#define RACE_GHOST 6004
#define RACE_SPIRIT 6005
#define RACE_MUMMIE 6006
#define RACE_BANSHEE 6007
#define RACE_NAGA_SOUL 6008
#define RACE_SHADOW_BEAST 6009
#define RACE_DEATH_GHAST 6010
#define RACE_WIZARD 6555
#define RACE_WIZARD_FAMILIAR 6556
#define RACE_WIZARD_GUARDIAN 6557
#define RACE_MUTANT_ABOM 6655
#define RACE_MUTANT_REPTILE 6656
#define RACE_OTHER_UNDEAD 6999
#define RACE_CRAB 7000
#define RACE_SAND_SPIDER 7002
#define RACE_RIVER_LEECH 7003
#define RACE_SAND_CRAWLER 7004
#define RACE_SEA_HORSE 7005
#define RACE_SHARK 7006
#define RACE_LAMPREY 7007
#define RACE_MANTA_RAY 7008
#define RACE_CLIFF_HUGGER 7009
#define RACE_ALGAE_MAN 7010
#define RACE_WHELK 7011
#define RACE_OYSTER 7012
#define RACE_KRAKEN 7013
#define RACE_CAVE_FISHER 7014 /* Lobster/spider breed */
#define RACE_OCTOPUS 7015
#define RACE_WHALE 7016
#define RACE_DOLPHIN 7017
#define RACE_EEL 7018
#define RACE_SQUID 7500
#define RACE_FISH 7998
#define RACE_OTHER_MARINE 7999
#define RACE_DROW 9978
#define RACE_ILLYTHID 9979
#define RACE_MONGRELMAN 9980
#define RACE_DRIDER 9981
#define RACE_ELEMENTALS_REX 9992
#define RACE_VORTEX_REX 9994
#define RACE_DRHEAD_REX 9995
#define RACE_DR_BODY_REX 9996
#define RACE_ELEMENTAL_GENIE 9997
Weapon Definitions in values.h
The following list was extracted from values.h:
#define WPN_BATTLE_AXE 7 /* Two Handed */
#define WPN_HAND_AXE 8
#define WPN_WAR_MATTOCK 9 /* Two Handed */
#define WPN_WAR_HAMMER 10
#define WPN_GREAT_SWORD 11 /* Two Handed */
#define WPN_SCIMITAR 12
#define WPN_KATANA 13
#define WPN_FALCHION 14
#define WPN_KOPESH 15
#define WPN_BROAD_SWORD 16
#define WPN_LONG_SWORD 17
#define WPN_RAPIER 18
#define WPN_SHORT_SWORD 19
#define WPN_DAGGER 20
#define WPN_BATTLE_MACE 21 /* Two Handed */
#define WPN_MACE 22
#define WPN_BATTLE_CLUB 23 /* Two handed */
#define WPN_CLUB 24
#define WPN_MORNING_STAR 25
#define WPN_FLAIL 26
#define WPN_QUARTERSTAFF 27
#define WPN_SPEAR 28
#define WPN_HALBERD 29
#define WPN_BARDICHE 30
#define WPN_SICKLE 31
#define WPN_SCYTHE 32 /* Two handed */
#define WPN_TRIDENT 33
#define WPN_FIST 34
#define WPN_KICK 35
#define WPN_BITE 36
#define WPN_STING 37
#define WPN_CLAW 38
#define WPN_CRUSH 39
#define WPN_WHIP 40
#define WPN_WAKIZASHI 41
#define WPN_BOW 42
#define WPN_CROSSBOW 43
#define WPN_SLING 44
#define WPN_FIGHTING_STAFF 45 /* Two handed */
#define WPN_SABER 46
#define WPN_CUTLASS 47
#define WPN_MACHETE 48
#define WPN_LANCE 49
#define WPN_SHOCK_LANCE 50
#define WPN_PIKE 51
#define WPN_GREAT_AXE 52
#define WPN_BATTLE_SWORD 53
#define WPN_WAR_MAUL 54
#define WPN_KNEE 55 /* Natural attack */
#define WPN_ELBOW 56 /* Natural attack */
#define WPN_MANA_BLADE 57
#define WPN_KUSARIGAMA 58
#define WPN_URUMI 59
/* Sized natural attacks - for NPC monster scaling */
#define WPN_KICK_TINY 60
#define WPN_KICK_MEDIUM 61
#define WPN_KICK_LARGE 62
#define WPN_KICK_HUGE 63
#define WPN_BITE_TINY 64
#define WPN_BITE_MEDIUM 65
#define WPN_BITE_LARGE 66
#define WPN_BITE_HUGE 67
#define WPN_STING_TINY 68
#define WPN_STING_MEDIUM 69
#define WPN_STING_LARGE 70
#define WPN_STING_HUGE 71
#define WPN_CLAW_TINY 72
#define WPN_CLAW_MEDIUM 73
#define WPN_CLAW_LARGE 74
#define WPN_CLAW_HUGE 75
#define WPN_CRUSH_TINY 76
#define WPN_CRUSH_MEDIUM 77
#define WPN_CRUSH_LARGE 78
#define WPN_CRUSH_HUGE 79
Liquid Macros File
The following liquid macros are available:
#define LIQ_WATER(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("clear", WEIGHT,CAPACITY,INSIDE,10,1,0,POISON)
#define LIQ_BEER(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("brown", WEIGHT,CAPACITY,INSIDE,5,2,3,POISON)
#define LIQ_WINE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("clear", WEIGHT,CAPACITY,INSIDE,5,2,5,POISON)
#define LIQ_ALE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("brown", WEIGHT,CAPACITY,INSIDE,5,2,2,POISON)
#define LIQ_DARK_ALE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("dark brown", WEIGHT,CAPACITY,INSIDE,5,2,1,POISON)
#define LIQ_WHISKEY(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("golden",WEIGHT ,CAPACITY,INSIDE,4,1,6,POISON)
#define LIQ_WISKEY(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("golden",WEIGHT ,CAPACITY,INSIDE,4,1,6,POISON)
#define LIQ_WHISKY(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("golden",WEIGHT ,CAPACITY,INSIDE,4,1,6,POISON)
#define LIQ_LEMONADE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("red", WEIGHT, CAPACITY, INSIDE, 8, 1, 0,POISON)
#define LIQ_FIREBRT(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("green", WEIGHT,CAPACITY,INSIDE,0,0,10,POISON)
#define LIQ_LOCALSPC(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("clear", WEIGHT, CAPACITY, INSIDE, 3, 3, 3,POISON)
#define LIQ_SLIME(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("light green", WEIGHT,CAPACITY,INSIDE,8,4,0,POISON)
#define LIQ_MILK(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("white", WEIGHT, CAPACITY, INSIDE, 6, 3, 0,POISON)
#define LIQ_TEA(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("brown", WEIGHT, CAPACITY, INSIDE, 6, 1, 0,POISON)
#define LIQ_COFFEE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("black", WEIGHT, CAPACITY, INSIDE, 6, 1, 0,POISON)
#define LIQ_COFFE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("black", WEIGHT, CAPACITY, INSIDE, 6, 1, 0,POISON)
#define LIQ_BLOOD(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("red", WEIGHT, CAPACITY, INSIDE, -1, 2, 0, POISON)
#define LIQ_SALTWAT(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("clear", WEIGHT, CAPACITY, INSIDE, 2, 1, 0, POISON)
#define LIQ_COKE(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("black", WEIGHT, CAPACITY, INSIDE, 5, 1, 0,POISON)
#define LIQ_VODKA(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("clear", WEIGHT,CAPACITY,INSIDE,0,0,10,POISON)
#define LIQ_BRANDY(WEIGHT,CAPACITY,INSIDE,POISON) \
LIQ_DEF("golden", WEIGHT,CAPACITY,INSIDE,4,1,6,POISON)
Complete Magical Transfers Macros Listing
This listing of macros was taken from wmacros.h. When building your objects you should check the macros file to make sure you have the most up to date macros.
#define CHAR_FLAG_TRANSFER(_MFLAGS) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_CHARFLAGS \
duration -1 \
data[0] _MFLAGS \
firstf TIF_EYES_TINGLE \
tickf TIF_NONE \
lastf TIF_EYES_TINGLE \
applyf APF_MOD_CHAR_FLAGS;
/* skill MUST be one of SKI_XXX, amount in -10 to +10 */
#define SKILL_TRANSFER(skill, amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_SKILL_TRANSFER \
duration -1 \
data[0] skill \
data[1] amount \
firstf TIF_SKI_INC \
tickf TIF_NONE \
lastf TIF_SKI_DEC \
applyf APF_SKILL_ADJ;
/* weapon MUST be one of WPN_XXX, amount in -10 to +10 */
#define WEAPON_TRANSFER(weapon, amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_WEAPON_TRANSFER \
duration -1 \
data[0] weapon \
data[1] amount \
firstf TIF_WPN_INC \
tickf TIF_NONE \
lastf TIF_WPN_DEC \
applyf APF_WEAPON_ADJ;
/* spell MUST be one of SPL_XXX, amount in -10 to +10 */
#define SPELL_TRANSFER(spell, amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_SPELL_TRANSFER \
duration -1 /* Must be permanent in the object */ \
data[0] spell /* It is a spell SPL_XXX transfer */ \
data[1] amount /* Amount of better spell skill */ \
firstf TIF_SPL_INC \
tickf TIF_NONE \
lastf TIF_SPL_DEC \
applyf APF_SPELL_ADJ;
#define STR_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_STR \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_STR /* It is a strength function */ \
data[1] amount /* Amount of better strength */ \
firstf TIF_STR_INC \
tickf TIF_NONE \
lastf TIF_STR_DEC \
applyf APF_ABILITY;
#define DEX_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_DEX \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_DEX /* It is a dex function */ \
data[1] amount /* Amount of better dex */ \
firstf TIF_DEX_INC \
tickf TIF_NONE \
lastf TIF_DEX_DEC \
applyf APF_ABILITY;
#define CON_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_CON \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_CON /* It is a con function */ \
data[1] amount /* Amount of better con */ \
firstf TIF_CON_INC \
tickf TIF_NONE \
lastf TIF_CON_DEC \
applyf APF_ABILITY;
#define CHA_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_CHA \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_CHA /* It is a cha function */ \
data[1] amount /* Amount of better cha */ \
firstf TIF_CHA_INC \
tickf TIF_NONE \
lastf TIF_CHA_DEC \
applyf APF_ABILITY;
#define BRA_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_BRA \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_BRA /* It is a bra function */ \
data[1] amount /* Amount of better bra */ \
firstf TIF_BRA_INC \
tickf TIF_NONE \
lastf TIF_BRA_DEC \
applyf APF_ABILITY;
#define MAG_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_MAG \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_MAG /* It is a mag function */ \
data[1] amount /* Amount of better mag */ \
firstf TIF_MAG_INC \
tickf TIF_NONE \
lastf TIF_MAG_DEC \
applyf APF_ABILITY;
#define DIV_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_DIV \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_DIV /* It is a div function */ \
data[1] amount /* Amount of better div */ \
firstf TIF_DIV_INC \
tickf TIF_NONE \
lastf TIF_DIV_DEC \
applyf APF_ABILITY;
#define HIT_TRANSFER(amount) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_HPP \
duration -1 /* Must be permanent in the object */ \
data[0] ABIL_HP /* It is a hit point function */ \
data[1] amount /* Amount of better strength */ \
firstf TIF_HIT_INC \
tickf TIF_NONE \
lastf TIF_HIT_DEC \
applyf APF_ABILITY;
#define SPEED_TRANSFER(delta_speed) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_SPEED \
duration -1 /* Must be permanent in the object */ \
data[0] delta_speed \
firstf TIF_SPEED_BETTER \
tickf TIF_NONE \
lastf TIF_SPEED_WORSE \
applyf APF_SPEED;
#define SLOW_TRANSFER(delta_speed) \
flags {UNIT_FL_MAGIC} \
affect \
id ID_TRANSFER_SPEED \
duration -1 \
data[0] delta_speed \
firstf TIF_SPEED_WORSE \
tickf TIF_NONE \
lastf TIF_SPEED_BETTER \
applyf APF_SPEED;
Skill Definitions in values.h
The following list was extracted from values.h:
#define SKI_TURN_UNDEAD 0
#define SKI_SCROLL_USE 1
#define SKI_WAND_USE 2
#define SKI_CONSIDER 3
#define SKI_DIAGNOSTICS 4
#define SKI_APPRAISAL 5
#define SKI_VENTRILOQUATE 6
#define SKI_WEATHER_WATCH 7
#define SKI_FLEE 8
#define SKI_SNEAK 9
#define SKI_BACKSTAB 10
#define SKI_HIDE 11
#define SKI_FIRST_AID 12
#define SKI_PICK_LOCK 13
#define SKI_STEAL 14
#define SKI_RESCUE 15
#define SKI_SEARCH 16
#define SKI_LEADERSHIP 17
#define SKI_KICK 18
#define SKI_SWIMMING 19
#define SKI_BASH 20
#define SKI_CLIMB 21
#define SKI_SHIELD 22
#define SKI_TRIP 23
#define SKI_DUAL_WIELD 24
#define SKI_CUFF 25
#define SKI_RESIZE_CLOTHES 26
#define SKI_RESIZE_LEATHER 27
#define SKI_RESIZE_METAL 28
#define SKI_EVALUATE 29 /* Fake skill to simulate combinations */
#define SKI_PEEK 30
#define SKI_PICK_POCKETS 31
#define SKI_FILCH 32
#define SKI_DISARM 33
#define SKI_SKIN 34
#define SKI_RUNEREAD 35
#define SKI_SCOUT 36
#define SKI_MEDITATE 37
#define SKI_DODGE 38
#define SKI_PERCEPTION 39
#define SKI_INFUSE 40
#define SKI_TRANCE 41
#define SKI_SENSE_ESSENCE 42
#define SKI_BEACONS 43
#define SKI_HARVEST 44
#define SKI_HERBS 45
#define SKI_ALCHEMY 46
#define SKI_PLANT 47
#define SKI_BUTCHER 48
#define SKI_LAY_TRAP 49
#define SKI_SHOOT 50
#define SKI_NOT_USED1 51
#define SKI_FORAGE 52
#define SKI_DOWSE 53
#define SKI_TRACK 54
#define SKI_HUNT 55
#define SKI_THROW 56
#define SKI_COOK 57
#define SKI_SCAN 58
#define SKI_SLIP 59
#define SKI_PALM 60
#define SKI_NOT_USED2 61
#define SKI_KNEE 62
#define SKI_ELBOW 64
#define SKI_HIT 65
#define SKI_PUNCH 66
#define SKI_GLANCE 67
// Language skills (must match RACE_XXX order)
#define SKI_LNG_HUMAN 68
#define SKI_LNG_ELF 69
#define SKI_LNG_DWARF 70
#define SKI_LNG_HALFLING 71
#define SKI_LNG_GNOME 72
#define SKI_LNG_ORC 73
#define SKI_LNG_OGRE 74
#define SKI_LNG_HALF_ELF 75
#define SKI_LNG_BROWNIE 76
#define SKI_LNG_GROLL 77
#define SKI_LNG_DARK_ELF 78
#define SKI_LNG_PARNON 79
#define SKI_SHELTER 80
// Armor proficiency skills
#define SKI_ARM_LEATHER 81
#define SKI_ARM_HLEATHER 82
#define SKI_ARM_CHAIN 83
#define SKI_ARM_PLATE 84
#define LAST_SKILL 84
Spell Definitions in values.h
The following list was extracted from values.h:
#define SPL_CALL_LIGHTNING 12 /* Cell Group */
#define SPL_BLESS 13 /* D I V I N E */
#define SPL_CURSE 14
#define SPL_REMOVE_CURSE 15
#define SPL_CURE_WOUNDS_1 16
#define SPL_CURE_WOUNDS_2 17
#define SPL_CURE_WOUNDS_3 18
#define SPL_CAUSE_WOUNDS_1 19
#define SPL_CAUSE_WOUNDS_2 20
#define SPL_CAUSE_WOUNDS_3 21
#define SPL_DISPEL_EVIL 22
#define SPL_REPEL_UNDEAD_1 23
#define SPL_REPEL_UNDEAD_2 24
#define SPL_BLIND 25
#define SPL_CURE_BLIND 26
#define SPL_LOCATE_OBJECT 27
#define SPL_LOCATE_CHAR 28
#define SPL_RAISE_MAG 29 /* P R O T E C T I O N */
#define SPL_RAISE_DIV 30
#define SPL_RAISE_STR 31
#define SPL_RAISE_DEX 32
#define SPL_RAISE_CON 33
#define SPL_RAISE_CHA 34
#define SPL_RAISE_BRA 35
#define SPL_SUN_RAY 36
#define SPL_DIVINE_RESIST 37
#define SPL_QUICKEN 38
#define SPL_HASTE 39
#define SPL_RAISE_SUMMONING 40
#define SPL_AWAKEN 41
#define SPL_MIND_SHIELD 42
#define SPL_HEAT_RESI 43
#define SPL_COLD_RESI 44
#define SPL_ELECTRICITY_RESI 45
#define SPL_POISON_RESI 46
#define SPL_ACID_RESI 47
#define SPL_PRO_EVIL 48
#define SPL_SANCTUARY 49
#define SPL_DISPEL_MAGIC 50
#define SPL_SUSTAIN 51
#define SPL_LOCK 52
#define SPL_UNLOCK 53
#define SPL_DROWSE 54
#define SPL_SLOW 55
#define SPL_DUST_DEVIL 56
#define SPL_DET_ALIGN 57 /* D E T E C T I O N */
#define SPL_DET_INVISIBLE 58
#define SPL_DET_MAGIC 59
#define SPL_DET_POISON 60
#define SPL_DET_UNDEAD 61
#define SPL_DET_CURSE 62
#define SPL_SENSE_LIFE 63
#define SPL_IDENTIFY_1 64
#define SPL_IDENTIFY_2 65
#define SPL_RANDOM_TELEPORT 66 /* S U M M O N I N G */
#define SPL_CLEAR_SKIES 67
#define SPL_STORM_CALL 68
#define SPL_WORD_OF_RECALL 69
#define SPL_CONTROL_TELEPORT 70
#define SPL_MINOR_GATE 71
#define SPL_GATE 72
#define SPL_CREATE_FOOD 73 /* C R E A T I O N */
#define SPL_CREATE_WATER 74
#define SPL_LIGHT_1 75
#define SPL_LIGHT_2 76
#define SPL_DARKNESS_1 77
#define SPL_DARKNESS_2 78
#define SPL_STUN 79
#define SPL_HOLD 80
#define SPL_ANIMATE_DEAD 81
#define SPL_LEATHER_SKIN 82
#define SPL_BARK_SKIN 83
#define SPL_CONTROL_UNDEAD 84
#define SPL_BONE_SKIN 85
#define SPL_STONE_SKIN 86
#define SPL_AID 87
#define SPL_COLOURSPRAY_1 88 /* M I N D */
#define SPL_COLOURSPRAY_2 89
#define SPL_COLOURSPRAY_3 90
#define SPL_INVISIBILITY 91
#define SPL_WIZARD_EYE 92
#define SPL_FEAR 93
#define SPL_CONFUSION 94
#define SPL_SLEEP 95
#define SPL_XRAY_VISION 96
#define SPL_CALM 97
#define SPL_SUMMER_RAIN 98
#define SPL_COMMAND 99
#define SPL_LEAVING 100
#define SPL_FIREBALL_1 101 /* H E A T */
#define SPL_FIREBALL_2 102
#define SPL_FIREBALL_3 103
#define SPL_FROSTBALL_1 104 /* C O L D */
#define SPL_FROSTBALL_2 105
#define SPL_FROSTBALL_3 106
#define SPL_LIGHTNING_1 107 /* C E L L */
#define SPL_LIGHTNING_2 108
#define SPL_LIGHTNING_3 109
#define SPL_STINKING_CLOUD_1 110 /* I N T E R N A L */
#define SPL_STINKING_CLOUD_2 111
#define SPL_STINKING_CLOUD_3 112
#define SPL_POISON 113
#define SPL_REMOVE_POISON 114
#define SPL_ENERGY_DRAIN 115
#define SPL_DISEASE_1 116
#define SPL_DISEASE_2 117
#define SPL_REM_DISEASE 118
#define SPL_ACIDBALL_1 119 /* E X T E R N A L */
#define SPL_ACIDBALL_2 120
#define SPL_ACIDBALL_3 121
#define SPL_MANA_BOOST 122
#define SPL_FIND_PATH 123 /* Divine */
#define SPL_DISPEL_GOOD 124
#define SPL_PRO_GOOD 125
#define SPL_TRANSPORT 126
#define SPL_FIRE_BREATH 127
#define SPL_FROST_BREATH 128
#define SPL_LIGHTNING_BREATH 129
#define SPL_ACID_BREATH 130
#define SPL_GAS_BREATH 131
#define SPL_LIGHT_BREATH 132
#define SPL_HOLD_MONSTER 133
#define SPL_HOLD_UNDEAD 134
#define SPL_RAISE_DEAD 135
#define SPL_RESURRECTION 136
#define SPL_TOTAL_RECALL 137
#define SPL_UNDEAD_DOOR 138
#define SPL_LIFE_PROTECTION 139
#define SPL_ENERGY_BOLT 140
#define SPL_CLENCHED_FIST 141
#define SPL_METEOR_SHOWER 142
#define SPL_SUN_BEAM 143
#define SPL_SOLAR_FLARE 144
#define SPL_SUMMON_DEVIL 145
#define SPL_SUMMON_DEMON 146
#define SPL_SUMMON_FIRE 147
#define SPL_SUMMON_WATER 148
#define SPL_SUMMON_AIR 149
#define SPL_SUMMON_EARTH 150
#define SPL_CHARGE_WAND 151
#define SPL_CHARGE_STAFF 152
#define SPL_MENDING 153
#define SPL_REPAIR 154
#define SPL_RECONSTRUCT 155
#define SPL_SENDING 156
#define SPL_REFIT 157
#define SPL_FIND_WANTED 158
#define SPL_LOCATE_WANTED 159
#define SPL_STORM_GATE 160
#define SPL_SUN_GLOBE 161
#define SPL_MAGIC_CANDLE 162
#define SPL_SONIC_BREATH 163
#define SPL_SHARD_BREATH 164
#define SPL_CONE_SHARD 165
#define SPL_SACRED 166
#define SPL_CLOSE_WOUNDS 167
#define SPL_OPEN_WOUNDS 168
#define SPL_TOUGH_SKIN 169
#define SPL_NOTOX 170
#define SPL_ADVAID 171
#define SPL_DET_CORPSE 172
#define SPL_FESTER 173
#define SPL_INSOMNIA 174
#define SPL_RESTLESS 175
#define SPL_POISON_2 176
#define SPL_SUMMER_SHOWER 177
#define SPL_CHAIN_LIGHT 178
#define SPL_DIM_DOOR 179
#define SPL_SEC_SHELTER 180
#define SPL_FAITH_HOUND 181
#define SPL_ANIM_OBJECT 182
#define SPL_TIME_STOP 183
#define SPL_CAUSE_INSTABILITY 184
#define SPL_CAUSE_FLIGHT 185
#define SPL_SLOW_ROT 186
#define SPL_HAMMER_HAND 187
#define SPL_CAUSE_PANIC 188
#define SPL_BANISH 189
#define SPL_HOLD_FLIGHT 190
#define SPL_BLINDING_FLASH 191
#define SPL_BLIZZARD 192
#define SPL_GODLY_STR 193
#define SPL_GODLY_DEX 194
#define SPL_GODLY_MAG 195
#define SPL_GODLY_DIV 196
#define SPL_MAGIC_MISSILES 197
#define SPL_PRODUCE_WEAPON 198
#define SPL_CALL_ANIMAL 199
#define SPL_SENSE_MAGIC 200
#define SPL_RAISE_HPP 201
#define SPL_LOWER_MAG 202
#define SPL_LOWER_DIV 203
#define SPL_LOWER_STR 204
#define SPL_LOWER_DEX 205
#define SPL_LOWER_CON 206
#define SPL_LOWER_CHA 207
#define SPL_LOWER_BRA 208
#define SPL_LOWER_HPP 209
#define SPL_REGENERATION 210
#define SPL_HOLY_WORD 211
#define SPL_UNHOLY_WORD 212
#define SPL_EAGLE_EYE 213
#define SPL_REVEAL 214
#define SPL_WPN_BLESS 215
#define SPL_FIRE_ENHANCE 216
#define SPL_LIGHT_ENHANCE 217
#define SPL_MUTE 218
#define SPL_INSIGHT 219
#define SPL_STALWARTNESS 220
#define SPL_REGAIN 221
#define SPL_CRIPPLE 222
#define SPL_GRP_BLESS 223
#define SPL_GRP_HASTE 224
#define SPL_ACID_RAIN 225
#define SPL_HOLY_LIGHT1 226
#define SPL_HOLY_LIGHT2 227
#define SPL_HOLY_LIGHT3 228
#define SPL_SUMMON_WARG 229
#define SPL_ABSORB_ENERGY 230 /* Original Catalyst spells */
#define SPL_ESSENCE_DISCOUNT 231
#define SPL_SOBERNESS 232
#define SPL_FREE_ACTION 233
#define SPL_TRANSFORM_GEM 234
#define SPL_MANA_TAP_1 235
#define SPL_MANA_TAP_2 236
#define SPL_MANA_TAP_3 237
#define SPL_MANA_SHIELD_1 238
#define SPL_MANA_SHIELD_2 239
#define SPL_MANA_SHIELD_3 240
#define SPL_MANA_PROXY 241
#define SPL_MANA_BLADE 242
#define SPL_SPELL_TURNING 243
#define SPL_BLISS 244
#define SPL_MANA_BURN 245
#define SPL_MANA_FLOW_1 246
#define SPL_MANA_FLOW_2 247
#define SPL_MANA_FLOW_3 248
#define SPL_MANA_SPILL 249
#define SPL_IGNORE_MAGIC 250
#define SPL_MANA_IMPLOSION 251
#define SPL_MANA_EXPLOSION 252
#define SPL_DEATH_BOLT 253
#define SPL_BLAZE 254 /* Wardens of Elements spells */
#define SPL_COMBUSTION 255
#define SPL_INCINERATION 256
#define SPL_FIRE_SHIELD 257
#define SPL_INFERNO 258
#define SPL_CONFLAGRATION 259
#define SPL_SEARING_MISSILES 260
#define SPL_CONGEAL 261
#define SPL_STIFFEN 262
#define SPL_GLACIATE 263
#define SPL_FLASH_FREEZE 264
#define SPL_DEEP_FREEZE 265
#define SPL_ICE_SHIELD 266
#define SPL_BENUMB 267
#define SPL_TINED_LIGHTNING 268
#define SPL_SPLIT_LIGHTNING 269
#define SPL_FORKED_LIGHTNING 270
#define SPL_SHOCK 271
#define SPL_FULMINATION 272
#define SPL_LIGHTNING_SHIELD 273
#define SPL_BALL_LIGHTNING 274
#define SPL_SOLAR_WIND 275
#define SPL_SOLAR_GUST 276
#define SPL_SOLAR_STORM 277
#define SPL_CORONAL_FIRE 278
#define SPL_HEX_HELIOS 279
#define SPL_FIST_RA 280
#define SPL_SUNNAS_GRACE 281
#define SPL_SUNNAS_SALVATION 282
#define SPL_LUNAR_COIL 283
#define SPL_LUNAR_BLAST 284
#define SPL_LUNAR_BURST 285
#define SPL_TWI_FLASH 286
#define SPL_EVENTIDE 287
#define SPL_NIGHTMARE 288
#define SPL_THOTHS_FURY 289
#define SPL_MANA_BEACON 290
#define SPL_PURSUE_BEACON 291
#define SPL_MANA_FRUIT 292
#define SPL_CAT_CON 293
#define SPL_CAT_BRA 294
#define SPL_MANA_PROJECTION 295
#define SPL_MIMIC_SPELL 296
#define SPL_MANA_JOLT 297
#define SPL_RESUSCITATE 298
#define SPL_GROUP_RES 299
#define SPL_GROUP_RESUS 300
#define SPL_GROUP_RDEAD 301
#define SPL_GROUP_TELEPORT 302
#define SPL_GROUP_SANC 303
#define SPL_GROUP_INVIS 304
#define SPL_MANA_TRACE 305
#define SPL_PROJECTION 306
#define SPL_DROUGHT 307
#define SPL_FAMINE 308
#define SPL_GROUP_FLOW 309
#define LAST_SPELL 309
Xterm 256 Color Reference
Xterm 256 colors can be used by number with &c#NNN for foreground or &b#NNN for background, where NNN is a number from 0-255. They can also be used by name with &c[name] or &b[name].
| Code | Name | RGB | Foreground | Background |
|---|---|---|---|---|
| 000 | black | 0, 0, 0 | Sample Text | Sample Text |
| 001 | red | 128, 0, 0 | Sample Text | Sample Text |
| 002 | green | 0, 128, 0 | Sample Text | Sample Text |
| 003 | yellow | 128, 128, 0 | Sample Text | Sample Text |
| 004 | blue | 0, 0, 128 | Sample Text | Sample Text |
| 005 | magenta | 128, 0, 128 | Sample Text | Sample Text |
| 006 | cyan | 0, 128, 128 | Sample Text | Sample Text |
| 007 | white | 192, 192, 192 | Sample Text | Sample Text |
| 008 | brightblack | 128, 128, 128 | Sample Text | Sample Text |
| 009 | brightred | 255, 0, 0 | Sample Text | Sample Text |
| 010 | brightgreen | 0, 255, 0 | Sample Text | Sample Text |
| 011 | brightyellow | 255, 255, 0 | Sample Text | Sample Text |
| 012 | brightblue | 0, 0, 255 | Sample Text | Sample Text |
| 013 | brightmagenta | 255, 0, 255 | Sample Text | Sample Text |
| 014 | brightcyan | 0, 255, 255 | Sample Text | Sample Text |
| 015 | brightwhite | 255, 255, 255 | Sample Text | Sample Text |
| 016 | blackonyx | 0, 0, 0 | Sample Text | Sample Text |
| 017 | navy | 0, 0, 95 | Sample Text | Sample Text |
| 018 | blueberry | 0, 0, 135 | Sample Text | Sample Text |
| 019 | cobalt | 0, 0, 175 | Sample Text | Sample Text |
| 020 | azure | 0, 0, 215 | Sample Text | Sample Text |
| 021 | ultramarine | 0, 0, 255 | Sample Text | Sample Text |
| 022 | treetop | 0, 95, 0 | Sample Text | Sample Text |
| 023 | tealgreen | 0, 95, 95 | Sample Text | Sample Text |
| 024 | bluesapphire | 0, 95, 135 | Sample Text | Sample Text |
| 025 | strongblue | 0, 95, 175 | Sample Text | Sample Text |
| 026 | nebulasblue | 0, 95, 215 | Sample Text | Sample Text |
| 027 | palaceblue | 0, 95, 255 | Sample Text | Sample Text |
| 028 | rangergreen | 0, 135, 0 | Sample Text | Sample Text |
| 029 | golfgreen | 0, 135, 95 | Sample Text | Sample Text |
| 030 | tropicalgreen | 0, 135, 135 | Sample Text | Sample Text |
| 031 | vividblue | 0, 135, 175 | Sample Text | Sample Text |
| 032 | blithe | 0, 135, 215 | Sample Text | Sample Text |
| 033 | marina | 0, 135, 255 | Sample Text | Sample Text |
| 034 | classicgreen | 0, 175, 0 | Sample Text | Sample Text |
| 035 | islandgreen | 0, 175, 95 | Sample Text | Sample Text |
| 036 | gumdropgreen | 0, 175, 135 | Sample Text | Sample Text |
| 037 | ceramicblue | 0, 175, 175 | Sample Text | Sample Text |
| 038 | aquarius | 0, 175, 215 | Sample Text | Sample Text |
| 039 | alaskanblue | 0, 175, 255 | Sample Text | Sample Text |
| 040 | shamrock | 0, 215, 0 | Sample Text | Sample Text |
| 041 | emerald | 0, 215, 95 | Sample Text | Sample Text |
| 042 | irishgreen | 0, 215, 135 | Sample Text | Sample Text |
| 043 | biscaygreen | 0, 215, 175 | Sample Text | Sample Text |
| 044 | cockatoo | 0, 215, 215 | Sample Text | Sample Text |
| 045 | bachelorbutton | 0, 215, 255 | Sample Text | Sample Text |
| 046 | acidgreen | 0, 255, 0 | Sample Text | Sample Text |
| 047 | lawngreen | 0, 255, 95 | Sample Text | Sample Text |
| 048 | jade | 0, 255, 135 | Sample Text | Sample Text |
| 049 | aquamarine | 0, 255, 175 | Sample Text | Sample Text |
| 050 | turquoise | 0, 255, 215 | Sample Text | Sample Text |
| 051 | electriccyan | 0, 255, 255 | Sample Text | Sample Text |
| 052 | sundriedtomato | 95, 0, 0 | Sample Text | Sample Text |
| 053 | grapejuice | 95, 0, 95 | Sample Text | Sample Text |
| 054 | prismviolet | 95, 0, 135 | Sample Text | Sample Text |
| 055 | royalpurple | 95, 0, 175 | Sample Text | Sample Text |
| 056 | indigo | 95, 0, 215 | Sample Text | Sample Text |
| 057 | blueviolet | 95, 0, 255 | Sample Text | Sample Text |
| 058 | avocado | 95, 95, 0 | Sample Text | Sample Text |
| 059 | gunmetal | 95, 95, 95 | Sample Text | Sample Text |
| 060 | twilightpurple | 95, 95, 135 | Sample Text | Sample Text |
| 061 | blueiris | 95, 95, 175 | Sample Text | Sample Text |
| 062 | bajablue | 95, 95, 215 | Sample Text | Sample Text |
| 063 | provincialblue | 95, 95, 255 | Sample Text | Sample Text |
| 064 | woodgreen | 95, 135, 0 | Sample Text | Sample Text |
| 065 | englishivy | 95, 135, 95 | Sample Text | Sample Text |
| 066 | oilblue | 95, 135, 135 | Sample Text | Sample Text |
| 067 | lichenblue | 95, 135, 175 | Sample Text | Sample Text |
| 068 | provence | 95, 135, 215 | Sample Text | Sample Text |
| 069 | cornflowerblue | 95, 135, 255 | Sample Text | Sample Text |
| 070 | greenery | 95, 175, 0 | Sample Text | Sample Text |
| 071 | poisongreen | 95, 175, 95 | Sample Text | Sample Text |
| 072 | jadecream | 95, 175, 135 | Sample Text | Sample Text |
| 073 | blueturquoise | 95, 175, 175 | Sample Text | Sample Text |
| 074 | bluegrotto | 95, 175, 215 | Sample Text | Sample Text |
| 075 | babyblue | 95, 175, 255 | Sample Text | Sample Text |
| 076 | jasminegreen | 95, 215, 0 | Sample Text | Sample Text |
| 077 | budgreen | 95, 215, 95 | Sample Text | Sample Text |
| 078 | springbouquet | 95, 215, 135 | Sample Text | Sample Text |
| 079 | springgreen | 95, 215, 175 | Sample Text | Sample Text |
| 080 | blueradiance | 95, 215, 215 | Sample Text | Sample Text |
| 081 | topaz | 95, 215, 255 | Sample Text | Sample Text |
| 082 | lime | 95, 255, 0 | Sample Text | Sample Text |
| 083 | electricgreen | 95, 255, 95 | Sample Text | Sample Text |
| 084 | seafoam | 95, 255, 135 | Sample Text | Sample Text |
| 085 | mintgreen | 95, 255, 175 | Sample Text | Sample Text |
| 086 | icegreen | 95, 255, 215 | Sample Text | Sample Text |
| 087 | tanagerturquoise | 95, 255, 255 | Sample Text | Sample Text |
| 088 | reddahlia | 135, 0, 0 | Sample Text | Sample Text |
| 089 | hollyhock | 135, 0, 95 | Sample Text | Sample Text |
| 090 | sparklinggrape | 135, 0, 135 | Sample Text | Sample Text |
| 091 | amaranthpurple | 135, 0, 175 | Sample Text | Sample Text |
| 092 | darkviolet | 135, 0, 215 | Sample Text | Sample Text |
| 093 | purple | 135, 0, 255 | Sample Text | Sample Text |
| 094 | tapenade | 135, 95, 0 | Sample Text | Sample Text |
| 095 | rosetaupe | 135, 95, 95 | Sample Text | Sample Text |
| 096 | chineseviolet | 135, 95, 135 | Sample Text | Sample Text |
| 097 | chiveblossom | 135, 95, 175 | Sample Text | Sample Text |
| 098 | dahliapurple | 135, 95, 215 | Sample Text | Sample Text |
| 099 | africanviolet | 135, 95, 255 | Sample Text | Sample Text |
| 100 | goldenlime | 135, 135, 0 | Sample Text | Sample Text |
| 101 | mosstone | 135, 135, 95 | Sample Text | Sample Text |
| 102 | sharkskin | 135, 135, 135 | Sample Text | Sample Text |
| 103 | persianviolet | 135, 135, 175 | Sample Text | Sample Text |
| 104 | jacaranda | 135, 135, 215 | Sample Text | Sample Text |
| 105 | grapemist | 135, 135, 255 | Sample Text | Sample Text |
| 106 | macawgreen | 135, 175, 0 | Sample Text | Sample Text |
| 107 | kiwi | 135, 175, 95 | Sample Text | Sample Text |
| 108 | peapod | 135, 175, 135 | Sample Text | Sample Text |
| 109 | aquifer | 135, 175, 175 | Sample Text | Sample Text |
| 110 | placidblue | 135, 175, 215 | Sample Text | Sample Text |
| 111 | bluebell | 135, 175, 255 | Sample Text | Sample Text |
| 112 | limegreen | 135, 215, 0 | Sample Text | Sample Text |
| 113 | greenflash | 135, 215, 95 | Sample Text | Sample Text |
| 114 | summergreen | 135, 215, 135 | Sample Text | Sample Text |
| 115 | cabbage | 135, 215, 175 | Sample Text | Sample Text |
| 116 | arubablue | 135, 215, 215 | Sample Text | Sample Text |
| 117 | crystalblue | 135, 215, 255 | Sample Text | Sample Text |
| 118 | chartreuse | 135, 255, 0 | Sample Text | Sample Text |
| 119 | apple | 135, 255, 95 | Sample Text | Sample Text |
| 120 | emeraldgreen | 135, 255, 135 | Sample Text | Sample Text |
| 121 | palegreen | 135, 255, 175 | Sample Text | Sample Text |
| 122 | beachglass | 135, 255, 215 | Sample Text | Sample Text |
| 123 | islandparadise | 135, 255, 255 | Sample Text | Sample Text |
| 124 | bloodred | 175, 0, 0 | Sample Text | Sample Text |
| 125 | vivacious | 175, 0, 95 | Sample Text | Sample Text |
| 126 | vividviola | 175, 0, 135 | Sample Text | Sample Text |
| 127 | dahlia | 175, 0, 175 | Sample Text | Sample Text |
| 128 | darkorchid | 175, 0, 215 | Sample Text | Sample Text |
| 129 | grape | 175, 0, 255 | Sample Text | Sample Text |
| 130 | honeyginger | 175, 95, 0 | Sample Text | Sample Text |
| 131 | dustycedar | 175, 95, 95 | Sample Text | Sample Text |
| 132 | meadowmauve | 175, 95, 135 | Sample Text | Sample Text |
| 133 | irisorchid | 175, 95, 175 | Sample Text | Sample Text |
| 134 | amethystorchid | 175, 95, 215 | Sample Text | Sample Text |
| 135 | amethyst | 175, 95, 255 | Sample Text | Sample Text |
| 136 | goldenpalm | 175, 135, 0 | Sample Text | Sample Text |
| 137 | applecinnamon | 175, 135, 95 | Sample Text | Sample Text |
| 138 | woodrose | 175, 135, 135 | Sample Text | Sample Text |
| 139 | regalorchid | 175, 135, 175 | Sample Text | Sample Text |
| 140 | bougainvillea | 175, 135, 215 | Sample Text | Sample Text |
| 141 | lilac | 175, 135, 255 | Sample Text | Sample Text |
| 142 | citronelle | 175, 175, 0 | Sample Text | Sample Text |
| 143 | palm | 175, 175, 95 | Sample Text | Sample Text |
| 144 | winterpear | 175, 175, 135 | Sample Text | Sample Text |
| 145 | miragegray | 175, 175, 175 | Sample Text | Sample Text |
| 146 | lavender | 175, 175, 215 | Sample Text | Sample Text |
| 147 | chambray | 175, 175, 255 | Sample Text | Sample Text |
| 148 | acidlime | 175, 215, 0 | Sample Text | Sample Text |
| 149 | greenglow | 175, 215, 95 | Sample Text | Sample Text |
| 150 | jadelime | 175, 215, 135 | Sample Text | Sample Text |
| 151 | pastelgreen | 175, 215, 175 | Sample Text | Sample Text |
| 152 | icymorn | 175, 215, 215 | Sample Text | Sample Text |
| 153 | omphalodes | 175, 215, 255 | Sample Text | Sample Text |
| 154 | limepopsicle | 175, 255, 0 | Sample Text | Sample Text |
| 155 | lizard | 175, 255, 95 | Sample Text | Sample Text |
| 156 | teagreen | 175, 255, 135 | Sample Text | Sample Text |
| 157 | paradisegreen | 175, 255, 175 | Sample Text | Sample Text |
| 158 | greenash | 175, 255, 215 | Sample Text | Sample Text |
| 159 | limpetshell | 175, 255, 255 | Sample Text | Sample Text |
| 160 | poinciana | 215, 0, 0 | Sample Text | Sample Text |
| 161 | brightrose | 215, 0, 95 | Sample Text | Sample Text |
| 162 | roseviolet | 215, 0, 135 | Sample Text | Sample Text |
| 163 | purpleorchid | 215, 0, 175 | Sample Text | Sample Text |
| 164 | purplesatin | 215, 0, 215 | Sample Text | Sample Text |
| 165 | phlox | 215, 0, 255 | Sample Text | Sample Text |
| 166 | autumnmaple | 215, 95, 0 | Sample Text | Sample Text |
| 167 | spicedcoral | 215, 95, 95 | Sample Text | Sample Text |
| 168 | shockingpink | 215, 95, 135 | Sample Text | Sample Text |
| 169 | superpink | 215, 95, 175 | Sample Text | Sample Text |
| 170 | bodacious | 215, 95, 215 | Sample Text | Sample Text |
| 171 | mediumorchid | 215, 95, 255 | Sample Text | Sample Text |
| 172 | autumnblaze | 215, 135, 0 | Sample Text | Sample Text |
| 173 | coppertan | 215, 135, 95 | Sample Text | Sample Text |
| 174 | peachblossom | 215, 135, 135 | Sample Text | Sample Text |
| 175 | fuchsiapink | 215, 135, 175 | Sample Text | Sample Text |
| 176 | cyclamen | 215, 135, 215 | Sample Text | Sample Text |
| 177 | violet | 215, 135, 255 | Sample Text | Sample Text |
| 178 | sulphur | 215, 175, 0 | Sample Text | Sample Text |
| 179 | ochre | 215, 175, 95 | Sample Text | Sample Text |
| 180 | sheepskin | 215, 175, 135 | Sample Text | Sample Text |
| 181 | silverpink | 215, 175, 175 | Sample Text | Sample Text |
| 182 | orchidbouquet | 215, 175, 215 | Sample Text | Sample Text |
| 183 | mauvemist | 215, 175, 255 | Sample Text | Sample Text |
| 184 | sulphurspring | 215, 215, 0 | Sample Text | Sample Text |
| 185 | limeade | 215, 215, 95 | Sample Text | Sample Text |
| 186 | mellowgreen | 215, 215, 135 | Sample Text | Sample Text |
| 187 | gardenglade | 215, 215, 175 | Sample Text | Sample Text |
| 188 | nimbuscloud | 215, 215, 215 | Sample Text | Sample Text |
| 189 | halogenblue | 215, 215, 255 | Sample Text | Sample Text |
| 190 | primrose | 215, 255, 0 | Sample Text | Sample Text |
| 191 | sunnylime | 215, 255, 95 | Sample Text | Sample Text |
| 192 | sharpgreen | 215, 255, 135 | Sample Text | Sample Text |
| 193 | shadowlime | 215, 255, 175 | Sample Text | Sample Text |
| 194 | patinagreen | 215, 255, 215 | Sample Text | Sample Text |
| 195 | soothingsea | 215, 255, 255 | Sample Text | Sample Text |
| 196 | cherrytomato | 255, 0, 0 | Sample Text | Sample Text |
| 197 | paradisepink | 255, 0, 95 | Sample Text | Sample Text |
| 198 | fandangopink | 255, 0, 135 | Sample Text | Sample Text |
| 199 | phloxpink | 255, 0, 175 | Sample Text | Sample Text |
| 200 | neonpurple | 255, 0, 215 | Sample Text | Sample Text |
| 201 | fuchsia | 255, 0, 255 | Sample Text | Sample Text |
| 202 | orangetiger | 255, 95, 0 | Sample Text | Sample Text |
| 203 | hotcoral | 255, 95, 95 | Sample Text | Sample Text |
| 204 | pinklemonade | 255, 95, 135 | Sample Text | Sample Text |
| 205 | azaleapink | 255, 95, 175 | Sample Text | Sample Text |
| 206 | operamauve | 255, 95, 215 | Sample Text | Sample Text |
| 207 | neonpink | 255, 95, 255 | Sample Text | Sample Text |
| 208 | autumnorange | 255, 135, 0 | Sample Text | Sample Text |
| 209 | melon | 255, 135, 95 | Sample Text | Sample Text |
| 210 | shellpink | 255, 135, 135 | Sample Text | Sample Text |
| 211 | sachetpink | 255, 135, 175 | Sample Text | Sample Text |
| 212 | lilacchiffon | 255, 135, 215 | Sample Text | Sample Text |
| 213 | bubblegum | 255, 135, 255 | Sample Text | Sample Text |
| 214 | goldfusion | 255, 175, 0 | Sample Text | Sample Text |
| 215 | chamois | 255, 175, 95 | Sample Text | Sample Text |
| 216 | apricotwash | 255, 175, 135 | Sample Text | Sample Text |
| 217 | peachbud | 255, 175, 175 | Sample Text | Sample Text |
| 218 | lilacsachet | 255, 175, 215 | Sample Text | Sample Text |
| 219 | orchid | 255, 175, 255 | Sample Text | Sample Text |
| 220 | cyberyellow | 255, 215, 0 | Sample Text | Sample Text |
| 221 | minionyellow | 255, 215, 95 | Sample Text | Sample Text |
| 222 | snapdragon | 255, 215, 135 | Sample Text | Sample Text |
| 223 | apricotsherbet | 255, 215, 175 | Sample Text | Sample Text |
| 224 | pinkdogwood | 255, 215, 215 | Sample Text | Sample Text |
| 225 | cherryblossom | 255, 215, 255 | Sample Text | Sample Text |
| 226 | blazingyellow | 255, 255, 0 | Sample Text | Sample Text |
| 227 | lemonverbena | 255, 255, 95 | Sample Text | Sample Text |
| 228 | twilight | 255, 255, 135 | Sample Text | Sample Text |
| 229 | elfinyellow | 255, 255, 175 | Sample Text | Sample Text |
| 230 | almondoil | 255, 255, 215 | Sample Text | Sample Text |
| 231 | voidwhite | 255, 255, 255 | Sample Text | Sample Text |
| 232 | anthracite | 8, 8, 8 | Sample Text | Sample Text |
| 233 | caviar | 18, 18, 18 | Sample Text | Sample Text |
| 234 | blackbeauty | 28, 28, 28 | Sample Text | Sample Text |
| 235 | meteorite | 38, 38, 38 | Sample Text | Sample Text |
| 236 | guardshoe | 48, 48, 48 | Sample Text | Sample Text |
| 237 | pirateblack | 58, 58, 58 | Sample Text | Sample Text |
| 238 | asphalt | 68, 68, 68 | Sample Text | Sample Text |
| 239 | darkshadow | 78, 78, 78 | Sample Text | Sample Text |
| 240 | granitegray | 88, 88, 88 | Sample Text | Sample Text |
| 241 | pewter | 98, 98, 98 | Sample Text | Sample Text |
| 242 | gargoyle | 108, 108, 108 | Sample Text | Sample Text |
| 243 | brushednickel | 118, 118, 118 | Sample Text | Sample Text |
| 244 | frostgrey | 128, 128, 128 | Sample Text | Sample Text |
| 245 | griffin | 138, 138, 138 | Sample Text | Sample Text |
| 246 | wetweather | 148, 148, 148 | Sample Text | Sample Text |
| 247 | silver | 158, 158, 158 | Sample Text | Sample Text |
| 248 | drizzle | 168, 168, 168 | Sample Text | Sample Text |
| 249 | harbormist | 178, 178, 178 | Sample Text | Sample Text |
| 250 | greyviolet | 188, 188, 188 | Sample Text | Sample Text |
| 251 | lunarrock | 198, 198, 198 | Sample Text | Sample Text |
| 252 | dawngrey | 208, 208, 208 | Sample Text | Sample Text |
| 253 | barelyblue | 218, 218, 218 | Sample Text | Sample Text |
| 254 | blanc | 228, 228, 228 | Sample Text | Sample Text |
| 255 | whitealyssum | 238, 238, 238 | Sample Text | Sample Text |