Treasure Compiler for gmoria

Table of Contents

1 Overview

This document describes the treasure-compiler (tc). It is a code-generation tool that is used to create files called treasure_tables.c and treasure_constant.h in gmoria. Editing those files by hand can be error prone, and tc creates those files so you don’t have to bother. It reads in a single human-readable file that completely describes the attributes of all of the objects in the game, and it generates code to be compiled into the game. The compiler issues warnings and errors when things don’t quite make sense. The audience for this tool is a developer who wants to add new objects to the game in a safe way. This document describes how to use this tool, and the format of the treasure-definition file. Objects in the game are called ‘treasure’ for historical reasons only. Treasures include things that can be picked up, but they can also be dynamic elements of the dungeon, like doors or traps. Treasures include everything that can be seen in the game that isn’t a monster or a wall.


2 The Treasure-Defintion File

The treasure-definition file describes all of the objects in the game. tc reads in this file to create the treasure_tables.c and treasure_constant.h files. It is meant to be human-readable, easily understood and modified by programmers who might not understand the intricacies of how the various arrays and constants fit together.

The treasure-definition file is comprised of blocks. A block looks like this:

treasure "& Longsword" {
	...
};

As can be seen, the block starts with a keyword denoting the kind of block (a treasure block). Following that there’s a name for the block (‘"& Longsword"’), and then there are a set of braces, followed by a semicolon. The attributes of the longsword object go inside of the braces (instead of ‘...’) . For more information about the purpose of the ‘&’ see Treasure Blocks.

There are four kinds of blocks: treasure, class, unidentified, and syllable blocks. A treasure can be derived from a class. A class block looks like:

class sword {
	...
};

It is very similar to the treasure block. The name isn’t quoted because the name of the class will not show up anywhere in the treasure_tables.c file. The attributes that go inside of a class block are the same as the treasure block.

Unidentified blocks have to do with naming objects when their function is not fully known. For example, potions can be "Blue", or "Speckled". Syllable blocks are another kind of unidentified block that pertain solely to scrolls. Names of unidentified scrolls are made up of a random set of syllables from this block. The unidentified block, and the syllable block are a simple list of words.

The treasure-definition file is made up of sequences of these class and treasure blocks, along with unidentified and syllable blocks. A complete treasure-defintion file contains many treasures, that derive from many classes which derive from many classes. The use of classes help to reduce errors, and increase consistency in the final product. Using a complex structure of classes makes changing the treasure-definition file more difficult; a good treasure-definition file strikes a balance.

The treasure compiler will provide error messaging when a class is referenced that doesn’t exist or if there is a synatical problem like a missing semi-colon. It will also complain if an important attribute is forgotten.

Hash style comments are also supported when they are located outside of a block.


2.1 Class Blocks

Class blocks are used by treasure blocks to derive attributes. For example all sword treasure blocks share a sword class that make them "sword-like".

A treasure is derived from a class like this:

treasure "& Longsword": sword {
	...
};

A class can be derived from zero or more classes. For example:

class sword: wieldable {
	...
};

All of the attributes contained in the wieldable class will be pulled into the sword class.


2.2 Treasure Blocks

Treasure blocks are the most important block, and they relate directly to the treasure_tables.c file. There is an "Amulet of DOOM" in the game because there is a treasure block in the treasure-defintion file that defines it.

A treasure block can derive from zero or more class blocks. For example:

treasure "DOOM": amulet, wearable {
	...
};

All of the attributes from the ‘amulet’ and ‘wearable’ class will be present in this treasure called ‘DOOM’. The name ‘DOOM’ will appear in the game when the player looks at the treasure. Notice that the name of the treasure isn’t ‘Amulet of DOOM’ – it’s "amuletness" is defined by an attribute in a block which isn’t shown in this example.

The name of a treasure block has some special rules. If it contains an ‘&’, it is replaced with ‘A’, ‘An’, or a number. If it contains a ‘~’ it is replaced with an ‘s’ to make a word plural. For example ‘& Bolt~’ becomes ‘a Bolt’ or ‘15 Bolts’ according to how many bolts there are associated with the object (the ‘quantity’ attribute). For objects like amulets, rings, wands, scrolls, potions, mushrooms, books and staffs the name is automatically prepended with ‘Amulet of’, or ‘Ring of’, or ‘Staff of’. The name of the treasure block should be chosen with these rules in mind.

The game expects certain treasure blocks to be present to fill the character’s initial backpack with. Different character classes will receive different items in their backpack. These are the treasure blocks that must be present:

Rations of Food

An item with a tval of ‘TV_FOOD’, and a subval of ‘90’ that is sold in a store.

Wooden Torches

An item with a tval of ‘TV_LIGHT’, and a subval of ‘192’ that is sold in a store.

Cloak

An item with a tval of ‘TV_CLOAK’, and a subval of ‘1’ that is not sold in a store.

Stilleto Dagger

An item with a tval of ‘TV_SWORD’, and a subval of ‘3’ that is not sold in a store.

Soft Leather Armor

An item with a tval of ‘TV_SOFT_ARMOR’, and a subval of ‘2’ that is not sold in a store.

Beginners Magic Book

An item with a tval of ‘TV_MAGIC_BOOK’, and a subval of ‘64’ that is not sold in a store.

Beginner’s Handbook

An item with a tval of ‘TV_PRAYER_BOOK’, and a subval of ‘64’ that is not sold in a store.


2.3 Unidentified Blocks

Various objects in the game have special descriptive terms attached to them when their function is unknown. For example, who knows what a "Blue Speckled" potion does? It may be a potion of Cure Poison but because it is still "unidentified" the potion needs a descriptive term to uniquely identify it’s effect. To make things a little more complicated, a "Blue Speckled" potion isn’t always a potion of Cure Poison – it is randomly set every game. Various kinds of objects need a special description when unidentified: ‘RING’, ‘WAND’, ‘STAFF’, ‘MUSHROOM’, and ‘POTION’. This is why the ‘unidentified’ block exists: to describe these objects when their function is unknown.

When there are more words in the unidentified block than of objects of that type, the word may not be used in the game. It is randomly decided which of the descriptive words will be used per game.

Here’s what the unidentified block looks like:

unidentified AMULET {
  "Amber","Driftwood","Coral","Agate","Ivory","Obsidian",
  "Bone","Brass","Bronze","Pewter","Tortoise Shell"
};

This means that an unidentified amulet object can be one of Amber, Driftwood, Coral, etc. There must be one entry in this ‘unidentified’ block per ‘AMULET’ described in the ‘treasure’ blocks. If there were only 10 treasure blocks with a ‘kind’ of ‘AMULET’, then one of these amulet adjectives would unassigned.


2.4 Syllable Blocks

During gameplay when the function of ‘SCROLL’ objects is unknown they are identified by a name that is comprised of a random jumble of syllables. The ‘syllable’ block describes these syllables.

The syllable block looks like this:

syllable {
  "a","ab","ag","aks","ala","an","ankh","app","arg","arze","ash","aus",
  "ban","bar","bat","bek","bie","bin","bit","bjor","blu","bot","bu",
  "byt","comp","con","cos","cre","dalf","dan","den","doe","dok","eep",
  "el","eng","er","ere","erk","esh","evs","fa","fid","for","fri","fu",
  "gan","gar","glen","gop","gre","ha","he","hyd","i","ing","ion","ip",
  "ish","it","ite","iv","jo","kho","kli","klis","la","lech","man","mar",
  "me","mi","mic","mik","mon","mung","mur","nej","nelg","nep","ner",
  "nes","nis","nih","nin","o","od","ood","org","orn","ox","oxy","pay",
  "pet","ple","plu","po","pot","prok","re","rea","rhov","ri","ro","rog",
  "rok","rol","sa","san","sat","see","sef","seh","shu","ski","sna","sne",
  "snik","sno","so","sol","sri","sta","sun","ta","tab","tem","ther","ti",
  "tox","trol","tue","turs","u","ulk","um","un","uni","ur","val","viv",
  "vly","vom","wah","wed","werg","wex","whon","wun","x","yerg","yp","zun"
};

There is no limit to the number syllables.


2.5 Attributes

Every treasure in moria is made up of a set of attributes. Every treasure and class block in the treasure-definition file describes attributes.

Attributes have a name, and a value, and are always followed by a semicolon. For example:

class sword {
	to_ac: 0;
	   ac: 0;
}

The ‘to_ac’ and ‘ac’ attributes are set to a value of 0 (because swords do not commonly increase the armor class of the wearer). The semicolon must follow each attribute value, or the compiler be unable to parse the file due to a syntax error.

Attributes fall into two categories: general and specific. Specific attributes pertain to an object with a particular ‘kind’, while general attributes apply to all ‘KIND’s.

The general attributes that apply to all ‘treasure’ and ‘class’ blocks are: ‘kind’, ‘letter’, ‘p1’, ‘cost’, ‘quantity’, ‘weight’, ‘to_hit’, ‘to_dam’, ‘ac’, ‘to_ac’, ‘damage’, ‘level’, ‘stackable’, ‘sold’, ‘relsubval’, and ‘subval’.

The specific attributes are: ‘special’, ‘spell’, ‘prayer’, ‘unique_function’, ‘potion_causes’, ‘eating_causes’, ‘staff_casts’, ‘scroll_casts’, ‘wand_casts’, and ‘contains’.

Here is an explanation of these attributes – what they do, and what their allowable values are:

kind

This attribute is the genre of the object. The following values are allowed for this attribute:

NOTHING

An administrative item kind. It doesn’t do anything at all.

MISC

A useless item in the game that can be picked up, dropped or thrown.

CHEST

An item that may contain other objects. Chests may be trapped.

SLING_AMMO

A small object that can be thrown via sling. It can be fired from certain ‘BOW’s.

BOLT

A small object that can be shot with a crossbow. It can be fired from certain ‘BOW’s.

ARROW

A small object that can be shot with a ‘bow’.

SPIKE

A small object that can be used to jam a door to make it unopenable. After the spike is jammed, it is consumed (it disappears).

LIGHT

An item that provides light when wielded.

BOW

A weapon that shoots arrows when wielded.

HAFTED

An axe-like weapon that be used to hit monsters when wielded.

POLEARM

A longer spear-like weapon that be used to hit monsters when wielded.

SWORD

A bladed weapon that be used to hit monsters when wielded.

DIGGING

A shovel-like object that can be wielded to dig in walls for ore.

BOOTS

An object that is wearable on the feet.

GLOVES

An object that is wearable on the hands.

CLOAK

An object that is wearable around the shoulders.

HELM

An object that is wearable on the head.

SHIELD

An object that is wearable on an arm.

SOFT_ARMOR

An object that is wearable on the body.

HARD_ARMOR

An object that is wearable on the body. It is heavier and more protective than it’s softer counterpart.

AMULET

An object wearable around the neck that usually has magical abilities.

RING

An object wearable around a finger that usually has magical abilities.

STAFF

An object that is used to do a variety of magical things. It has so-called charges that are consumed as the player uses the staff.

WAND

An object that is used to do a variety of magical things. It has charges that are consumed as the player uses the wand. The effect of this object happens in a given direction.

SCROLL

An object that is read to do a variety of magical things. After the scroll is read, it is consumed (it disappears).

POTION

An object that is quaffed and has a variety of magical effects. The empty potion disappears after it is consumed.

FLASK

An object that fuels a light source. The empty flask disappears after it is consumed.

FOOD

An object that is eaten.

MUSHROOM

An object that is eaten, but usually has magical properties.

MAGIC_BOOK

An object that contains spells, and is readable to cast spells.

PRAYER_BOOK

An object that contains prayers, and is readable to pray prayers.

GOLD

Currency.

INVIS_TRAP

A feature of the terrain, a trap that can’t normally be seen until it is stepped on.

VIS_TRAP

A feature of the terrain, a trap that is plainly visible.

RUBBLE

A feature of the terrain, some loose rock lying about.

OPEN_DOOR

A feature of the terrain, a door that is open.

CLOSED_DOOR

A feature of the terrain, a door that is closed.

UP_STAIRS

A feature of the terrain, some stairs going upwards.

DOWN_STAIRS

A feature of the terrain, some stairs going downwards.

SECRET_DOOR

A feature of the terrain, a closed door that is not plainly visible.

STORE_DOOR

A feature of the terrain in the town, a door corresponding to a store.

The ‘kind’ attribute is used like this:

class ring {
	kind: RING;
};
letter

This attribute represents the ascii character that the treasure appears on the screen as. This value is a string, where the first character in that string is the character used to represent the treasure onscreen. Letters like ‘#’ and ‘"’ are incorrectly handled, and must be specified numerically with the decimal value. For example instead of ‘letter: "#";’, use ‘letter: 35;’.

In most cases, the letter attribute is used like this:

class ring {
	letter: "=";
};
p1

This attribute has different meanings when it used with objects of differing ‘kind’s. Here is what ‘p1’ means per ‘kind’:

FOOD

p1’ means the number of turns the player will go without feeling hungry after eating this object.

MUSHROOM

p1’ means the number of turns the player will go without feeling hungry after eating the mushroom.

FLASK

p1’ means the number of turns of light the flask holds.

LIGHT

p1’ means the number of turns of light the object holds initially.

DIGGING

p1’ determines how effective the digging tool is. Legal values are 1, 2, and 3, with 3 being the most effective digging tool.

POTION

p1’ means the number of turns the player will go without feeling hungry after quaffing the potion.

BOW

p1’ can be any value from 1 to 6, and it relates to a bonus that the object gets when used with the proper ammunition.

1

The bow shoots ‘SLING_AMMO’.

2

The bow shoots ‘ARROW’s with a small bonus.

3

The bow shoots ‘ARROW’s with a medium bonus.

4

The bow shoots ‘ARROW’s with an large bonus.

5

The bow shoots ‘ARROW’s with the largest bonus.

6

The crossbow shoots ‘BOLT’s with a medium bonus.

7

The crossbow shoots ‘BOLT’s with the largest bonus.

VIS_TRAP

p1’ represents the amount of experience the player gets after disarming the trap.

INVIS_TRAP

p1’ represents the amount of experience the player gets after disarming the trap.

ac

This attribute represents the armour class of the object. The higher the armour class, the harder it is for a creature to hit the player when the player is wearing this armour. A legal value for this attribute is ‘0’ or more, where the largest practical value is ‘125’.

class shield {
	ac: 60;
};
cost

This attribute represents the intrinsic value of the object in gold pieces. A store owner will buy the object from the player for a fraction of this value (unless it is cursed). A legal value for this attribute is ‘0’ or more.

quantity

This attribute represents the number of objects. Having a quantity greater than ‘1’ is useful for giving the new characters a specific number of torches, or rations of food at the beginning of a new game. Theoretically this attribute is useful for putting things in the dungeon that are stackable, and come in pairs, or threes, etc. A legal value for this attribute is ‘0’ or more.

weight

This attribute represents how heavy the object is (in tenths of stones). One stone is about 14 pounds. A legal value for this attribute is ‘0’ or more. Here is an example of how to use the ‘weight’ attribute:

class weighs_one_stone {
	weight: 10;
};
damage

This attribute has two terms. The first is the number of dice to roll, and the second term is the number of sides that the die has. When a die is said to have 3 sides, it is presumed that one side has a value of 1, another has 2, and the last has 3. These fictious dice are rolled and the value is the base amount to subtract from a monster’s hit-points. The ‘to_dam’ attribute can be used to augment this total with a fixed amount. For example:

class no_damage {
	damage: 0|0;
};

or:

class hits_for_7_to_21_damage{
	damage: 7|3;
};
to_hit

A fixed bonus to the likelihood that this object will hit it’s target. A legal value for this attribute is ‘0’ or more. This attribute applies mostly to weapons, but not exclusively.

to_dam

A fixed bonus to the damage of the object. A legal value for this attribute is ‘0’ or more. This attribute applies mostly to weapons, but not exclusively. For example:

class hits_for_22_to_36_damage{
	damage: 7|3;
        to_dam: 15;
};
to_ac

A fixed bonus to the object’s armor class.

level

The level of the dungeon that this object is most frequently found at. A level of ‘0’ means the town level, a level of ‘1’ means 50 feet below into the dungeon, level ‘2’ means 100 feet, etc. Here’s an example of how the ‘level’ attribute is used:

class commomly_found_at_1250_feet_below {
	level: 25;
};
stackable

This attribute indicates the stacking policy of the object. It can be one of the following values: ‘never’, ‘with_same_kind’, or ‘with_same_p1’. This attribute assists in the autonumbering of ‘subval’ attribute when ‘subval’ is not specified.

Stacking means the objects are gathered on one line in the player’s inventory. Objects that ‘never’ stack are things like swords, and boots. It is impossible to merge a sword with another sword of the same kind; one sword will always occupy one slot in the player’s inventory, while two swords will take up two slots.

Objects that stack ‘with_same_kind’ are things like potions, and mushrooms. This means that all the potions of sleep that the player happens to find will be put in a single pile in the player’s inventory. e.g. ‘8 Potions of Sleep’.

Things that stack ‘with_same_p1’ are things like arrows, and bolts. This is so that ‘+3’ arrows don’t get mixed in to the normal arrows.

relsubval

It is not always desired to implicitly increment the subval by 1, so there is a way to explicitly set the subval relative to the stackable policy. This is done by specifying the ‘relsubval’ attribute. The idea here is better than absolutely specifying the ‘subval’ by specifying it because there’s no easy way to know ahead of time what the first subval for ‘with_same_kind’ or ‘with_same_p1’ will be. If the ‘with_same_kind’ attribute starts numbering at 64, the subval is relatively specified as ‘relsubval: 3’, the subval would become 64 + 3 = 67.

subval

The ‘subval’ attribute is used to enumerate different objects of the same ‘kind’. Unforunately the gmoria source expects particular values for ‘subval’s for various ‘kind’s. The user of this tool must be very careful when changing subvals – it is possible that other source code must be changed to make the game function.

When ‘subval’ is not specified the compiler will try to autonumber it – picking the next available subval, or taking an existing subval if the object has the same name.

sold

This attribute indicates which stores an object is sold in, and how frequently it is available for sale. It can be a combination of the following: ‘by_general_store’, ‘by_armoury’, ‘by_weaponsmith’, ‘by_temple’, ‘by_alchemist’, ‘by_magic_shop’, and ‘exclusively_in_town’. The value ‘exclusively_in_town’ indicates that this object never appears randomly in the dungeon, and is only for sale in a store. The other values indicate which store sells this object. To make the object appear in a General Store more frequently, the value would be ‘by_general_store*2’, ‘by_general_store*3’, etc. The multiplier indicates that the object is 2 times more likely, 3 times more likely, etc. to appear for sale in the General Store.

Here’s a complicated example for a ‘Word-of-Recall’ scroll: ‘sold: by_temple, by_alchemist*3, exclusively_in_town;’ It is sold in the temple, and in the alchemist’s store, and it is not found within the dungeon randomly. The scroll is found three times more often in the Alchemist’s store than it would if it were only ‘*1’.

An unexpected requirement is that the total number of items for sale in each store must be equal. For example, if the general store only sells rations, and every other store sells precisely three different items, the rations must appear as ‘sold: by_general_store*3’.

Please note that ‘exclusively_in_town’, is a misnomer – an object can be said to be sold exclusively in town, but not sold in a store. This is because the value actually means that it will not randomly show up in the dungeon.

special

This attribute applies to objects that have a ‘kind’ of ‘AMULET’, ‘DIGGING’, and ‘RING’. It is used to apply various special abilities to amulets, shovels and rings.

special’ can have any combination of the following values:

strength

Gives the wearer a strength bonus.

intelligence

Gives a bonus to the wearer’s intelligence.

wisdom

Gives a bonus to the wearer’s wisdom.

dexterity

Gives a bonus to the wearer’s dexterity.

constitution

Gives a bonus to the wearer’s constitution.

charisma

Gives a bonus to the wearer’s charisma.

search

Causes the wearer to find hidden doors and traps more often.

slow_digestion

Causes the wearer to get hungry less often.

stealth

Causes the wearer to wake up sleeping monsters less often.

aggravate

Causes the wearer to wake up sleeping monsters more often.

teleport

Causes the wearer to be randomly transported to another place on the map.

regenerate

Causes the wearer to slowly gain hit-points when injured.

speed

Causes the wearer to move faster.

ego_flame_tongue

This value is used with ‘FLASK’ objects. When the object is thrown onto a fire-based monster, it does extra damage.

resist_fire

Causes the wearer to be less affected by fire attacks.

resist_acid

Causes the wearer to be less affected by acid attacks.

resist_cold

Causes the wearer to be less affected by cold/ice attacks.

sustain_stat

Causes the wearer to have strength, intelligence, dexterity, wisdom, charisma, or constitution remain the same.

free_action

Makes the wearer unable to be slept, paralyzed, or made afraid.

see_invisible

Causes the wearer the ability see invisible monsters.

resist_lightning

Causes the wearer to be less affected by lightning attacks.

free_falling

Gives the wearer the ability to gracefully float down into any unexpected holes in the dungeon floor.

blindness

Causes the wearer to become blind.

fear

Causes the wearer to become afaid.

tunnel

This gives ‘DIGGING’ objects their ability to tunnel through rock.

infrared

Gives the wearer the ability see into the darkness.

cursed

Causes the wearer to be unable to take the item off.

Here is an example of how to use ‘special’:

class perfect_sight {
	special: infrared, see_invisible, search;
};

It is also possible to negate a special if it has already been defined by another inherited class:

class not_blind {
	special: ~blindness;
};
spell

This attribute applies to objects that have a ‘kind’ of ‘MAGIC_BOOK’. The idea here is that the book contains a number of different spells. It can be any combination of the following values:

magic_missile

This spell throws a magical arrow at a target.

detect_monsters

This spell shows the player where the monsters are, but only for an instant.

phase_door

This spell transports the player to a nearby location.

light_area

This spell provides light to open spaces.

cure_light_wounds

This spell restores some of the player’s hit-points.

find_hidden_traps_and_doors

This spell shows the player where invisible traps and secret doors are.

stinking_cloud

This spell throws a ball of nausea at a group of opponents.

confusion

This spell causes a monster to become confused temporarily.

lightning_bolt

This spell throws a lightning bolt at a target.

trap_and_door_destruction

This spell makes traps and doors disappear.

sleep_i

This spell makes a group of creatures fall asleep.

cure_poison

This spell negates the effects of poison.

teleport_self

This spell works like phase door, but transports the player farther away.

remove_curse

This spell makes it possible to take off a cursed object.

frost_bolt

This spell throws an arrow of magical ice at a target.

turn_stone_to_mud

This spell dissolves walls and rock-based creatures.

create_food

This spell creates food. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.

recharge_item_i

This spell reloads staffs and wands, but has a chance of destroying the item.

sleep_ii

This spell makes a group of creatures fall asleep. It is more effective than ‘sleep’.

polymorph_other

This spell turns a creature into another creature.

identify

This spell assists the player in discovering the true nature of an object.

sleep_iii

This spell makes a group of creatures fall asleep. It is more effective than ‘sleep_ii’.

fire_bolt

This spell throws a magical arrow of fire at a target.

slow_monster

This spell makes a monster move a little slower.

frost_ball

This spell throws a ball of ice at a group of opponents.

recharge_item_ii

This spell reloads staffs and wands, but has a chance of destroying the item. It is more effective than ‘recharge_item_i’.

teleport_other

This spell works like ‘teleport_self’, but operates on another creature.

haste_self

This spell makes the player move a little faster.

fire_ball

This spell throws a ball of fire at a group of opponents.

resist_poison_gas

This spell gives a permanent, non-cumulative small resistance to poison gas.

word_of_destruction

This spell destroys everything on the screen.

genocide

This spell destroys all creatures of a given appearance on the level.

prayer

This attribute applies to objects that have a ‘kind’ of ‘PRAYER_BOOK’. It can be any combination of the following values:

detect_evil

This prayer shows the player all the evil creatures on the screen, but only for an instant.

cure_light_wounds

This prayer cures a small number of the player’s hit-points.

bless

This prayer improves ther player’s armor class and fighting ability for a short period of time.

remove_fear

This prayer negates the effects of fear on the player.

call_light

This prayer negates darkness in an open space.

find_traps

This prayer shows the player all of the invisible traps on the screen.

detect_doors_and_stairs

This prayer shows the player all of the doors and stairs on the screen.

slow_poison

This prayer lessens the effects of poison, but does not cure it.

blind_creature

This prayer causes a creature to lose it’s sight.

portal

This prayer transports the player to a nearby location.

cure_medium_wounds

This prayer cures a medium number of the player’s hit-points.

chant

This prayer improves the player’s armor class and fighting ability for a medium period of time.

sanctuary

This prayer causes neighbouring monsters to fall asleep for a while.

create_food

This prayer creates food. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.

remove_curse

This prayer makes it possible to take off a cursed object.

resist_heat_and_cold

This prayer lessens the effects of heat and cold attacks on the player.

neutralize_poison

This prayer cures the effects of poison.

orb_of_draining

This prayer drains experience from a creature.

cure_serious_wounds

This prayer cures a large number of the player’s hit-points.

sense_invisible

This prayer shows the player all of the invisible creatures on the screen.

protection_from_evil

This prayer lessens the attacks of evil characters on the player.

earthquake

This prayer rents the earth and collapses the ceiling.

sense_surroundings

This prayer shows the walls on the screen.

cure_critical_wounds

This prayer cures a very large number of the player’s hit-points.

turn_undead

This prayer attempts to make undead creatures flee the player.

pray_prayer

This prayer improves the player’s armor class and fighting ability for a long period of time.

dispel_undead

This prayer attempts to utterly destroy an undead creature.

heal

This prayer restores up to 200 of the player’s hit-points.

dispel_evil

This prayer attempts to utterly destroy an evil creature.

resist_poison_gas

This prayer gives a permanent, non-cumulative small resistance to poison gas.

glyph_of_warding

This prayer leaves a ’Glyph’ on the ground that creatures cann’t pass over. See the ‘scare_monster’ value of the ‘unique_function’ attribute for which object is dropped on the ground.

holy_word

This prayer dispels evil, removes fear, cures poison, restores 1000 HPs, restores all stats, and invulnerability for 3 turns.

unique_function

This attribute gives an object a unique behaviour. It can be one of the following values:

chest_ruined

This value indicates that this object is left behind after a chest is bashed.

wizard_object

This value indicates that it is used as a base object when creating new objects in wizard mode.

scare_monster

This value indicates that this object is left on the ground after a ‘glyph_of_warding’ prayer or ‘warding_glyph’ scroll is read.

created_by_spell

This value indicates that this object is created by a ‘create_food’ spell or prayer.

inventory_object

This value indicates that the object is administrative in nature, and is used as a necessary placeholder in the player’s inventory.

potion_causes

This attribute applies to objects that have a ‘kind’ of ‘POTION’. It can have one of the following values:

gain_strength

Causes the player’s strength stat to increase.

lose_strength

Causes the player’s strength stat to descrease.

restore_strength

Causes the player’s strength stat to return to a normal level.

gain_intelligence

Causes the player’s intelligence stat to increase.

lose_intelligence

Causes the player’s intelligence stat to descrease.

restore_intelligence

Causes the player’s intelligence stat to return to a normal level.

gain_wisdom

Causes the player’s wisdom stat to increase.

lose_wisdom

Causes the player’s wisdom stat to descrease.

restore_wisdom

Causes the player’s wisdom stat to return to a normal level.

gain_charisma

Causes the player’s charisma stat to increase.

lose_charisma

Causes the player’s charisma stat to descrease.

restore_charisma

Causes the player’s charisma stat to return to a normal level.

cure_wounds_i

Restores a small number of the player’s hit-points.

cure_wounds_ii

Restores a medium number of the player’s hit-points.

cure_wounds_iii

Restores a large number of the player’s hit-points.

healing

Restores up to 1000 of the player’s hit-points.

gain_constitution

Causes the player’s constitution stat to increase.

gain_experience

Causes the player to gain experience, and possibly a level.

sleep

Puts the player into a deep sleep.

blindness

Makes the player unable to see anything at all. Reading from scrolls or books is impossible.

confusion

Makes the player act erradically.

poisoning

Causes the player’s hit-points to steadily decrease.

speed

Makes the player move faster for a temporary amount of time.

slowness

Makes the player move slower for a temporary amount of time.

gain_dexterity

Causes the player’s dexterity stat to increase.

restore_dexterity

Causes the player’s dexterity stat to return to a normal level.

restore_constitution

Causes the player’s constitution stat to return to a normal level.

cure_blindness

Negates the effects of blindness when the player is blind.

cure_confusion

Negates the effects of confusion when the player is confused.

cure_poison

Completely negates the effects of poison when the player is poisoned.

lose_experience

Causes the player to lose experience points, and maybe lose a level.

throw_up

Causes the player to throw up! The potion cures poison and the player becomes hungry sooner.

invulnerability

Negates the effects of attacks on the player for a temporary period of time.

heroism

Causes the player temporarily receive more hit-points and become a better fighter.

super_heroism

Causes the player temporarily receive more hit-points and become a better fighter. More effective than ‘heroism’.

cure_fear

Negates the effects of fear when the player is afraid.

restore_life_levels

Causes the player experience points to be restored to a normal level.

resist_heat

Lessens the effect of fire attacks on the player.

resist_cold

Lessens the effect of cold attacks on the player.

see_invisible

Causes the player to be able to see invisible creatures for a short amount of time.

slow_poison

Lessens the effects of poison when the player is poisoned.

cure_poison

Completely negates the effects of poison when the player is poisoned.

restore_mana

Restores the player’s magic points.

infravision

Causes the player to see creatures farther into the darkness.

eating_causes

This attribute applies to objects that have a ‘kind’ of ‘MUSHROOM’. It can have one of the following values. These objects can also be thrown at a creature and the effect happens to the creature, instead of the player.

poisoning

Causes the player’s hit-points to steadily decrease for a temporary amount of time.

blindness

Causes the player to become blind for a temporary period of time.

fear

Causes the player to become afraid for a temporary period of time.

confusion_i

Causes the player to act erradically for a temporary period of time.

confusion_ii

Causes the player to act more erradically for a longer period of time.

cure_poison

Negates the effects of poison when the player is poisoned.

cure_blindness

Negates the effects of blindness when the player is blinded.

cure_fear

Negates the effects of fear when the player is afraid.

cure_confusion

Negates the effects of confusion when the player is confused.

lose_strength

Causes the player’s strength stat to decrease.

lose_constitution

Causes the player’s constitution stat to decrease.

restore_strength

Causes the player’s strength stat to return to a normal level.

restore_constitution

Causes the player’s constitution stat to return to a normal level.

restore_intelligence

Causes the player’s intelligence stat to return to a normal level.

restore_wisdom

Causes the player’s wisdom stat to return to a normal level.

restore_dexterity

Causes the player’s dexterity stat to return to a normal level.

restore_charisma

Causes the player’s charisma stat to return to a normal level.

cure_wounds_i

Restores a small number of the player’s hit-points.

cure_wounds_ii

Restores a medium number of the player’s hit-points.

cure_wounds_iii

Restores a large number of the player’s hit-points.

cure_wounds_iv

Restores a very large number of the player’s hit-points.

cause_wounds

Decreases the player’s hit-points.

staff_casts

This attribute applies to objects that have a ‘kind’ of ‘STAFF’. Any one of the following values can be used:

light

Negates darkness in an open space.

detect_secret_doors

Shows secret doors that are located on the screen.

detect_traps

Shows traps that are located on the screen.

detect_treasures

Shows gold that is located on the screen.

detect_objects

Shows objects that are located on the screen.

teleport

Teleports the player elsewhere on the level.

earthquake

Rent the earth and collapse the ceiling.

summon_monster

Make a monster appear nearby.

earthquake_ii

Rent the earth and collapse the ceiling, in a larger radius.

starlight

Make a shaft of light appear in all directions.

speed_monsters

Make monsters on the screen move faster.

slow_monsters

Make monsters on the screen move slower.

sleep_monsters_ii

Make monsters on the screen go to sleep.

cure_wounds_i

Restore a small amount of the player’s hit-points.

detect_invisible

Show invisible creatures that are located on the screen.

speed

Make the player go faster temporarily.

slowness

Make the player go slower temporarily.

mass_polymorph

Change the monsters on the screen to other other monsters.

remove_curse

Make a cursed item able to be taken off.

detect_evil

See the evil creatures that are located on the screen.

curing

Negate the affects of poison, blindness, and confusion.

dispel_undead

Attempt to utterly destroy an undead creature.

darkness

Turn out the lights!

wand_casts

This attribute applies to objects that have a ‘kind’ of ‘WAND’. It can be one of the following values:

light_line

Make a shaft of light appear in a given direction.

lightning_bolt

Throws a lightning bolt at a target.

frost_bolt

Throws a magical arrow of ice in a given direction.

fire_bolt

Throws a magical arrow of fire in a given direction.

stone_to_mud

Dissolves walls and rock-based creatures in a given direction.

polymorph_monster

Changes a target creature into another creature.

heal_monster

Restores hit-points in the target creature.

haste_monster

Makes the target creature move faster.

slow_monster

Makes the target creature move slower.

confuse_monster

Makes the target creature move erradically.

sleep_monster

Makes the target creature go to sleep.

drain_life

Reduces experience from the target creature.

destroy_traps_and_doors

Makes targeted traps or doors disappear.

magic_missile

Throws a magical arrow in a given direction.

build_wall

Makes a line of walls in the given direction

clone_monster

Duplicates the target creature.

teleport_monster

Transport a target creature to another place on the level.

disarm_all

Disarms all chests and traps in a given direction.

lightning_ball

Throws a ball of lightning at a group of opponents.

cold_ball

Throws a ball of ice at a group of opponents.

fire_ball

Throws a ball of fire at a group of opponents.

poison_gas

Throws a ball of poison at a group of opponents.

acid_ball

Throws a ball of acid at a group of opponents.

wonder

This wand behaves randomly like a different wand.

scroll_casts

This attribute applies to objects that have a ‘kind’ of ‘SCROLL’.

increase_tohit

Attempts to increase a selected weapon’s hit bonus.

increase_todam

Attempts to increase a selected weapon’s damage bonus.

enchant_armor_i

Attempts to increase the armor class of a piece of armor.

identify

Assists the player in discovering the true nature of a selected object.

remove_curse

Makes it possible to take off a cursed object.

light

Negates darkness in an open space.

summon_monster

Make a monster appear nearby.

phase_door

Transport the player to a nearby location.

teleport

Causes the player to be randomly transported to another place on the map.

teleport_level

Causes the player to be randomly transported to another level of the dungeon.

confuse_monster

Makes the next creature the player hits move erradically.

magic_mapping

Shows the player the hidden walls on the screen.

sleep_monsters_i

This spell makes a group of creatures fall asleep.

warding_glyph

Leaves a ’Glyph’ on the ground that creatures cann’t pass over. See the ‘scare_monster’ value of the ‘unique_function’ attribute for which object is dropped on the ground.

detect_treasure

Shows gold that is located on the screen.

detect_objects

Shows objects that are located on the screen.

detect_traps

Shows traps that are located on the screen.

detect_secret_doors

Shows secret doors that are located on the screen.

mass_genocide

Kills all creatures on the whole level except for the Balrog.

detect_invisble

Gives the player the ability see where invisible monsters are.

aggravate_monster

Causes the player to wake up monsters that are sleeping nearby.

create_trap

Creates a set of traps that enclose the player.

trap_or_door_destruction

Make traps and doors disappear.

create_door

Creates a set of doors enclosing the player.

recharge

Charge a staff or a wand.

genocide

Destroys all creatures of a given appearance on the level.

darkness

Turn out the lights.

protection_from_evil

Lessen the attacks of evil characters on the player.

create_food

This scroll creates food when it is read. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.

dispel_undead

Attempts to utterly destroy an undead creature.

enchant_weapon

Attempts to enchant a weapon that the player is weilding.

curse_weapon

Curses a weapon the player is weilding.

enchant_armor_ii

Attempts to enchant armor that the player is wearing.

curse_armor

Curses armor the player is weilding.

summon_undead

Make an undead monster appear nearby.

bless_i

Improves ther player’s armor class and fighting ability for a short period of time.

bless_ii

Improves the player’s armor class and fighting ability for a medium period of time.

bless_iii

Improves the player’s armor class and fighting ability for a long period of time.

recall

Causes the player to be transported to the town if the player is in the dungeon. If the player is already in the town, it causes the player to be transported into the dungeon – to the deepest level the player has explored. The recall effect does not happen immediately.

earthquake

Rents the earth and collapses the ceiling.

contains

This attribute applies to objects that have a ‘kind’ of ‘CHEST’. It can have any combination of the following values:

carry_small_obj

When this value is set, the chest will not carry ‘CHEST’s, ‘BOW’s, ‘POLEARM’s, ‘HARD_ARMOR’, ‘SOFT_ARMOR’, or ‘STAFF’s. It will also not carry an object that is ‘HAFTED’, is a ‘SWORD’ or ‘DIGGING’ utensil if weighs more than 15 stones.

carry_obj

When this value is set, the chest will carry any object that is found in the dungeon.

carry_gold

When this value is set the chest will carry some gold.

has_random_60

The chest contains objects 60% of the time.

has_random_90

The chest contains objects 90% of the time.

has_1d2_obj

The chest contains a minimum of 1 object, and a maximum of 2 objects.

has_2d2_obj

The chest contains a minimum of 2 objects, and a maximum of 4 objects.

has_4d2_obj

The chest contains a minimum of 4 objects, and a maximum of 8 objects.


2.6 Deriving Attributes

Certain attributes behave differently when derived from a class. Attributes can be overridden, merged, and negated.

Attributes like ac, level and cost only have one value, and their value is overwritten when they are derived from a class.

For example:

class sword {
	ac: 0;
};

class maingauche : sword {
	ac: 1;
};

This collection of classes results in ‘ac’ being 1, not 0. The value of ‘ac’ is taken from ‘sword’ as 0, and then is replaced with 1.

Other attributes like special, spell, prayer, stackable, and unique_function have more than one value, and they are merged when deriving.

For example:

class cursed {
	special: cursed;
};

class teleportable: cursed {
	special: teleport;
};

This collection of classes results in treasure being ‘teleport, cursed’. It is easy to merge attributes in an unexpected fashion; the user must beware.

Through the practice of derivation, attributes can be merged that just don’t go together. Often there’s a way to undo it, like by using the ‘~’ operator, or the ‘none’ value. The compiler will try to complain when things don’t make sense, but it doesn’t catch all of the cases. Here’s an example that shows how to negate a flag:

class cursed {
	special: cursed;
};

class ring {
           kind: RING;
};

class weaknessring: cursed, ring {
	special: strength;
             p1: -5;
           cost: 0;
};

treasure "Strength" : weaknessring {
	special: ~cursed;
             p1: 0;
           cost: 500;
};

This collection of classes results in the ‘ring of Strength’ having a ‘special’ of ‘strength’. The ‘cursed’ flag is dropped because of the ‘~cursed’ term.


3 A Small Example

Let’s take this treasure-definition file as an example. It describes the skeleton objects.

class single_item {
	 quantity: 1;
};

class unwearable : single_item {
	  to_ac: 0; 	      ac: 0;
};

class unwieldable {
	 to_hit: 0; 	  to_dam: 0;
};

class worthless {
	   cost: 0;
};

class bone : unwearable, unwieldable, worthless {
           kind: MISC;	  letter: "s";	      p1: 0;    damage: 1|1;
      stackable: never;
};

treasure "& Human Skeleton" : bone {
	 weight: 60;       level: 1;
};

treasure "& Dwarf Skeleton" : bone {
	 weight: 50;       level: 1;
};

treasure "& Elf Skeleton" : bone {
	 weight: 40;       level: 1;
};

treasure "& Gnome Skeleton" : bone {
	 weight: 25;       level: 1;
};

treasure "& broken set of teeth" : bone {
	 weight: 3;       level: 0;
};

treasure "& large broken bone" : bone {
	 weight: 2;       level: 0;
};

Seven treasures are derived from the ‘bone’ class. They all hit for 1d1 when thrown, and cannot stack with other bones. The ‘bone’ class is derived from the ‘worthless’ class which ensures that the intrinsic value of the object is zero. Bones are ‘unwieldable’ and ‘unwearable’ so their ac and bonuses are always zero. ‘unwearable’ things are always single objects. When these bones are thrown, they hit an opponent with ‘1d1’ damage.

The resulting file that tc outputs looks similar to this:

/* The following data was generated by the tc program. */

treasure_type object_list[MAX_OBJECTS] = {
{"& Elf Skeleton"               ,0x00000000L,      TV_MISC, 's',        /*  0*/
    0,     0,    0,   1,  40,   0,   0,  0,   0, {1,1}  ,  1},
{"& Dwarf Skeleton"             ,0x00000000L,      TV_MISC, 's',        /*  1*/
    0,     0,    1,   1,  50,   0,   0,  0,   0, {1,1}  ,  1},
{"& Gnome Skeleton"             ,0x00000000L,      TV_MISC, 's',        /*  2*/
    0,     0,    2,   1,  25,   0,   0,  0,   0, {1,1}  ,  1},
{"& Human Skeleton"             ,0x00000000L,      TV_MISC, 's',        /*  3*/
    0,     0,    3,   1,  60,   0,   0,  0,   0, {1,1}  ,  1},
{"& broken set of teeth"        ,0x00000000L,      TV_MISC, 's',        /*  4*/
    0,     0,    4,   1,   3,   0,   0,  0,   0, {1,1}  ,  0},
{"& large broken bone"          ,0x00000000L,      TV_MISC, 's',        /*  5*/
    0,     0,    5,   1,   2,   0,   0,  0,   0, {1,1}  ,  0},
};


The note about bit-shifting in desc.c is confusing to beginners. The moria codebase presumes bit shifting of the object ident offsets by 6 bits in desc.c because the range of subvals for objects that never stack is 63 (SINGLE_ITEM_STACK_MIN - 1). It is also worth noting that changing OBJECT_IDENT_SIZE will break compatibility with the save game file. This means that other versions of moria will not be able to read save game files with an OBJECT_IDENT_SIZE that is not 448. It is expected that users will create new variants of moria using this tool. Should backwards comptability be desired then special care must be taken to ensure it.


4 Invoking moria-tc

This is the output of the command ‘tc --help’:

Usage: moria-tc [OPTION...] FILE
Generate gmoria's treasure_tables.c from FILE.

  -c, --consistency-check    check for consistency errors
  -C, --constants            generate constants instead of tables.
  -o, --outfile=FILE         put generated code into FILE
  -?, --help                 give this help list
      --usage                give a short usage message
  -V, --version              print program version

By default the treasures_table.c file goes to the standard output unless the -o
option is used.

For complete documentation, visit: <http://sv.nongnu.org/p/gmoria/>

Report bugs to gmoria@nym.hush.com.

FILE is the treasure-defintion file to "compile". If it is "-", then it will be read from the standard input.

tc supports the following options:

-o
--outputfile

Put generated code into FILE. This option puts the generated treasure_tables.c file into a specific FILE. If FILE is "-", then it will go to the standard output. This is the default.

-c
--consistency-check

Check for consistency errors. A loose set of rules is applied to treasures in the treasure-definition file. For example, if a book doesn’t contain any spells, it complains. See the section on Consistency Checks for more information.

-C
--constants

Generate constants instead of tables. This option makes moria-tc generate the treasure_constant.h file instead of the treasure_tables.c file.


4.1 Consistency Checks

The following consistency checks are implemented:

  1. When a treasure is a ‘STAFF’, then it must have a ‘staff_casts’ attribute specified.
  2. When a treasure is a ‘MUSHROOM’, then it must have an ‘eating_causes’ attribute specified.
  3. When a treasure is a ‘WAND’, then it must have a ‘wand_casts’ attribute specified.
  4. When a treasure is a ‘SCROLL’, then it must have a ‘scroll_casts’ attribute specified.
  5. If a treasure is a ‘MAGIC_BOOK’, then it must have a ‘spell’ attribute specified to denote which spells the book contains.
  6. If a treasure is a ‘PRAYER_BOOK’, then it must have a ‘prayer’ attribute specified to denote which prayers the book contains.
  7. When a treasure is a ‘GOLD’, then it must have a ‘cost’ attribute that exceeds zero.
  8. When a treasure is a ‘FOOD’, then it must have a ‘p1’ attribute that exceeds zero to represent the food’s ability to prevent hunger.
  9. All treasures except ones that are ‘NOTHING’ must have a ‘quantity’ over zero.
  10. Treasures that are ‘SOFT_ARMOR’, ‘HARD_ARMOR’, ‘BOOTS’ and ‘GLOVES’ must have an ‘ac’ over zero.
  11. All treasures must have a ‘weight’ over zero, except for those that are door related, trap related, ‘RUBBLE’, ‘GOLD’, or ‘NOTHING’.
  12. SWORD’, ‘HAFTED’, and ‘POLEARM’ objects must have a ‘damage’ of at least ‘1d1’.

5 Workflow

moria-tc will typically be used in this fashion:

  1. start a new treasure-definition file
  2. add and modify treasure and class blocks
  3. run moria-tc on the new treasure-definition file
  4. check for warning and errors, goto 2 if there are any
  5. replace the src/treasure_tables.c file in the gmoria source tree with the resulting treasure_tables.c file mitem re-run moria-tc on the same treasure-definition file but this time with the –constant option
  6. replace the src/treasure_constant.h file in the gmoria source tree with the resulting treasure_constant.h file
  7. recompile gmoria by typing ‘make’ in the top level directory

6 Contributors

The following persons have contributed to this software:


7 Reporting Bugs

If a bug is found in moria-tc, please send electronic mail to gmoria@nym.hush.com. Include the version number, which can be found by running ‘tc --version. Also include in the output that the program produced and the expected output.

Send questions, comments or suggestions about moria-tc, to gmoria@nym.hush.com.