Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

FieldType
symbolic nameSymbol
namesStringlist
titleString
descrString
extraStructure
minvInteger
keyString
spellInteger
romflagsInteger
sexInteger
raceInteger
attackInteger
defenseInteger
positionInteger
manipulateInteger
alignmentInteger
flagsInteger
weightInteger
capacityInteger
lightInteger
moneyStructure
expInteger
levelInteger
heightInteger
abilitiesStructure
weaponsStructure
spellsStructure
specialStructure
dilbegin/dilcopyFunction pointer
endSymbol

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:

FlagDescription
CHAR_PROTECTEDAttacking this char is treated as murder and triggers guard responses
CHAR_LEGAL_TARGETInternal flag after illegal actions. Will not persist in zones
CHAR_OUTLAWKilling this char is not treated as a crime
CHAR_GROUPChar is in a group. Will not persist in zones
CHAR_BLINDSets the char as blind
CHAR_HIDESets the char as hiding
CHAR_MUTESets the char as mute, can not speak
CHAR_SNEAKSets the char as sneaking
CHAR_DETECT_ALIGNChar can detect alignment. Pointless for NPCs
CHAR_DETECT_INVISIBLEChar can see invisible units
CHAR_DETECT_MAGICChar can detect magic. Pointless for NPCs
CHAR_DETECT_POISONChar can detect poison. Pointless for NPCs
CHAR_DETECT_UNDEADChar can detect undead. Pointless for NPCs
CHAR_DETECT_CURSEChar can detect curses. Pointless for NPCs
CHAR_DETECT_LIFEChar can detect life. Pointless for NPCs
CHAR_WIMPYMakes the char flee when low on HP
CHAR_SELF_DEFENCETemporary flag when the char is not the initiator in combat. Pointless for NPC definitions.
CHAR_PEACEFULAggressive NPCs will not attack this character
CHAR_KILL_SELFSet 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:

SymbolValueDescription
SEX_NEUTRAL0Neither male nor female
SEX_MALE1Male
SEX_FEMALE2Female

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:

SymbolDescription
RACE_HUMANHuman
RACE_ELFElf
RACE_DWARFDwarf
RACE_HALFLINGHalfling
RACE_GNOMEGnome
RACE_HALF_ORCHalf-orc
RACE_HALF_OGREHalf-ogre
RACE_HALF_ELFHalf-elf
RACE_BROWNIEBrownie
RACE_GROLLGroll
RACE_DARK_ELFDark 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:

SymbolDescription
POSITION_DEADNPC is dead
POSITION_MORTALLYWNPC is mortally wounded
POSITION_INCAPNPC is incapacitated
POSITION_STUNNEDNPC is stunned
POSITION_SLEEPINGNPC is sleeping
POSITION_RESTINGNPC is resting
POSITION_SITTINGNPC is sitting
POSITION_FIGHTINGNPC is fighting
POSITION_STANDINGNPC 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:

LBSSize
0 - 5Tiny
6 - 40Small
41 - 160Medium
161 - 500Large
501 and upHuge

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
ArgumentDescription
axe_hamAny hammer or axe
swordAny sword-like weapon, including dagger and rapier, etc.
club_maceAny club or mace-like weapon, flails, morning star, etc.
polearmAny spear or pole-like weapon: spear, trident, sickle, scythe, etc.
unarmedAny bite, claw, sting or other natural attack
specialAny 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
ArgumentDescription
divCovers all divine sphere spells
proCovers all protection sphere spells
detCovers all detection sphere spells
sumCovers all summoning spells
creCovers all creation spells
minCovers all mind spells
heaCovers all heat spells (fireball, etc.)
colCovers all cold spells (frostball, etc.)
celCovers all cell (electricity) spells (lightning bolt, etc.)
intCovers all internal (poison) spells (toxicate, etc.)
extCovers 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.def or the spells.def for 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:

ArgumentTypeDescription
atk_splstringAttack spell, e.g., “fireball” or “” for none
def_splstringDefense spell, e.g., “heal” or “” for none
def_pctintegerHP percentage when defense spell is cast
spdintegerSpeed 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:

ArgumentTypeDescription
zonesstringZone names separated by spaces
spdintegerSpeed in seconds (minimum 5)
doorsintegerCan open/close doors (0=false, 1=true)
lckd_doorsintegerCan 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:

ArgumentTypeDescription
sxinteger0=any sex, 1=opposite, 2=male, 3=female, 4=neutral
rceintegerRace to attack (-1 for any)
oppinteger0=non-specific, 1=attack specified race, 2=attack all except
levlintegerLevel threshold (positive=above, negative=below, 0=any)
sancinteger0=ignore, 1=obey sanc, 2=obey soothe, 3=obey both
tmeintegerTime to wait before attacking (ticks)
tarintegerTarget selection (-2=last, -1=weakest, 0=random, 1=strongest, 2=first)
alignstring“ANY”, “GOOD”, “EVIL”, “NEUTRAL”, “OPPOSITE”, “SALIGN”, “DALIGN”
attackstringlistTwo 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 NPC
  • guild_master - Handles join/leave commands
  • guild_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

  1. Using the teamwork DIL function, create a guard that will help all other guards.

  2. Using the rescue DIL function, add to your guard from exercise one and make it so it will now rescue as well as help.

  3. 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.

  4. Turn your shop keeper from exercise three into a global wandering sales person.

  5. Using the aggressive DIL function, create a Dwarf aggressive to any Orc that walks into the room.