Dungeon profile (dungeon_profile.txt)
The dungeon is divided into non-overlapping square blocks of block_size by block_size grids. When rooms are placed, each is assigned a rectangular chunk of blocks, and those assignments won’t leave a block assigned to more than one room. So…
block_size affects how densely the rooms can be packed and the maximum number of rooms possible;
rooms is the number of rooms to aim for;
unusual is a measure of how likely high rarity roooms are to appear – higher values make the rare rooms rarer;
rarity is the maximum rarity room allowed with this cave profile.
These are percentage chances:
rnd of choosing a random tunnel direction (as opposed to heading in the desired direction);
chg the chance of changing direction, at any tunnel grid;
con the chance of just terminating a tunnel;
pen the chance of putting a door in a room entrance;
jct the chance of a door at a tunnel junction.
Streamers are drawn as a random walk which stops at the dungeon edge.
den is the number of grids near any walk grid to make streamer;
rng is how far from the walk those grids can be;
mag and qua are the numbers of magma and quartz streamers per level;
1/mc and 1/qc are the chances of treasure in magma and quartz.
A number of stairs is randomly placed on a level.
up is the random value used for up staircases;
down is the random value used for down staircases.
min-level is the shallowest dungeon level on which the profile can be used
alloc is used to decide which profile to use. For a profile that has a positive value for alloc, the profile will be used for a level that satisfies the profile’s min-level with a probability of the value of alloc divided by the sum of the alloc values for all other possible profiles at that level. Except for the town profile, if alloc is zero or less than -1, the profile will not be used. If alloc is -1, the profile can only be selected by hard-coded tests in generate.c for the profile selection. If those tests do not already include the profile, using a value of -1 will be the same as using 0 for alloc. The hard-coded tests currently include checks for the
town, moria, and labyrinth profiles.
name is the room name, which must match the name in list-rooms.h so the correct room-building function can be called;
rating is the rating of the room (used only for template rooms);
height is the maximum height of the room, and define how much
space is allocated for that room;
width are the maximum width of the room;
level is the minimum depth at which this room can appear;
pit is 1 if the room is a pit/nest, 0 otherwise;
rarity is the room’s rarity – normally 0, 1 or 2 (see comments about profile rarity above). Some rooms are chosen by a different means; in this case rarity is usually 0.
cutoff is used to pick between rooms once a rarity is chosen: a random value from 0 to 99 is selected and a room may appear if its cutoff is greater than that value.
It is IMPORTANT that non-zero cutoffs appear in ascending order within the rooms of the same rarity for a given profile: a room with a smaller cutoff appearing after one with a larger cutoff will never be selected.
Note that getting a smaller cave profile cutoff or room cutoff after a larger one will result in the smaller one never appearing.
Cave generation (gen-cave.c)
In this file, we use the SQUARE_WALL flags to the info field in cave->squares. Those are usually only applied and tested on granite, but some (SQUARE_WALL_INNER) is applied and tested on permanent walls.
SQUARE_WALL_SOLID indicates the wall should not be tunnelled;
SQUARE_WALL_INNER marks an inward-facing wall of a room; SQUARE_WALL_OUTER marks an outer wall of a room.
We use SQUARE_WALL_SOLID to prevent multiple corridors from piercing a wall in two adjacent locations, which would be messy, and SQUARE_WALL_OUTER to indicate which walls surround rooms, and may thus be pierced by corridors entering or leaving the room.
Note that a tunnel which attempts to leave a room near the edge of the dungeon in a direction toward that edge will cause “silly” wall piercings, but will have no permanently incorrect effects, as long as the tunnel can eventually exit from another side. And note that the wall may not come back into the room by the hole it left through, so it must bend to the left or right and then optionally re-enter the room (at least 2 grids away). This is not a problem since every room that is large enough to block the passage of tunnels is also large enough to allow the tunnel to pierce the room itself several times.
Note that no two corridors may enter a room through adjacent grids, they must either share an entryway or else use entryways at least two grids apart. This prevents large (or “silly”) doorways.
Traditionally, to create rooms in the dungeon, it was divided up into “blocks” of 11×11 grids each, and all rooms were required to occupy a rectangular group of blocks. As long as each room type reserved a sufficient number of blocks, the room building routines would not need to check bounds. Note that in classic generation most of the normal rooms actually only use 23×11 grids, and so reserve 33×11 grids.
Note that a lot of the original motivation for the block system was the fact that there was only one size of map available, 22×66 grids, and the dungeon level was divided up into nine of these in three rows of three. Now that the map can be resized and enlarged, and dungeon levels themselves can be different sizes, much of this original motivation has gone. Blocks can still be used, but different cave profiles can set their own block sizes. The classic generation method still uses the traditional blocks; the main motivation for using blocks now is for the aesthetic effect of placing rooms on a grid.
Room generation (gen-room.c)
This file covers everything to do with generation of individual rooms in the dungeon. It consists of room generating helper functions plus the actual room builders (which are referred to in the room profiles in generate.c).
The room builders all take as arguments the chunk they are being generated in, and the co-ordinates of the room centre in that chunk. Each room builder is also able to find space for itself in the chunk using the find_space() function; the chunk generating functions can ask it to do that by passing too large centre co-ordinates.
This is the top level dungeon generation file, which contains room profiles (for determining what rooms are available and their parameters), cave profiles (for determining the level generation function and parameters for different styles of levels), initialisation functions for template rooms and vaults, and the main level generation function (which calls the level builders from gen-cave.c).
See the “vault.txt” file for more on vault generation. See the “room_template.txt” file for more room templates.