Des-file format
des-file format is the language which is used to describe the special levels for NetHack. It is compiled into a binary file by lev_comp.
There are two types of levels you can create: mazes and rooms. For MAZE-type levels you "draw" one or more maps with ASCII characters and then describe the monsters, objects and so on that are in the map. For ROOM-type levels, you describe rooms and their contents. The maze-levels are easier to make and understand, and room-type levels do not offer as much control over the level.
Contents
- 1 Language syntax
- 1.1 MAZE-type levels
- 1.1.1 MAZE
- 1.1.2 FLAGS
- 1.1.3 INIT_MAP
- 1.1.4 MESSAGE
- 1.1.5 NOMAP
- 1.1.6 GEOMETRY
- 1.1.7 MAP
- 1.1.8 NON_DIGGABLE
- 1.1.9 NON_PASSWALL
- 1.1.10 RANDOM_PLACES
- 1.1.11 RANDOM_MONSTERS
- 1.1.12 RANDOM_OBJECTS
- 1.1.13 DOOR
- 1.1.14 DRAWBRIDGE
- 1.1.15 REGION
- 1.1.16 STAIR-region
- 1.1.17 PORTAL
- 1.1.18 TELEPORT_REGION
- 1.1.19 BRANCH
- 1.1.20 MAZEWALK
- 1.1.21 WALLIFY
- 1.1.22 LADDER
- 1.1.23 GOLD
- 1.2 ROOM-type levels
- 1.3 Common syntax
- 1.1 MAZE-type levels
Language syntax
All lines beginning with # are comments and are ignored by the level compiler, except between MAP and ENDMAP.
Example:
# This is a comment.
MAZE-type levels
Maze-type levels begin with MAZE, followed with optional FLAGS, optional INIT_MAP, 0 or more MESSAGEs and up to 9 maze-parts, each of which consists either of NOMAP or GEOMETRY and MAP, followed by zero or more the random register initializers, one of each (RANDOM_MONSTERS, RANDOM_OBJECTS, RANDOM_PLACES), followed by zero or more of the map details (everything else, eg. MONSTER, OBJECT, TRAP, etc.)
That is:
- MAZE
- FLAGS, optional
- INIT_MAP, optional
- MESSAGE, 0 or more
- up to 9 map-parts, which consist of:
- NOMAP or GEOMETRY and MAP
- RANDOM_MONSTERS, optional
- RANDOM_OBJECTS, optional
- RANDOM_PLACES, optional
- The rest of the definitions of this map-part
Example:
MAZE:"test",' ' FLAGS:noteleport MESSAGE:"Welcome!" GEOMETRY:center,center MAP ..... .L.L. ..... .L.L. ..... ENDMAP MONSTER:random,random,random OBJECT:'%',random,random
MAZE
MAZE:"foo",'X'
- foo is the unique file name which will be used for this special level, up to 8 characters. For example: soko3-2. This file name is defined by the way this level is defined in dungeon.def.
- 'X' is the fill map character. The map will be filled with this dungeon feature before anything else is done. This can also be random, which fills the whole level with a checkerboard grid or walls and stone, so you can use MAZEWALK on it.
Example:
MAZE:"soko3-2",' '
FLAGS
FLAGS:flaglist
flaglist is one or more of the following flags, separated by commas
- noteleport: Player cannot teleport within the level.
- hardfloor: The floor is too hard to dig.
- nommap: magic mapping does not work.
- arboreal: supposedly an outdoor map. Basically solid walls will be trees, and corridors are not used.
- shortsighted: Monsters cannot see you from far away.
Example:
FLAGS:noteleport,hardfloor
INIT_MAP
INIT_MAP:'X', 'Y', smoothed, joined, lighted, walled
This causes the level map to be initialized with a random map generator, similar to how the random Gnomish Mines look like. Each MAZE-level can contain only 0 or 1 of these definitions.
- 'X' is the "foreground" fill map character. This should be something the player can walk on, as the walkable part will be made out of this.
- 'Y' is the "background" fill map character. This will surround the foreground area, so can be solid or harmful to player.
- smoothed is either true or false, and denotes whether the level will be "smoothed"
- joined is either true or false, and denoted whether the level will be "joined".
- lighted is either lit, unlit, or random
- walled is either true or false.
Examples:
INIT_MAP: 'L', '.', false, false, unlit, false INIT_MAP: '.', ' ', true, true, random, true
MESSAGE
MESSAGE:"string"
You can have 0 or more of these per special level. "string" is any message you want player to see when entering the level.
Example:
MESSAGE: "Well done, mortal!"
NOMAP
NOMAP
Instead of GEOMETRY and MAP, you use this if you think that INIT_MAP creates a good enough random map and you don't want to use any fixed map-parts.
See also MAP
GEOMETRY
GEOMETRY:xadj,yadj
This must be followed by a MAP definition, and tells the approximate position of the following MAP-part on the level.
- xadj is one of left, half-left, center, half-right, right or random
- yadj is one of top, center, bottom or random
Example:
GEOMETRY:left,top
MAP
MAP ... ... ... ENDMAP
This must be preceded by GEOMETRY definition. You define a map-part by "drawing" with map characters between the MAP and ENDMAP. The map can be up to 21 lines high and and each line can be up to 76 chars long. Each line must also be the same length.
See also NOMAP.
NON_DIGGABLE
NON_DIGGABLE:region
Sets the walls inside the region as non-diggable.
Example:
NON_DIGGABLE:(00,00,13,12)
NON_PASSWALL
NON_PASSWALL:region
Players and monsters cannot phase through the walls inside the region
Example:
NON_PASSWALL:(00,00,13,12)
RANDOM_PLACES
RANDOM_PLACES:place,...
With this command you can set up to 10 coordinate registers, which you can access by using place[N] instead of a coordinate in any other command. The registers are shuffled at level creation time.
Example:
RANDOM_PLACES:(23,9),(37,14),(51,9) OBJECT:'?',"genocide",place[0]
RANDOM_MONSTERS
RANDOM_MONSTERS:'X',...
With this command you can set up 10 monster symbol registers, which you can access by using monster[N] instead of a monster symbol in any other command. The registers are shuffled at level creation time.
Example:
RANDOM_MONSTERS: 'E', 'X' MONSTER:monster[0],random,(27,05)
RANDOM_OBJECTS
RANDOM_OBJECTS:'X',...
With this command you can set up 10 object class symbol registers, which you can access by using object[N] instead of a object class symbol in any other command. The registers are shuffled at level creation time.
Example:
RANDOM_OBJECTS:'[',')','*','%' OBJECT:object[0],random,(39,05)
DOOR
DOOR:state,place
Puts a door on the map.
- state is one of the following: nodoor, locked, closed, open or random
- place is either a coordinate, a RANDOM_PLACES place, or random
Example:
DOOR:locked,(10,5)
DRAWBRIDGE
DRAWBRIDGE:place,dir,state
- place is either a coordinate, a RANDOM_PLACES place, or random
- dir is one of the following: north, east, south or west
- state is one of the following: nodoor, locked, closed, open or random
Note that the drawbridge placement is different from door placement; the coordinate must be a place where the drawbridge would be when it's open, and from that place towards the direction there should be a wall, where the portcullis will be.
Example:
DRAWBRIDGE:(25,18), north, closed
REGION
REGION:(x1,y1,x2,y2), lighted, "type"
Define a region on the map with certain light-state and type.
- lighted is either lit or unlit.
- "type" is one of the room types.
You can add filled or unfilled, it will denote whether the room will get stocked with the normal monster or objects it would get. After that you can add true or false to denote whether the room is irregularly shaped. If the room is irregular, only the first coordinate (x1,y1) must be inside the room, and the room must be closed off from other areas with non-floor map characters. Use the boundary symbol 'B' in the MAP to enclose an irregular room; it will be converted to floor symbol '.' after the level has been created.
Examples:
REGION:(43,12,49,16),unlit,"ordinary" REGION:(12,01,20,09),unlit,"morgue",unfilled REGION:(11,03,29,10),lit,"temple",filled,true
STAIR-region
STAIR:(x1,y1,x2,y2), (x3,y3,x4,y4), updown
Places a stair within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4).
- updown is either up or down, denoting the direction of the stairs.
If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP.
Example:
STAIR:(0,0,79,20), (20,5,50,15), up STAIR:levregion(01,0,79,20), (0,0,28,12), up STAIR:(0,0,50,10), levregion(10,0,20,15), down
PORTAL
PORTAL:(x1,y1,x2,y2), (x3,y3,x4,y4),"levelname"
Places a magical portal within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). The portal will level teleport player to the level with the name "levelname". If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP.
Example:
PORTAL:levregion(57,01,78,19),(0,0,0,0),"fire" PORTAL:(0,0,75,19),(65,13,75,19),"air"
TELEPORT_REGION
TELEPORT_REGION:(x1,y1,x2,y2),(x3,y3,x4,y4)
Restricts the area where player can end up on the level when he level teleports or falls in there. Player will end up within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP. You can also add an optional direction parameter, either up or down, which will tell when this rule is applied; when player is coming from below or above.
Example:
TELEPORT_REGION:(69,16,69,16),(0,0,0,0) TELEPORT_REGION:levregion(56,00,79,20),levregion(01,00,55,20),down
BRANCH
BRANCH:(x1,y1,x2,y2),(x3,y3,x4,y4)
Places stairs or a magical portal to a dungeon branch within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP.
Example:
BRANCH:levregion(51,2,77,18),(0,0,40,20)
MAZEWALK
MAZEWALK:place,dir
Creates a random maze, starting from place.
- place is either a coordinate, a RANDOM_PLACES place, or random
- dir is one of the following: north, east, south or west
Example:
MAZEWALK:(00,06),west
WALLIFY
WALLIFY
Turns walls completely surrounded by other walls into solid stone ' '.
LADDER
LADDER:place, updown
Places a ladder up or down at coordinate. See also STAIRS.
- place is either a coordinate, a RANDOM_PLACES place, or random
- updown is either up or down, denoting the direction of the stairs.
Example:
LADDER:(11,05),down
GOLD
GOLD:place, amount
Places amount of gold in place.
- place is either a coordinate, a RANDOM_PLACES place, or random
- amount is any positive integer number.
Example:
GOLD:(5,5),12345
ROOM-type levels
Room-type levels begin with LEVEL, followed by optional FLAGS, optional INIT_MAP, 0 or more MESSAGEs, followed by optional random register initializers (RANDOM_MONSTERS and RANDOM_OBJECT), followed by 0 or more ROOM and SUBROOM definitions (and the contents for those rooms), followed by RANDOM_CORRIDORS.
It's not possible to define arbitrarily shaped rooms with this type of level.
LEVEL
LEVEL: "name"
"name" is the unique file name for this level. Can be up to 8 chars long.
Example:
LEVEL: "oracle"
RANDOM_CORRIDORS
RANDOM_CORRIDORS
Creates random corridors between the rooms in the level, so that all rooms are accessible.
ROOM
ROOM: "type", lighted, pos, align, size
Creates a room. The room will be placed on a position defined both by pos and align. pos defines the rough position (in a 5-by-5 grid on the screen), and align defines the room position within that.
- "type" is one of the room types.
- lighted is one of lit, unlit or random.
- pos is either random or (xpos, ypos), where both xpos and ypos are between 0 and 5. This is an approximate coordinate on the screen.
- align is either random or (xalign, yalign) and is the room alignment within the pos.
- xalign is one of left, half-left, center, half-right, right or random
- yalign is one of top, center, bottom or random.
- size is either random or (width, height).
You can also give one additional parameter, which can either be true or false. This tells whether the room will get stocked by objects and monsters it would normally get (such as shopkeepers and items for sale for shops).
Example:
ROOM: "ordinary", random, random, random, random ROOM: "ordinary", lit, (3,3), (center,center), (11,9)
SUBROOM
SUBROOM: "type", lighted, pos, size, "parent"
Creates a room inside previously defined ROOM.
- "type" is one of the room types.
- lighted is one of lit, unlit or random.
- pos is either random or (xpos, ypos), where xpos and ypos define the absolute position of this subroom inside the parent room. (0,0) is the upper left corner of the parent.
- size is either random or (width, height).
- "parent" is the name of the parent room, as defined with NAME.
You can also give one additional parameter, which can either be true or false. This tells whether the room will get stocked by objects and monsters it would normally get (such as shopkeepers and items for sale for shops).
Example:
SUBROOM:"shop",lit,(10,10),(3,3),"town" SUBROOM:"ordinary",random,(19,2),(2,2),"town"
NAME
NAME: "string"
Names the previously defined ROOM or SUBROOM. Subrooms need to know the name of their parent room, this has no other meaning.
Example:
NAME: "town"
CHANCE
CHANCE: int
Assigns a creation chance to the previously defined ROOM or SUBROOM. The room walls and doors will get created no matter what, this just tells whether the room contents will be created. int should be in the 0-100 range. Only non-ordinary rooms can have this.
Example:
CHANCE: 90
Room DOOR
DOOR: secret, state, wall, pos
Creates a door with certain state on the previously defined ROOM or SUBROOM. Note that Room DOOR format is different from MAZE-level DOOR.
- secret can be true, false or random
- state is one of the following: nodoor, locked, closed, open or random
- wall is one of the following: north, east, south or west and tells on what wall of the room the door will be created.
- pos is either random or a positive integer, and tells how far from top or left the door will be.
Example:
DOOR: false, closed, south, random
Common syntax
The following commands are common to both MAZE and ROOM-type levels. For the MAZE-levels, the coordinates used are the previously defined MAP, for ROOM-levels, it's either the previously defined ROOM or SUBROOM.
ALTAR
ALTAR:place,align,type
Places an altar on the previously defined map or ROOM or SUBROOM.
- place is either a coordinate, a RANDOM_PLACES place, or random
- align is either noalign, law, neutral, chaos, coaligned, noncoaligned, random or an alignment register align[N], where N can be either 0,1 or 2.
- type is one of sanctum, shrine, altar or randomq
Example:
ALTAR:(50,14),chaos,altar ALTAR:place[0],noalign,altar ALTAR:(07,09),align[0],sanctum
CONTAINER
This defines a container that you can put items in. It accepts exactly the same parameters as OBJECT. Normal content generation for this object is suppressed.
Example:
CONTAINER:'(',"chest",(5,5) OBJECT:'/',"wishing",contained
ENGRAVING
ENGRAVING:place, type, "text"
Creates an engraving on the floor.
- place is either a coordinate, a RANDOM_PLACES place, or random
- type is one of dust, engrave, burn, mark or random.
- "text" is the text to engrave on the floor.
Example:
ENGRAVING:(12,03), engrave, "You are now entering the Gnome King's wine cellar."
FOUNTAIN
FOUNTAIN:place
Places a fountain on the map.
- place is either a coordinate, a RANDOM_PLACES place, or random
Example:
FOUNTAIN:(10,08)
MONSTER
MONSTER:'X',"monst",place
- 'X' is the monster class symbol, or random, or a RANDOM_MONSTERS index
- "monst" is the specific monster, or random
- place is either a coordinate, a RANDOM_PLACES place, or random
Other things you can add to the monster definition:
- hostile or peaceful
- asleep or awake
- For mimics and other shapechangers you can also add the following:
- m_feature "dungeon_feature" to force the mimic to be a dungeon feature.
- m_object "object_name" to force the mimic to be an object. object_name is the name of an object as they are in objects.c
- m_monster "monster_name" to force the shapechanger to be a certain monster.
- "Name" to name the monster.
Optionally, you can put [NN%] right after MONSTER to make the monster generation optional. NN is a percentage chance of the monster being generated when the level is created.
Examples:
MONSTER:'v',"dust vortex",(42,05) MONSTER:'E',"earth elemental",(39,06),peaceful MONSTER:'&',"Pestilence",place[0],hostile MONSTER:random,random,random MONSTER:random,random,(01,01), asleep MONSTER:monster[0],random,(27,05) MONSTER:'m',"giant mimic",place[1],m_feature "fountain" MONSTER:'m',random,place[0], m_object "luckstone" MONSTER:'@',"rogue",(35,06),peaceful,"Pug" MONSTER[50%]:'P', "green slime", random
OBJECT
OBJECT:'X',"name",place
Each map-part can contain any number of object definitions.
- 'X': a character denoting one of the object classes.
- "name": either an object name as listed in objects.c, or random
- place: either a coordinate, a RANDOM_PLACES place, or random, or contained. If contained, then this object will be placed in the previously defined CONTAINER.
Optional stuff you can add to the object definition:
- cursestate, "monster_id", spe
- cursestate, spe
- "monster_id", spe
Where
- cursestate is one of blessed, uncursed, cursed or random.
- "monster_id" is a monster type, as defined in monst.c
- spe is an integer, and defines different things depending on what kind of object is generated:
- enchantment for armor and weapons
- charges for wands, rings, magic markers and everything else that has charges.
- historic for statues. 1 is historic, 0 is normal.
- tins: 1 means spinach, -1 is home-made.
- containers: 1 means the box contains Shroedinger's cat.
- oil lamps and candles: 0 means the lamp is out of oil.
- Candelabrum: how many candles are attached to it.
- scroll of mail: 1 means it was not delivered to current player.
- eggs: 1 means hero laid it.
- chests: 2 means it's a royal coffer in a throne room.
After these you can also add a quoted string, which would become the object's name.
Optionally, you can put [NN%] right after OBJECT to make the object generation optional. NN is a percentage chance of the object being generated when the level is created.
Examples:
OBJECT:'%', "food ration", random OBJECT:'*', random, (10,10) OBJECT:'?', "genocide", place[0] OBJECT[10%]:'"', "amulet of life saving", random OBJECT:'%', "corpse", random, "archeologist", 0 OBJECT[50%]:')', "scimitar", contained, blessed, +2 OBJECT:'`', "statue", (0,0), "forest centaur", 1 OBJECT:'(', "crystal ball", (17,08), blessed, 5, "The Orb of Fate"
STAIR
STAIR:place, updown
Places a stair up or down at coordinate. See also STAIR-region and LADDER.
- place is either a coordinate, a RANDOM_PLACES place, or random
- updown is either up or down, denoting the direction of the stairs.
Example:
STAIR:(70,08), up STAIR:random, down STAIR:place[3], up
TRAP
TRAP:"name",place
- "name" is the trap's name, or random
- place is either a coordinate, a RANDOM_PLACES place, or random
Optionally, you can put [NN%] right after TRAP to make the trap generation optional. NN is a percentage chance of the trap being generated when the level is created.
Examples:
TRAP:"hole",(12,10) TRAP:"anti magic",random TRAP:random,random TRAP[25%]:"polymorph",random
Map characters
character | dungeon feature |
---|---|
' ' | solid wall |
'#' | corridor |
'.' | room floor |
'-' | horizontal wall |
'|' | vertical wall |
'+' | door |
'A' | air |
'B' | crosswall / boundary symbol hack (See REGION) |
'C' | cloud |
'S' | secret door |
'H' | secret corridor |
'{' | fountain |
'\' | throne |
'K' | sink |
'}' | moat |
'P' | pool of water |
'L' | lava pool |
'I' | ice |
'W' | water |
'T' | tree |
'F' | iron bars |
Trap names
"anti magic", "arrow", "bear", "board", "dart", "falling rock", "fire", "hole", "land mine", "level teleport", "magic portal", "magic", "pit", "polymorph", "rolling boulder", "rust", "sleep gas", "spiked pit", "statue", "teleport", "trap door", "web"
Room types
"ordinary", "throne", "swamp", "vault", "beehive", "morgue", "barracks", "zoo", "delphi", "temple", "anthole", "cocknest", "leprehall", "shop", "armor shop", "scroll shop", "potion shop", "weapon shop", "food shop", "ring shop", "wand shop", "tool shop", "book shop", "candle shop"