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.
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.
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.
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:
An item with a tval of ‘TV_FOOD’, and a subval of ‘90’ that is sold in a store.
An item with a tval of ‘TV_LIGHT’, and a subval of ‘192’ that is sold in a store.
An item with a tval of ‘TV_CLOAK’, and a subval of ‘1’ that is not sold in a store.
An item with a tval of ‘TV_SWORD’, and a subval of ‘3’ that is not sold in a store.
An item with a tval of ‘TV_SOFT_ARMOR’, and a subval of ‘2’ that is not sold in a store.
An item with a tval of ‘TV_MAGIC_BOOK’, and a subval of ‘64’ that is not sold in a store.
An item with a tval of ‘TV_PRAYER_BOOK’, and a subval of ‘64’ that is not sold in a store.
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.
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.
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:
This attribute is the genre of the object. The following values are allowed for this attribute:
An administrative item kind. It doesn’t do anything at all.
A useless item in the game that can be picked up, dropped or thrown.
An item that may contain other objects. Chests may be trapped.
A small object that can be thrown via sling. It can be fired from certain ‘BOW’s.
A small object that can be shot with a crossbow. It can be fired from certain ‘BOW’s.
A small object that can be shot with a ‘bow’.
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).
An item that provides light when wielded.
A weapon that shoots arrows when wielded.
An axe-like weapon that be used to hit monsters when wielded.
A longer spear-like weapon that be used to hit monsters when wielded.
A bladed weapon that be used to hit monsters when wielded.
A shovel-like object that can be wielded to dig in walls for ore.
An object that is wearable on the feet.
An object that is wearable on the hands.
An object that is wearable around the shoulders.
An object that is wearable on the head.
An object that is wearable on an arm.
An object that is wearable on the body.
An object that is wearable on the body. It is heavier and more protective than it’s softer counterpart.
An object wearable around the neck that usually has magical abilities.
An object wearable around a finger that usually has magical abilities.
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.
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.
An object that is read to do a variety of magical things. After the scroll is read, it is consumed (it disappears).
An object that is quaffed and has a variety of magical effects. The empty potion disappears after it is consumed.
An object that fuels a light source. The empty flask disappears after it is consumed.
An object that is eaten.
An object that is eaten, but usually has magical properties.
An object that contains spells, and is readable to cast spells.
An object that contains prayers, and is readable to pray prayers.
Currency.
A feature of the terrain, a trap that can’t normally be seen until it is stepped on.
A feature of the terrain, a trap that is plainly visible.
A feature of the terrain, some loose rock lying about.
A feature of the terrain, a door that is open.
A feature of the terrain, a door that is closed.
A feature of the terrain, some stairs going upwards.
A feature of the terrain, some stairs going downwards.
A feature of the terrain, a closed door that is not plainly visible.
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; };
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: "="; };
This attribute has different meanings when it used with objects of differing ‘kind’s. Here is what ‘p1’ means per ‘kind’:
‘p1’ means the number of turns the player will go without feeling hungry after eating this object.
‘p1’ means the number of turns the player will go without feeling hungry after eating the mushroom.
‘p1’ means the number of turns of light the flask holds.
‘p1’ means the number of turns of light the object holds initially.
‘p1’ determines how effective the digging tool is. Legal values are 1, 2, and 3, with 3 being the most effective digging tool.
‘p1’ means the number of turns the player will go without feeling hungry after quaffing the potion.
‘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.
The bow shoots ‘SLING_AMMO’.
The bow shoots ‘ARROW’s with a small bonus.
The bow shoots ‘ARROW’s with a medium bonus.
The bow shoots ‘ARROW’s with an large bonus.
The bow shoots ‘ARROW’s with the largest bonus.
The crossbow shoots ‘BOLT’s with a medium bonus.
The crossbow shoots ‘BOLT’s with the largest bonus.
‘p1’ represents the amount of experience the player gets after disarming the trap.
‘p1’ represents the amount of experience the player gets after disarming the trap.
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; };
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.
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.
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; };
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; };
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.
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; };
A fixed bonus to the object’s armor class.
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; };
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.
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.
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.
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.
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:
Gives the wearer a strength bonus.
Gives a bonus to the wearer’s intelligence.
Gives a bonus to the wearer’s wisdom.
Gives a bonus to the wearer’s dexterity.
Gives a bonus to the wearer’s constitution.
Gives a bonus to the wearer’s charisma.
Causes the wearer to find hidden doors and traps more often.
Causes the wearer to get hungry less often.
Causes the wearer to wake up sleeping monsters less often.
Causes the wearer to wake up sleeping monsters more often.
Causes the wearer to be randomly transported to another place on the map.
Causes the wearer to slowly gain hit-points when injured.
Causes the wearer to move faster.
This value is used with ‘FLASK’ objects. When the object is thrown onto a fire-based monster, it does extra damage.
Causes the wearer to be less affected by fire attacks.
Causes the wearer to be less affected by acid attacks.
Causes the wearer to be less affected by cold/ice attacks.
Causes the wearer to have strength, intelligence, dexterity, wisdom, charisma, or constitution remain the same.
Makes the wearer unable to be slept, paralyzed, or made afraid.
Causes the wearer the ability see invisible monsters.
Causes the wearer to be less affected by lightning attacks.
Gives the wearer the ability to gracefully float down into any unexpected holes in the dungeon floor.
Causes the wearer to become blind.
Causes the wearer to become afaid.
This gives ‘DIGGING’ objects their ability to tunnel through rock.
Gives the wearer the ability see into the darkness.
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; };
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:
This spell throws a magical arrow at a target.
This spell shows the player where the monsters are, but only for an instant.
This spell transports the player to a nearby location.
This spell provides light to open spaces.
This spell restores some of the player’s hit-points.
This spell shows the player where invisible traps and secret doors are.
This spell throws a ball of nausea at a group of opponents.
This spell causes a monster to become confused temporarily.
This spell throws a lightning bolt at a target.
This spell makes traps and doors disappear.
This spell makes a group of creatures fall asleep.
This spell negates the effects of poison.
This spell works like phase door, but transports the player farther away.
This spell makes it possible to take off a cursed object.
This spell throws an arrow of magical ice at a target.
This spell dissolves walls and rock-based creatures.
This spell creates food. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.
This spell reloads staffs and wands, but has a chance of destroying the item.
This spell makes a group of creatures fall asleep. It is more effective than ‘sleep’.
This spell turns a creature into another creature.
This spell assists the player in discovering the true nature of an object.
This spell makes a group of creatures fall asleep. It is more effective than ‘sleep_ii’.
This spell throws a magical arrow of fire at a target.
This spell makes a monster move a little slower.
This spell throws a ball of ice at a group of opponents.
This spell reloads staffs and wands, but has a chance of destroying the item. It is more effective than ‘recharge_item_i’.
This spell works like ‘teleport_self’, but operates on another creature.
This spell makes the player move a little faster.
This spell throws a ball of fire at a group of opponents.
This spell gives a permanent, non-cumulative small resistance to poison gas.
This spell destroys everything on the screen.
This spell destroys all creatures of a given appearance on the level.
This attribute applies to objects that have a ‘kind’ of ‘PRAYER_BOOK’. It can be any combination of the following values:
This prayer shows the player all the evil creatures on the screen, but only for an instant.
This prayer cures a small number of the player’s hit-points.
This prayer improves ther player’s armor class and fighting ability for a short period of time.
This prayer negates the effects of fear on the player.
This prayer negates darkness in an open space.
This prayer shows the player all of the invisible traps on the screen.
This prayer shows the player all of the doors and stairs on the screen.
This prayer lessens the effects of poison, but does not cure it.
This prayer causes a creature to lose it’s sight.
This prayer transports the player to a nearby location.
This prayer cures a medium number of the player’s hit-points.
This prayer improves the player’s armor class and fighting ability for a medium period of time.
This prayer causes neighbouring monsters to fall asleep for a while.
This prayer creates food. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.
This prayer makes it possible to take off a cursed object.
This prayer lessens the effects of heat and cold attacks on the player.
This prayer cures the effects of poison.
This prayer drains experience from a creature.
This prayer cures a large number of the player’s hit-points.
This prayer shows the player all of the invisible creatures on the screen.
This prayer lessens the attacks of evil characters on the player.
This prayer rents the earth and collapses the ceiling.
This prayer shows the walls on the screen.
This prayer cures a very large number of the player’s hit-points.
This prayer attempts to make undead creatures flee the player.
This prayer improves the player’s armor class and fighting ability for a long period of time.
This prayer attempts to utterly destroy an undead creature.
This prayer restores up to 200 of the player’s hit-points.
This prayer attempts to utterly destroy an evil creature.
This prayer gives a permanent, non-cumulative small resistance to poison gas.
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.
This prayer dispels evil, removes fear, cures poison, restores 1000 HPs, restores all stats, and invulnerability for 3 turns.
This attribute gives an object a unique behaviour. It can be one of the following values:
This value indicates that this object is left behind after a chest is bashed.
This value indicates that it is used as a base object when creating new objects in wizard mode.
This value indicates that this object is left on the ground after a ‘glyph_of_warding’ prayer or ‘warding_glyph’ scroll is read.
This value indicates that this object is created by a ‘create_food’ spell or prayer.
This value indicates that the object is administrative in nature, and is used as a necessary placeholder in the player’s inventory.
This attribute applies to objects that have a ‘kind’ of ‘POTION’. It can have one of the following values:
Causes the player’s strength stat to increase.
Causes the player’s strength stat to descrease.
Causes the player’s strength stat to return to a normal level.
Causes the player’s intelligence stat to increase.
Causes the player’s intelligence stat to descrease.
Causes the player’s intelligence stat to return to a normal level.
Causes the player’s wisdom stat to increase.
Causes the player’s wisdom stat to descrease.
Causes the player’s wisdom stat to return to a normal level.
Causes the player’s charisma stat to increase.
Causes the player’s charisma stat to descrease.
Causes the player’s charisma stat to return to a normal level.
Restores a small number of the player’s hit-points.
Restores a medium number of the player’s hit-points.
Restores a large number of the player’s hit-points.
Restores up to 1000 of the player’s hit-points.
Causes the player’s constitution stat to increase.
Causes the player to gain experience, and possibly a level.
Puts the player into a deep sleep.
Makes the player unable to see anything at all. Reading from scrolls or books is impossible.
Makes the player act erradically.
Causes the player’s hit-points to steadily decrease.
Makes the player move faster for a temporary amount of time.
Makes the player move slower for a temporary amount of time.
Causes the player’s dexterity stat to increase.
Causes the player’s dexterity stat to return to a normal level.
Causes the player’s constitution stat to return to a normal level.
Negates the effects of blindness when the player is blind.
Negates the effects of confusion when the player is confused.
Completely negates the effects of poison when the player is poisoned.
Causes the player to lose experience points, and maybe lose a level.
Causes the player to throw up! The potion cures poison and the player becomes hungry sooner.
Negates the effects of attacks on the player for a temporary period of time.
Causes the player temporarily receive more hit-points and become a better fighter.
Causes the player temporarily receive more hit-points and become a better fighter. More effective than ‘heroism’.
Negates the effects of fear when the player is afraid.
Causes the player experience points to be restored to a normal level.
Lessens the effect of fire attacks on the player.
Lessens the effect of cold attacks on the player.
Causes the player to be able to see invisible creatures for a short amount of time.
Lessens the effects of poison when the player is poisoned.
Completely negates the effects of poison when the player is poisoned.
Restores the player’s magic points.
Causes the player to see creatures farther into the darkness.
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.
Causes the player’s hit-points to steadily decrease for a temporary amount of time.
Causes the player to become blind for a temporary period of time.
Causes the player to become afraid for a temporary period of time.
Causes the player to act erradically for a temporary period of time.
Causes the player to act more erradically for a longer period of time.
Negates the effects of poison when the player is poisoned.
Negates the effects of blindness when the player is blinded.
Negates the effects of fear when the player is afraid.
Negates the effects of confusion when the player is confused.
Causes the player’s strength stat to decrease.
Causes the player’s constitution stat to decrease.
Causes the player’s strength stat to return to a normal level.
Causes the player’s constitution stat to return to a normal level.
Causes the player’s intelligence stat to return to a normal level.
Causes the player’s wisdom stat to return to a normal level.
Causes the player’s dexterity stat to return to a normal level.
Causes the player’s charisma stat to return to a normal level.
Restores a small number of the player’s hit-points.
Restores a medium number of the player’s hit-points.
Restores a large number of the player’s hit-points.
Restores a very large number of the player’s hit-points.
Decreases the player’s hit-points.
This attribute applies to objects that have a ‘kind’ of ‘STAFF’. Any one of the following values can be used:
Negates darkness in an open space.
Shows secret doors that are located on the screen.
Shows traps that are located on the screen.
Shows gold that is located on the screen.
Shows objects that are located on the screen.
Teleports the player elsewhere on the level.
Rent the earth and collapse the ceiling.
Make a monster appear nearby.
Rent the earth and collapse the ceiling, in a larger radius.
Make a shaft of light appear in all directions.
Make monsters on the screen move faster.
Make monsters on the screen move slower.
Make monsters on the screen go to sleep.
Restore a small amount of the player’s hit-points.
Show invisible creatures that are located on the screen.
Make the player go faster temporarily.
Make the player go slower temporarily.
Change the monsters on the screen to other other monsters.
Make a cursed item able to be taken off.
See the evil creatures that are located on the screen.
Negate the affects of poison, blindness, and confusion.
Attempt to utterly destroy an undead creature.
Turn out the lights!
This attribute applies to objects that have a ‘kind’ of ‘WAND’. It can be one of the following values:
Make a shaft of light appear in a given direction.
Throws a lightning bolt at a target.
Throws a magical arrow of ice in a given direction.
Throws a magical arrow of fire in a given direction.
Dissolves walls and rock-based creatures in a given direction.
Changes a target creature into another creature.
Restores hit-points in the target creature.
Makes the target creature move faster.
Makes the target creature move slower.
Makes the target creature move erradically.
Makes the target creature go to sleep.
Reduces experience from the target creature.
Makes targeted traps or doors disappear.
Throws a magical arrow in a given direction.
Makes a line of walls in the given direction
Duplicates the target creature.
Transport a target creature to another place on the level.
Disarms all chests and traps in a given direction.
Throws a ball of lightning at a group of opponents.
Throws a ball of ice at a group of opponents.
Throws a ball of fire at a group of opponents.
Throws a ball of poison at a group of opponents.
Throws a ball of acid at a group of opponents.
This wand behaves randomly like a different wand.
This attribute applies to objects that have a ‘kind’ of ‘SCROLL’.
Attempts to increase a selected weapon’s hit bonus.
Attempts to increase a selected weapon’s damage bonus.
Attempts to increase the armor class of a piece of armor.
Assists the player in discovering the true nature of a selected object.
Makes it possible to take off a cursed object.
Negates darkness in an open space.
Make a monster appear nearby.
Transport the player to a nearby location.
Causes the player to be randomly transported to another place on the map.
Causes the player to be randomly transported to another level of the dungeon.
Makes the next creature the player hits move erradically.
Shows the player the hidden walls on the screen.
This spell makes a group of creatures fall asleep.
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.
Shows gold that is located on the screen.
Shows objects that are located on the screen.
Shows traps that are located on the screen.
Shows secret doors that are located on the screen.
Kills all creatures on the whole level except for the Balrog.
Gives the player the ability see where invisible monsters are.
Causes the player to wake up monsters that are sleeping nearby.
Creates a set of traps that enclose the player.
Make traps and doors disappear.
Creates a set of doors enclosing the player.
Charge a staff or a wand.
Destroys all creatures of a given appearance on the level.
Turn out the lights.
Lessen the attacks of evil characters on the player.
This scroll creates food when it is read. See the ‘created_by_spell’ value of the ‘unique_function’ attribute for which foodstuff is created.
Attempts to utterly destroy an undead creature.
Attempts to enchant a weapon that the player is weilding.
Curses a weapon the player is weilding.
Attempts to enchant armor that the player is wearing.
Curses armor the player is weilding.
Make an undead monster appear nearby.
Improves ther player’s armor class and fighting ability for a short period of time.
Improves the player’s armor class and fighting ability for a medium period of time.
Improves the player’s armor class and fighting ability for a long period of time.
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.
Rents the earth and collapses the ceiling.
This attribute applies to objects that have a ‘kind’ of ‘CHEST’. It can have any combination of the following values:
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.
When this value is set, the chest will carry any object that is found in the dungeon.
When this value is set the chest will carry some gold.
The chest contains objects 60% of the time.
The chest contains objects 90% of the time.
The chest contains a minimum of 1 object, and a maximum of 2 objects.
The chest contains a minimum of 2 objects, and a maximum of 4 objects.
The chest contains a minimum of 4 objects, and a maximum of 8 objects.
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.
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.
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.
The following consistency checks are implemented:
moria-tc
will typically be used in this fashion:
moria-tc
on the new treasure-definition file
moria-tc
on the same treasure-definition file but this time with the –constant option
The following persons have contributed to this software:
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.