Header declarations

Prior to the map itself being declared, any number of header declarations may be written.

(All declarations apart from NAME: are translated to Lua function calls behind the scenes. See the Lua reference for more information.)

Try to respect line lengths of 80 characters. Should some line exceed that (which is quite possible, especially for ITEM and MONS lines), you can use the \ symbol to break a line. You can break a line anywhere, with the exception of comma-separated lists, where you cannot start a new line with a comma. See the end of this section for examples.

Vault Metadata

These declarations describe basic information about your vault for the game to use.



NAME:     a_string

Each map must have a unique name. Underscores and digits are ok.



DESC:     readable name

A map may optionally have a description. If provided, and if the character dies in the vault, the map description will be shown along with the place at end of game. For instance, Cerebov's castle has DESC: Cerebov's castle, resulting in deaths being described as:

   Killed from afar by a Balrug (32 damage)
   ... with a bolt of fire
   ... in Pandemonium (Cerebov's castle).

Map descriptions are also written to scores and logfile entries.



TAGS:    <tag>[ <tag>][ <tag>] ...

Tags can mark vaults with special properties and attributes, and can also be used as ah-hoc string identifiers in combination with other techniques (see SUBVAULT and serial_vaults).

Tags go on a TAGS: line and are space-separated. You can have several TAGS: lines, or use \ for very long ones. Valid tags are:

  • “allow_dup”: Vaults are normally used only once per game. If you have a vault that can be used more than once, use allow_dup to tell the dungeon builder that the vault can be reused.
  • “chance_FOO”: Maps can be tagged chance_ with any unique suffix to indicate that if the map's CHANCE roll is made, one of the maps tagged chance_FOO should be picked.
  • “dummy”: this tag indicates that the vault is a stub; if the dungeon builder picks a dummy vault, it pretends no vault was selected. Dummies are used to reduce the probability of other vaults at the same depth / place.
  • “entry”: this tag MUST be there for a vault to be pickable as an entry vault.
  • “extra”: requests that the dungeon builder treat this as an extra vault and try to immediately place another vault of the same type it was trying to place when it placed this vault. “extra” is good to use for things like labyrinth entries that should not affect the chance of other minivaults on the level. If you use “extra”, you probably want to use one of the “luniq” tags as well if your map is tagged “allow_dup”.
  • “generate_awake”: Monsters placed (using MONS, KMONS) in this vault will be generated awake.
  • “patrolling”: Monsters placed (using MONS, KMONS) in this vault will be generated with their starting position as patrol point. If not otherwise occupied (fighting, seeking) they will patrol the area.
  • “no_item_gen”: Prevents random item generation in the vault. Items explicitly placed by the vault are not affected.
  • “mini_float”: applicable only to minivaults, requests that the dungeon builder pick random exits from the minivault and connect it to the rest of the level, similar to the exit behaviour for floating vaults. Has no effect if the minivault has explicitly defined exits (the @ glyph).
  • “no_monster_gen”: Prevents random monster generation at the time of the vault's creation. Highly advised for entry vaults with a player-hostile geography, MUST-HAVE for those with water/lava. Can be applied only to particular symbols with KMASK.
  • “no_pool_fixup”: prevents water squares next to land from being randomly converted from deep water (the default) to shallow.
  • “no_wall_fixup”: In Dis, the Vaults and the Crypt a vault's rock walls will be changed to be the same as the wall type of the rest of the level. If you don't want that to happen then use this tag.
  • “no_trap_gen”: Prevents random trap generation at the time of the vault's creation.
  • “uniq_BAR”: (uniq_ with any suffix) specifies that only one of the vaults with this tag can be used in a game.
  • “luniq”: specifies that this vault can be used only once on a given level. “luniq” is only relevant when used with “allow_dup”.
  • “luniq_BAR”: (luniq_ with any suffix) specifies that only one of the vaults with this tag can be used on any given level. “luniq_BAR” is only relevant when used with “allow_dup”.
  • “branch_entry” eg. “orc_entry”, “lair_entry” etc. If chosen, these maps will contain the stairs for that branch. If a branch has very few entries, a dummy entry is advisable to make sure the player doesn't get bored of the same few entries recycled ad nauseam. Note: if any TAG argument contains an “entry”, the vault will be no longer eligible for random placement. (Currently, this just affects your choice of BAR when using uniq_BAR.)
  • “mnoleg” or the name of some other pandemonium lord. This makes the map eligible for said pan lord's lair. See pan.des.
  • “minotaur” turns this into a labyrinth exit vault. “lab” turns this into an additional labyrinth flavour vault. See lab.des for examples and details.
  • “no_rotate”: Normally, the dungeon builder can, at its whim, rotate your vault. This flag tells it, “hey, don't do that to my vault!”
  • “no_hmirror”: Like no_rotate, but for horizontal mirroring.
  • “no_vmirror”: Like no_rotate, but for vertical mirroring.
  • “overwritable”: Lets the dungeon builder overwrite this vault with other ones. Don't use this casually.
  • “can_overwrite”: Tells the dungeon builder that this vault can be placed on top of other vaults, even those without the “overwritable” tag. Don't use this casually.
  • “layout”: Makes the vault eligible for use as a level layout. Do not use this unless you know what you are doing.
  • “layout_foo”: Indicates what sort of level layouts this vault is compatible with, for vaults that don't fit in with all layouts; the absence of this type of tags means it can go with any layout. Multiple layout_foo tags can be used if it can be used with multiple layouts. Current values for “foo” are: rooms, city, open, caves, cross, shoals, swamp, labyrinth (though currently random vaults aren't placed in the last three).
  • “no_species_xx”: Disables the vault for a given player species (two-letter abbreviation). Note that the current design rules strictly disallow varying the map generation based on the character – this tag is only for acquirement-like effects, sprint, or tutorial.
  • “ruin”: requests the level builder to damage the vault by removing walls near the edges, making it look like a ruin. You can request that a vault be ruined only in a particular branch using “ruin_<branch>”. For instance: “ruin_lair”.
  • “trowel_portal”: This vault can be created by the Trowel card. This tag should be used exclusively for the generic (one tile) entries to portal vaults, like bazaars and labyrinths. Other portal vaults may be eligible for Trowel, too.
  • “no_dump”: Don't dump out this vault's name in the list of vaults generated during the game. Use this if the vault is predictable (like the Vault:8 and Slime:6 vaults) or are for weird internal uses (like the shoalhut vaults).
  • “unrand”: Don't pick this vault randomly by DEPTH. Can still be picked by tag or PLACE.
  • “transparent”: Marks the vault as potentially passable for the purposes of level connectivity. By default, vaults are considered non-passable regardless of their contents. With this tag, the actual terrain of the vault affects its passability as seen by the dungeon builder.

Vault Placement

These factors control how the vault gets placed within the actual dungeon; how it is oriented within the level, appropriate depths or special places where it can appear, and



ORIENT:   (float |encompass | north | northwest | ... | southeast)

Some kind of ORIENT: line is mandatory for vaults; skipping ORIENT: makes your map a minivault. As a rule of thumb, if you're writing a small random map, skip the ORIENT: line and make it a minivault.

  • “float”: The dungeon builder puts your vault wherever it wants to.
  • “some_direction”: The vault lies along that side of the map:
     xxxxxxxxxxxx       xxxxxxxxxxxxx
     x.ORIENT:N.x       xORIENT:NW|..
     x..VAULT...x       x.VAULT...|..
     x----------x       x---------|..
     x.rest.....x       x.rest.......
     x..|.of....x       x..|..of.-->.
     x..v.level.x       x..v....level

ORIENT: float vaults give a lot of flexibility to the dungeon generator; float should generally be preferred to other ORIENT: settings for new vaults.


For random vaults, branch entry vaults, and minivaults, this specifies the range of levels where the vault may be placed in the dungeon. E.g.


DEPTH: 7-20

DEPTH: does not force a map to be placed in a particular place; it applies only when the dungeon builder is looking for a random vault or minivault, so you can control at what depths your vault gets placed.

A simple DEPTH: declaration that does not specify a branch applies to all branches. A map declared with depth 7-20 could be used in the Lair, for instance (Lair:1 will be treated as a depth of 12 if the Lair entrance is on D:11). In general, you should avoid using such unconstrained DEPTHs unless you know what you are doing.

You can constrain a map by branch:

DEPTH: Lair:3-6

(Anywhere between levels 3-6 of the Lair, inclusive.)

You can apply multiple constraints in one DEPTH line, comma-separated:

DEPTH: 7-20, !12-14

(Anywhere in the dungeon between depths 7-20, but not on levels 12-14.)

DEPTH: 7-20, !Orc

(Anywhere in the dungeon between depths 7-20, but never in the Orcish Mines.)

DEPTH: Lair:*

(Anywhere in the Lair. Can also be expressed as “DEPTH: Lair”.)

Maps that do not specify a DEPTH: attribute will inherit their depth constraints from the closest preceding default-depth: line. If there is no preceding default-depth directive in the .des file, the map will have no DEPTH: constraint. Note that maps without a DEPTH: constraint cannot be selected as random vaults or minivaults. It can make sense to use an empty DEPTH line as in


if these maps are otherwise chosen, e.g. by TAG. See serial_ponds.des for an example. When doing this, make sure that there is no default-depth line handing out a depth! (This can mean that you are better off with a new des file for elaborate vaults.)



CHANCE:   <priority>:<roll> or <roll> [ (<depth-ranges>) ]

CHANCE allows you to control the probability that your map is used on any given level with an absolute roll.

There are two ways to specify the CHANCE roll:



CHANCE: 5.01%

If specified as a raw number, the chance of selecting the vault is <number> in 10000. If specified as a percentage, the chance of selecting the vault is <perc> * 100 in 10000.

CHANCE is useful for random vaults with a DEPTH (or default-depth) setting that want to ensure a certain chance of being placed per level.

If a map in the current depth range has a CHANCE, Crawl will roll a random number in the range 1-10000, and select the map if the CHANCE is >= the rolled random number.

Dummy vaults may also use CHANCE to specify an absolute chance of using the dummy instead of a real map. For dummies, use CHANCE with a priority of 0:

CHANCE: 0 : 80%

This specifies a CHANCE of 80%, which means the dummy will be used in 80% of vault placement attempts.

The Lua equivalent of the two simple CHANCE forms is:

 : chance(<number>)
 : chance(<priority>, <number>)

These lines are all equivalent:

 : chance(500)

A common case when using CHANCE is to assign a CHANCE to a set of maps. For instance, if you have a set of portal vault entries, and you want one of the set to be used on 5% of all levels, you can do this:

NAME: portal_a
CHANCE: 50 : 5%
TAGS: chance_portal_group

NAME: portal_b
CHANCE: 50 : 5%
TAGS: chance_portal_group

That is, if you have a set of maps that use CHANCE and are tagged chance_xxx, then one map of that set will be used when the chance is met.

In some cases you'd like to set a different CHANCE based on where the vault is being placed. For instance:

NAME: ziggurat_portal
CHANCE: 5% (Pan), 2% (D:*, Lair:2-4), 3%

If you specify a depth range in parentheses after a chance spec, that spec applies only in that depth range. Each chance's depth range will be checked in the order specified, with the exception of the default chance (3% in this example) which is always checked last.

The Lua equivalent of depth-constrained CHANCE:

CHANCE: 2% (D:*, Lair:2-4), 0 : 50% (Geh)

is as:

 : depth_chance("D:*, Lair:2-4", 200)
 : depth_chance("Geh", 0, 5000)



WEIGHT:   (number with 10 being default)

For entry vaults and any other vaults randomly picked from among a set, this type of line affects the likelihood of the given vault being picked in a given game. The default WEIGHT: is 10. The likelihood of a vault getting picked is: [vault's WEIGHT: / sum of all WEIGHT:s of vaults of that type]

As with CHANCE, you may constrain weights to apply only in certain depths:

WEIGHT: 100 (D:2-4), 20 (Crypt, Zot)

(Note that the default weight is always 10 unless explicitly changed)

The Lua equivalent of a depth-constrained WEIGHT: WEIGHT: 100 (D:2-4) is : depth_weight(“D:2-4”, 100)



PLACE:    Used to specify certain special levels. Existing special levels include most branch ends.

The branches need to use the official abbreviations also used e.g. in the overmap (Ctrl-O): D, Temple, Orc, Elf, Lair, Swamp, Shoal, Slime, Snake, Hive, Vault, Blade, Crypt, Tomb, Hell, Dis, Geh, Coc, Tar, Zot.

PLACE can also be used to specify arbitrary places, like D:3, which will force the map (or one of the maps with PLACE: D:3) to be picked when D:3 is generated.

PLACE cannot be used to specify places in the Abyss, Pandemonium, or Labyrinths.

PLACE can be used with random vaults and minivaults for testing them.


The SHUFFLE, SUBST and NSUBST declarations are all methods of randomising the glyphs in your vault map (often prior to applying items, feaures, or monsters to them with declarations like KITEM, KFEAT, and KMONS.



SHUFFLE:  def, 12/3?

This allows you to randomly permute glyphs on the map. There are two ways:

SHUFFLE: 123w     (i.e. list of glyphs, NOT slash-separated)

could, for example, swap all occurences of “1” with “2”, as well as swapping all “3” with “w” (or any other of the 24 possibilities).

SHUFFLE: 12/3w    (i.e. list of slash-separated blocks of same size)

will either do nothing or swap all “1” with “3” and then also swap “2” with “w” everywhere.

Several SHUFFLE: lines can be used, and mixed with SUBST:, and the shuffles and substitutions will be applied in order. You can also put multiple SHUFFLEs on one line, comma-separated. Shuffles cannot use , or /. All spaces are stripped before shuffling.



SUBST:    ?=xc, !:bv, 1=2 1:100

The SUBST: directive allows you to specify a placeholder symbol that is replaced with a random glyph from a set. For instance:

SUBST: ? = T U V

replaces occurrences of ? with one of TUV. Since whitespaces are irrelevant, the two lines are equivalent.

SUBST: ? = T:20 U V

makes T twice as likely to be used as U or V (the default weight is 10). Note that there has to be at least one space before and after T:20 and that whitespace in T:20 is not permitted.


replaces occurrences of ? with one of TUV, and guarantees that all occurrences of ? will get the same replacement symbol.

The placeholder and replacement symbols can be any non-space, printable character, including : and =, apart from commas. For example, the following is valid:

SUBST: = = +=:123def"

SUBST: lines can safely replace symbols with themselves, as in:

SUBST: w = wW

Multiple substitutions can be performed on one line, using commas:

SUBST: w = wW, ? : TUV

Multiple SUBST lines can be used, and mixed with SHUFFLE or NSUBST. Each line will be applied in order.


Substitutes glyphs from a numerically-controlled pool of replacement glyphs.


NSUBST:   <glyphs> = <substitution>[ / <substitution>] ... [ / <remainder>]


NSUBST:   A = 3:w / *:l

NSUBST is similar to SUBST, replacing placeholders with replacement values. Unlike SUBST, however, it allows you to replace the same placeholder with many different glyphs (instead of choosing one substitution and replacing all occurrences with it).

NSUBST specifications can be quite complex and composed of many parts. They feature a slash-separated list of individual substitutions. Each substitution will be performed in order, as long as there are enough target glyphs left.

A substitution's syntax is as follows:

<count><operator><replacement>[:<weight>][ <replacement>[:<weight>] ...

The <operator> can be either ':' or '=':

  • ':' indicates that one replacement will be chosen and used for <count> number of glyphs
  • '=' indicates that each of <count> glyphs can roll any of the replacements in this term

Any number of terms can be included in a complete substitution.

Weight makes different glyphs more or less likely to be used. Every glyph has a default weight of 10 if not specified. When weights are not specified, no separator spaces are required between the replacement glyphs.

The final <remainder> term may use a special case '*' for the <count>. This indicates that all remaining affected glyphs will be substituted.


– TODO: Before/after map examples would be nice here

NSUBST: ? = 3:wW

Replace three occurrences of ? with either all w or all W.

NSUBST: ? = 3:wW / 3=wW

Replace three occurrences of ? with either all w or all W. Then, replace three more occurrences of ? with any mixture of w and W.

NSUBST: ? = 3:wW / 3=w:5 W / *:l

Replace three occurrences of ? with either all w or all W. Then, replace three more occurrences of ? with any mixture of w and W, where w is half as likely as W. All remaining ? are replaced with l.

You can use complex SUBST specifications:

? = 3= w .:15 A / *: =+CF

This is equivalent to SUBST: ? = w .:15 A for three ? and SUBST: ? : =+CF for all the others.

You can use any number of NSUBST specifiers:

? = wW / l / A / 1234

If you omit the initial <count>: or <count>=, then 1= is assumed, except for the last spec where *= is assumed.

The parser can get confused with NSUBST specifications like wW / nc=. If you use replacement symbols from * or = (perhaps also for / and numbers), it is safer to spell out the <count> preceding the replacement symbols.



SUBVAULT: X : some_vault_tag / some_other_vault_tag:20

Pick a vault that matches the tag and replace matching glyphs in the current map with the cells from that vault.

Multiple glyphs can be specified on the left hand side and weighted sets of tags can be used on the right hand side.

The use of an equal sign to pick a different subvault per-glyph, e.g. “X = some_vault_tag” is not supported at this time. Use a ':' instead to fix the choice of vault tag among all glyphs.

When a subvault is applied, the first step is finding the smallest bounding box around the glyphs. For example, in the following vault definition, the smallest bounding box around the X glyph is a 4×3 rectangle:


After the bounding box is calculated, a valid subvault that matches the given tags and is no larger than the bounding box will be found. If no subvault can be found, the vault will throw an error. If a subvault is found that is smaller than the provided bounding box, then it will be randomly placed and possibly rotated within the bounding box.

There is not much optimization to best fit a subvault into the glyphs provided by the parent vault. So, take some care when using non-rectangular subvaults. The only special case is if you provide a subvault that is the exact same shape as what the parent vault requests.

Everything from the subvault cell (feature, items, monsters, properties, markers) overwrite the glyph in the parent map. Once replaced, this cell is immutable and cannot be changed with something like SUBST, MARKER, or KFEAT.

Additional glyphs that are not replaced by the subvault will be left untouched so that the parent vault can replace them with whatever feature it desires. These untouched glyphs can occur either because the subvault was smaller than the bounding box or because the subvault left the glyph blank (' '). Because of this, a SUBVAULT command should usually be followed by a SUBST command to clean up these remaining glyphs.

Subvaults are allowed to include subvaults themselves, recursively. However, there is no checking for infinite loops or cycles of subvaults, so use this feature with some care.

During map verification, the SUBVAULT command does not do anything. Therefore, the compilation step for Lua vaults will not catch errors where no maps exist for a given tag or where all maps that do exist are too big to fit into the provided space in the parent map. (The reasoning for not verifying the subvault command is so that you can specify maps by tag that may be defined later in the file or even in another file that hasn't been loaded yet.) So, test your subvaults!

As the size of the subvault may vary depending on the parent vault, there are some helpful Lua functions (in the dgn module) that can be used to get more information about what the parent vault is requesting. Here's a quick reference:

Dungeon Features and Inhabitants

The most crucial part of vault design is careful placement of appropriate items, features, and of course monsters. Not that all vaults need specify these things; it's perfectly fine to design purely architectural vaults and let the dungeon builder decide on the furniture.

But, if your vault is designed with a specific theme or tactical scenario in mind, you will doubtless want a degree of control over what goes where. These declarations provide a number of ways to easily place specific features as well as randomised sets of features in your vault.



  ITEM:     (list of items, separated by comma)

These are used to help place specified items at specific places within a vault. They create an array with up to 8 positions. What's in the first position in the array will be used when the dungeon builder sees a “d” in the vault definition, the second will be used for “e”s, etc. Positions are comma-separated; several ITEM: lines are possible as well. The following defines letters 'd' - 'g':

ITEM: stone, ring mail, meat ration, ring of hunger

Positions can contain multiple possibilities, one of which the builder will choose randomly. Separate such multiple possibilities using a slash. Note that “nothing” (without the quotes) is a valid possibility. The random choice is done for each individual occurence of the letter. You can also give possibilities a “weight,” which affects their chance of being picked. The default weight is 10. You can abbreviate “weight:30” by “w:30”. The chance to pick a possibility is [possibility's weight: / sum of all weight:s in that array position]

For example, the following line makes letter 'd' into a bread ration with 50% chance, or apple or orange with 25% chance each:

ITEM: bread ration / w:5 apple / w:5 orange

NOTE: You can place multiple items on the same square by using the KITEM directive. See the following section for more information.



KITEM:    ? = potion of healing / potion of restore abilities

See item definitions for how to define individual items and their properties.

KITEM: places the specified item at all occurrences of the placeholder. It can be combined with KFEAT: and KMONS: lines for the same placeholder.

You can use q: to specify quantities:

KITEM: ? = q:100 gold

KITEM: allows you to place multiple items on the same square:

KITEM: ? = bread ration, potion of water, potion of porridge



MONS:     [[dcss:help:maps:syntax:monster_info|<monster_info>]], [[dcss:help:maps:syntax:monster_info|<monster_info>]] ...

These are used to help place specific monsters at specific places in a vault. They create an array with up to 7 positions. What's in the first position in the array will be used when the dungeon builder sees a “1” in the vault definition, the second for “2,” etc. Note that if, for example, you place a 3 on the map, but your MONS: line has no third position, the 3 will be filled with RANDOM_MONSTER. Also note that for entry vaults (D:1), all monsters in sight of the hero are removed. This does not hold for plants. You can use weights as for ITEM: lines.

See monster_info for more details on how to define monster properties.

Note that the glyphs 8, 9, 0 (without MONS) also place monsters.



KMONS:    ? = orc priest / w:3 deep elf priest

KMONS: allows you to specify a placeholder symbol that indicates the position of a monster (or monsters).

Using KMONS: allows you to exceed the 7 slot limit for monsters.

It is also useful if you want to place a monster on a non-floor square (used in association with a KFEAT:). For example,

KMONS: Z = rat

places a rat on a shallow water square for all occurrences of Z.

KMONS: also allows you to specify alternative monsters if the primary monster you want to place is unavailable (because it is a unique that was already generated). For instance, if you want to generate one of Terence, Michael or Erica or a generic human (whoever is available, in that order, you can use):

KMONS: n = Terence, Michael, Erica, human

Or if you want to pick randomly:

KMONS: n = Terence / Michael / Erica, human



KFEAT:    G = C / needle trap / antique armour shop / altar_zin

The KFEAT: directive allows you to specify a placeholder symbol that is replaced with another symbol, named feature, trap, or shop. For example, the line above will replace occurrences of G with C (random altar), a needle trap, an antique armour shop, or an altar of Zin. Different instances of G may receive different replacements. To force a single replacement for all G, use:

KFEAT:    G : C / needle trap / antique armour shop

You'll notice that 'G' is the symbol of a granite statue. Kxxx directives allow you to assign arbitrary definitions to any symbol.

The 'web' trap doesn't need the word 'trap':

KFEAT:    A = web / floor

KFEAT features are specified as a feature name (see terrain.cc for a full list of feature names). As another example, you can place a portal to the Abyss as:

KFEAT:    A = enter_abyss

If you want no feature as an option in a KFEAT line, use '.' or 'floor'. If you do not want to specify the type of shop, use 'any shop' or 'random shop'. If you wish to specify more complex options for shops, please go to Shop definition.

If you want a trap to start out known to the player, add “known” to the trap name:

KFEAT: A = known needle trap

You can also place feature mimic using the same syntax as item mimics (or prevent random placement of feature mimics). For example this altar has one chance in 10 of being turned into an altar mimic:

KFEAT: C = C mimic:10

The placeholder used by KFEAT can be shared by KITEM and KMONS; see below. If the placeholder is shared, all defined Kxxxx operations for the placeholder are performed. Also, all Kxxx lines accept weights as for MONS or ITEM.



KMASK:    Z = no_monster_gen

KMASK allows you set or unset various masks for particular symbols, rather than for the entire vault like if you did it with TAGS. Valid masks are

  • “no_item_gen”: Prevents random item on that symbol. Items explicitly placed on that symbol aren't affected.
  • “no_monster_gen”: Prevents random monster generation on that symbol. MUST-HAVE for those with water/lava symbols in entry vaults.
  • “no_trap_gen”: Prevents random trap generation on that symbol.
  • “no_pool_fixup”: prevents a water square next to land from being randomly converted from deep water (the default) to shallow.
  • “no_wall_fixup”: prevents (rock) walls from being converted to the level's default wall type, such as in Vaults.

For example

KMASK: W = no_monster_gen

will prevent monsters from randomly being generated on shallow water squares. Note that if shuffling and substitutions cause W to end up as water 10% of the time and floor 90% of the time, then those floor squares will still have no_monster_gen set, but that's still a higher degree of control than you get with TAGS.

If TAGS has been used to set a mask for the entire vault, you can use KMASK to remove that mask from particular symbols. For instance:

TAGS:  no_monster_gen
KMASK: W = !no_monster_gen

would make it so that monsters are only randomly generated on shallow water squares.

Unlike KFEAT, KITEM, and KMONS, KMASK does not override the normal meaning of the glyph.

Like KFEAT, KMASK applies to cells that have the specified glyph after applying all shuffles and substitutions.



KPROP:    x = bloody

KPROP: allows you to assign a specific property to a feature. Like KFEAT: and KMONS:, it can be combined with these for the same place-holder.

Unlike KFEAT etc., KPROP is applied to the cells of the map that currently have that glyph, applying only the shuffles and substitutions before the KPROP declaration. That is:

KFEAT: ' = rock_wall
KPROP: ' = bloody
SUBST: ' = '.

causes ' to produce a bloody wall or a bloody floor at random, while:

KFEAT: ' = rock_wall
SUBST: ' = '.
KPROP: ' = bloody

causes ' to produce either a bloody wall or a bloodless floor.

Unlike KFEAT, KITEM, and KMONS, KPROP: does not override the normal meaning of the glyph.

Available properties are:

  • “bloody”: Causes features to appear as though splattered with blood. This should be used very, very sparingly!
  • “no_cloud_gen”: Prevents clouds from being generated over this feature (usually lava). Does not stop fog generators or clouds entering from nearby squares.
  • “no_rtele_into”: Prevents random teleport from chosing to use this square. Use this to prevent nasty situations like the player ending up in a closet (for example, because your map randomises wall/floor so much that closets may occur) or an extremely dense monster array (like a hellion island).
  • “no_ctele_into”: Prevents controlled teleportation into this square. Will instead generate the message “A strong magical force throws you back!”.
  • “no_tele_into”: Combines the above no_rtele_into and no_ctele_into in one flag, and disallows both random and controlled teleports. Use this for vaults with loot where the player is not supposed to get it by teleporting alone.
  • “no_submerge”: Monsters will not submerge in this square.
  • “no_tide”: Shoals tides will not affect this square.
  • “no_jiyva”: No spawning jellies, no off-level eating.

Two additional named properties exist, but should be avoided:

  • “highlight”: The square will be highlighted in the X map in wizard mode, and will appear in dumps as ”?”. For debugging use only; this property should be removed before submitting vaults.
  • “mold”: The square is covered with mold. This property is reserved for use by ballistomycetes and should in general not be set by vaults.

Properties can also be used as tags to apply to the entire vault:

TAGS: no_rtele_into no_tide

Visual Properties

Whilst this feature should be used sparingly and with care, it is possible to manipulate the way most things will appear on the user's screen (both in Console and Tiles builds).



COLOUR:   . = green / blue:5 / red / none

COLOUR: allows you to attach explicit colours to any feature. Explicit colours will override the default colour for that feature. The example shown above colours all . (floor) in the map green, blue, red, or unchanged (use the default colour).

You can use : to specify that all glyphs get the same colour:

COLOUR: x : red / blue

will colour all rock walls in the map red, or all rock walls blue.

COLOUR: should be used very sparingly, and only for features where it won't cause confusion (i.e.: never re-colour features like lava or traps unless you really know what you do!)

If you apply COLOUR to a glyph and then apply a SUBST, the COLOUR will transfer to the resulting transformed glyph.

There are two types of basic colours available: base and “elemental”. Available base colours are as follows: blue, green, cyan, red, magenta, brown, lightgrey, darkgrey, lightblue, lightgreen, lightcyan, lightred, lightmagenta, yellow and white.

Elemental colours are: fire, ice, earth, electricity, air, poison, water, magic, mutagenic, warp, enchant, heal, holy, dark, death, necro, unholy, vehumet, beogh, crystal, blood, smoke, slime, jewel, elven, dwarven, orcish, gila, kraken, floor, rock, stone, mist, shimmer_blue, decay, silver, gold, iron, bone, elven_brick, waves, tree, random. See colour.h for comments on each.

Elemental colours can be based on both random numbers (for things that repeatedly change colour, such as Xom altars which use “random”) and on the map location where they are placed (for example, trees use “tree”), as well as any other part of the global state that is accessible (for example, shallow water in the Shoals uses “waves”, which is based on the current turn count and the height map of the map location). The majority of predefined elemental colours are based on random numbers, but you can easily define new colours to suit your maps.

Even more so than base colours, elemental colours should be used very, very, very sparingly.

Colours apply automatically to floor and rock wall tiles, although not all branches have coloured variations for their tile set.




allows you to set the floor colour for the whole level the vault appears in. Should only be used for bazaars and other portal vaults.



LROCKCOL: yellow

allows you to set the colour of rock walls for the whole level the vault appears in. Should only be used for bazaars and other portal vaults.



TILE:     x = wall_flesh

Identical to FTILE and RTILE in syntax, but closer to COLOUR in functionality. Instead of replacing the floor or relevant rock tiles, this can be used to replace the tile used for any specific feature.

This can be used in combination with FTILE and RTILE to change the appearance of features. It can only be used with previously specified tiles, however.

Like COLOUR and FTILE, this should be used sparingly and to good effect.

If COLOUR is also specified and there is a coloured variation of this tile, then it will be used.

To override doors, use the specific tile set in combination with the “no_random” specifier. Example:

  + = no_random dngn_fleshy_orifice



FTILE:    . = floor_grass:20 / floor_dirt / none

Similar to COLOUR, FTILE allows you to attach explicit floor tiles to any glyph. In non-tiles builds, this does nothing. If the tile specified has variations, those will be used automatically. Only tiles from the dungeon image can be used.

This will not (necessarily) replace the feature tile itself, only the floor. If you set the FTILE on a fountain glyph, then the fountain will still appear normally, but the floor underneath it will be the tile that was specified.

If a feature that normally covers the floor (e.g. rock walls) is destroyed, this floor tile will be used in place of the normal floor. Thus, it can be useful even for non-floor features.

Like COLOUR, this should be used sparingly.

If COLOUR is also specified and there is a coloured variation of this tile, then it will be used.



RTILE:    x = wall_hive:15 / wall_lair / none

Identical to FTILE, but for rock walls. Not useful for anything but the rock wall feature.



  LFLOORTILE: (tile name string, e.g. "floor_tomb")

Like LFLOORCOL, this overrides the default floor tiles used for this level. If the tile specified has variations, those will be used automatically.



  LROCKTILE: (tile name string, e.g. "wall_hive")

Same as LFLOORTILE, but for rock walls.

Rarely-used Properties

These properties are typically used in specific branches and portals and should not or need not be used in most vaults.




Persistent, changeable per-level flags which affect game behaviour; should only be used for vaults with ORIENT encompass or with PLACE. Causes a level's flags to be set when the level is first created. These flags can later be altered using Lua markers; for examples, look at the slime pit vault in slime.des, and the vaults in hell.des.

Valid flags are:

  • no_tele_control - prevents the player from using teleport control
  • no_magic_map - which prevents magic mapping from working.
  • not_mappable - prevents the player from remembering where they've been (like in the Abyss) - not recommended


— WARNING: I believe that the BFLAGS command was removed because 1) it is not in l_dgn.cc with the implementations for the other .des commands, 2) attempting to compile a LUA script containing it generates an attempt to call global 'bflags' (a nil value) error, and 3) the only appearance of the string “bflags” in the DCSS source code is in the LUA parser generator. If this can be confirmed, this section should be removed from the devwiki (here) and syntax.des. infiniplex



Persistent, changeable per-branch flags which affect game behaviour; should only be used for vaults which go on the first level of a particular branch. These flags can later be altered using Lua markers.

— TODO: Here it said said “see the Tomb vaults in vaults.lua for an example” of the above. However there is no longer a vaults.lua, and the Tomb vaults (tomb.des) do not include any Lua; so if anyone knows what this was a reference to, please update this! mumra

Valid flags are:

  • no_tele_control - prevents the player from using teleport control
  • not_mappable - prevents the player from remembering where they've been (like in the Abyss)
  • no_magic_map - which prevents magic mapping from working.
  • islanded - allows isolated zones with no stairs.
  • has_orb - the Orb of Zot is on the floor in this branch.



FHEIGHT:  xyz = 40

FHEIGHT sets the height in the level's heightmap for any specified features. If the level does not already have a heightmap, a heightmap will be attached to it when the dungeon builder sees FHEIGHT used.

Heightmaps are currently only useful in the Shoals, as a means of influencing how the tide interacts with your vault. The Shoals heightmap uses these heights when the tide's height is 0, i.e. at neutral tide:

>= 0 Floor
>= -14 Shallow water
⇐ -15 Deep water

The tide's height at low tide is -18, and at high tide is 25, though Ilsuiw's Call Tide spell can bring the tide's height up to 50.

In general, you do not need to use explicit FHEIGHT lines in your vaults. The Shoals dungeon builder will automatically assign suitable heights to features in vaults. FHEIGHT is primarily useful to override the default heights of features. If you use FHEIGHT to set nonstandard heights for features such as deep water (if you want deep water at heights > 0, for instance), you must also use KPROP to set the no_tide flag on that square, or the Shoals level builder will undo your height changes.

Lua Scripting



  MARKER:   A = feat:<feature_name> or lua:<marker_expr>

A marker ties a square on the map to a game-trigger of some sort (which depends on the marker and what feature it is on).

The portals to the Hells in the Vestibule of Hell are each annotated with feature markers like this:

MARKER: D=feat:enter_dis, G=feat:enter_gehenna

When the horn is sounded, the stone arch at D becomes the portal to Dis, the arch at G becomes the portal to Gehenna. This behaviour applies only to the Vestibule of Hell.

Lua markers are used for more complex triggers, such as for bazaar and labyrinth gates, rune pickup triggers for the branches of Hell, fog generators, etc.

Here's a Lua marker that creates a cloud generator (for a full explanation of the various parameters, read the header of dat/dlua/lm_fog.lua):

MARKER:  A = lua:fog_machine { \
   pow_max = 15, delay_min = 100, delay_max = 150, \
   size = 1, size_buildup_amnt = 29, \
   size_buildup_time = 1000 }

Feature names used in markers must be names matching the names in the source code. There's a full list of feature names in the Advanced section of this documentation.

An important note about markers is that they are also considered map transforms along with SUBST, NSUBST and SHUFFLE. You usually want to place a MARKER line after all SUBST, NSUBST and SHUFFLE lines so that the final position of the marker key is used. For instance, if you want to attach a marker to the rune in a map which randomises the position of the rune, this is a mistake:

MARKER: O = lua:<expr>

because the marker will be placed at O (the rune), then O may be shuffled to a different position. The correct order in this case is:

MARKER: O = lua:<expr>

Handling long lines

For most map headers, you can split long lines by ending the line that will be continued on the next line with \ as:

  KMONS: * = orc ; katana | quick blade . chain mail | scale mail / \
  goblin ; dagger

If you're using continuation lines for comma-separated lists of monsters or items, split your line after the comma, not before. For example:


  ITEM: potion of healing \
  , potion of speed


  ITEM: potion of healing, \
  potion of speed

But in general, it is preferable to use multiple ITEM or MONS lines if you're splitting comma-separated values:


      ITEM: potion of healing
      ITEM: potion of speed

Spaces before the \ of the continued line are significant, leading spaces of the next (continuing) line are not. In other words, given:

ITEM: potion of\

Crawl will see “potion ofhealing”, not “potion of healing”.

Assigning multiple glyphs at once

Declarations that modify glyphs allow multiple glyphs to be assigned simultaneously as a convenience. For example, the following declaration will assign floor_orc as the tile to be used for all up stair cases and floor:

  FTILE: .[{( = floor_orc

This case is identical to the longer syntax:

  FTILE: . = floor_orc
  FTILE: [ = floor_orc
  FTILE: { = floor_orc
  FTILE: ( = floor_orc

Using : instead of = while assigning glyphs will assign the same value to all glyphs. In the following example, the glyphs A, B, and C will either all contain gold or all contain nothing:

  KITEM: ABC : gold / nothing

Note: The number of items assigned in an NSUBST expression applies to the entire group of glyphs being assigned. For example:

  # Among all A, B, and C glyphs, make one a floor and the rest walls.
  NSUBST: ABC = 1:. / *:x
  # Make one A glyph floor, one B glyph floor, and one C glyph floor.
  # Make the rest of the A, B, and C glyphs walls.
  NSUBST: A = 1:. / *:x
  NSUBST: B = 1:. / *:x
  NSUBST: C = 1:. / *:x
Logged in as: Anonymous (VIEWER)
dcss/help/maps/syntax/headers.txt · Last modified: 2014-02-05 21:49 by infiniplex
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki