diff options
-rw-r--r-- | crawl-ref/docs/level_design.txt | 310 | ||||
-rw-r--r-- | crawl-ref/source/dat/crypt.des | 6 | ||||
-rw-r--r-- | crawl-ref/source/dat/hells.des | 2 | ||||
-rw-r--r-- | crawl-ref/source/dat/lair.des | 9 | ||||
-rw-r--r-- | crawl-ref/source/dat/mini.des | 2 | ||||
-rw-r--r-- | crawl-ref/source/dat/temple.des | 2 |
6 files changed, 180 insertions, 151 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt index 29e3e85a7d..486b7b88df 100644 --- a/crawl-ref/docs/level_design.txt +++ b/crawl-ref/docs/level_design.txt @@ -1,5 +1,6 @@ +----------------------------------------------- How to make levels for Dungeon Crawl Stone Soup -=============================================== +----------------------------------------------- Contents: A. Introduction B. Sample map @@ -14,7 +15,7 @@ Contents: A. Introduction K. Portal vaults A. Introduction ------------------ +================= All fixed level information resides in various .des files to be found in the dat directory. If you are interested in adding some vaults, say, start with @@ -41,7 +42,7 @@ use: portal.des - portal vaults entrances temple.des - Ecumenical Temples, and Temple entrances vaults.des - entrances for the Vaults, and Vaults:8 - zot.des - Zot:5 + zot.des - vaults for the Zor branch and the maps for Zot:5 Kinds of Vaults @@ -53,38 +54,29 @@ rooms+corridors. The only exceptions to this are branch entry vaults and minivaults - these are placed after the level is generated, and therefore do not influence level generation. -* Entry vault: - -A map designed for D:1, which (usually) contains the primary upstair { and is -always tagged "entry". A player starting a new game will usually land in an -entry vault. - - -* Branch entry vault, or branch portal vault: - -A map containing the entry to a branch - either a branch stair (such as the -stair to the Orcish Mines), or a branch portal (a portal to Hell, say). Always -tagged "<branchname>_entry". +Entry vault: + A map designed for D:1, which (usually) contains the primary upstair { +and is always tagged "entry". A player starting a new game will usually land +in an entry vault. +Branch entry vault, or branch portal vault: + A map containing the entry to a branch - either a branch stair (such as +the stair to the Orcish Mines), or a branch portal (a portal to Hell, say). +Always tagged "<branchname>_entry". -* Special level: - -A map for a location of significance in the game, such as the Ecumenical +Special level: + A map for a location of significance in the game, such as the Ecumenical Temple, or the end of branches such as level 5 of the Snake Pit (Snake:5). Special level maps usually have a PLACE: attribute. - -* Random vaults: - -Random vaults may be randomly generated at any level in the dungeon. Random -vault maps are selected by the dungeon builder based on their DEPTH: +Random vaults: + Random vaults may be randomly generated at any level in the dungeon. +Random vault maps are selected by the dungeon builder based on their DEPTH: attributes. - -* Random minivaults: - -Random minivaults are small maps that are placed onto a level that the -dungeon builder has already constructed fully otherwise (the level may +Random minivaults: + Random minivaults are small maps that are placed onto a level that the +dungeon builder has already constructed fully otherwise (the level may include other vaults). Minivaults are distinguished from normal vaults solely by the absence of an @@ -92,67 +84,39 @@ ORIENT: declaration. Any map without a specified ORIENT: is a minivault. B. Sample Map ---------------- +=============== Before going into the technical details of the level-file syntax, let's look at an example - a branch entry for the Ecumenical Temple - to see what a map definition looks like. # name below: -NAME: a_useless_temple_entry_02 -# header section below: -ORIENT: float -CHANCE: 5 -TAGS: temple_entry -FLAGS: no_rotate -SHUFFLE: de -SUBST: 1=12. -MONS: butterfly, plant -ITEM: stone, w:10 any book / w:90 nothing -# actual map below: -MAP -xx1@2xx -x1wWw2x -ewwOwwd -x2www1x -xx1.1xx -ENDMAP +NAME: useless_temple_entry +# header section below: +ORIENT: float # "ORIENT: float" tells the level builder that + # this entry can be anywhere on the level. +TAGS: temple_entry # "TAGS: temple_entry" turns the 'O' on the +MONS: butterfly, plant # map into stairs to the Temple. +ITEM: stone +# actual map below: # The symbols on the map: +MAP # x - rock wall +xx.d.xx # . - floor +x..1..x # @ - entry point ( +@d2O2d. # O - stairs to the Temple +x..1..x # 1 - first monster from list (here butterfly) +xx.d.xx # 2 - second monster from list (here plant) +ENDMAP # d - first item from the list (here stones) Every map consists of a name, a header and the actual map (the order is not important as long as the name comes first, but try to stick to this order for consistency). Lines starting with # are comments. The keywords available are explained -briefly after the example map and in detail in the following sections. - -"ORIENT: float" tells the level builder that this entry can be anywhere on the - level; other ORIENT: values can force a map to one edge of the - level. -"CHANCE: 5" makes the map appear less often (default is 10). -"TAGS: temple_entry" turns the 'O' on the map into stairs to the Temple. -"FLAGS: no_rotate" forbids rotation (but mirroring is still allowed). -"SHUFFLE: de" may replace all 'd' with 'e' in the map. -"SUBST: 1=12." may replace each '1' with either '1' or '2' or '.'. -"MONS: butterfly, plant" turns all '1' into butterflies, and '2' into plants. -"ITEM: stone" turns all 'd' into stones. -"ITEM: w:10 any book / w:90 nothing" turns all 'e' into a book - (with 10% chance) or creates no object (with 90% chance). - -The symbols on the map: - x - rock wall - w - water (could be deep or shallow) - W - shallow water - . - plain floor - @ - entry point (this square will be connected to the rest of the map) - O - stairs to the Temple - 1 - first monster from the list (here butterfly) - note the SUBST: 1=12. - 2 - second monster from the list (plant) - d - first item from the list (here stones) - e - second item from the list (here occassionally a book) +in detail in the following sections. C. Map symbols ----------------- +================ Terrain ------- @@ -213,9 +177,9 @@ Features Y - Blood fountain (use sparingly!) Note: Due to the level maker having seen incremental improvements over the -years, there are some inconsistencies. For examples, dangerous statues -(orange, silver, ice) are now genuine monsters. In particular, you might see -many older vaults still using the deprecated 'H' and 'S' glyphs which should +years, there are some inconsistencies. For examples, dangerous statues (ice, +orange, silver) are now genuine monsters. In particular, you might see many +older vaults still using the deprecated 'H' and 'S' glyphs which should otherwise be dispensed with. Similarly, the most of the other feature glyphs can be replaced with KFEAT: @@ -245,11 +209,17 @@ Monsters D. Header information ------------------------ +======================= (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. + NAME: a_string Each map must have a unique name. Underscores and digits are ok. @@ -337,7 +307,7 @@ CHANCE: (number with 10 being default) PLACE: Used to specify certain special levels. Existing special levels are: Temple, Hell, Dis:7, Geh:7, Coc:7, Tar:7, Hive:4, Vault:8, Snake:5, - Elf:7, Slime:6, Blade, Zot:5, Tomb:1, Tomb:2, Tomb:3, Swamp:5. + Elf:7, Slime:6, Blade, Zot:5, Tomb:1, Tomb:2, Tomb:3, Swamp:5, Crypt:4 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 @@ -348,7 +318,8 @@ PLACE: Used to specify certain special levels. Existing special levels are: PLACE can be used with random vaults and minivaults for testing them. -TAGS: Tags go an a TAGS: line and are space-separated. Valid tags are: +TAGS: Tags go an 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. @@ -405,9 +376,6 @@ TAGS: Tags go an a TAGS: line and are space-separated. Valid tags are: open, caves, cross, shoals, swamp, labyrinth (though currently random vaults aren't placed in the last three). - Pre-0.3 Crawl distinguished between TAGS and FLAGS. 0.3 and - newer Crawls treat TAGS and FLAGS as synonyms. - LFLAGS: Persistent, changeable per-level flags which affect game behaviour (FLAGS just controls how the vault is placed); should only be used for vaults with ORIENT encompass or with PLACE. Causes a level's @@ -415,10 +383,11 @@ LFLAGS: Persistent, changeable per-level flags which affect game behaviour later be altered using Lua markers; for examples, look at the slime pit vault in lair.des, and the vaults in hell.des and elf.des. - Valid flags are: no_tele_control, which prevents the player from - using teleport control; not_mappable, which prevents the player - from remembering where they've been (like in the Abyss), and - no_magic_map, which prevents magic mapping from working. + 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. BFLAGS: Persistent, changeable per-*branch* flags which affect game behaviour; should only be used for vaults which go on the first @@ -426,11 +395,12 @@ BFLAGS: Persistent, changeable per-*branch* flags which affect game using Lua markers; see the Tomb vaults in vaults.lua for an example. - Valid flags are: no_tele_control, which prevents the player from - using teleport control; not_mappable, which prevents the player - from remembering where they've been (like in the Abyss), and - no_magic_map, which prevents magic mapping from working. - + 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. + FLOORCOL: blue FLOORCOL: allows you to set the floor colour for the level the vault appears in. Should only be used for bazaars and other @@ -565,7 +535,7 @@ COLOUR: . = green / blue:5 / red / none COLOUR: should be used very sparingly, and only for features where it won't cause confusion (i.e.: never re-colour features - like lava!) + like lava or traps unless you really know what you do!) SHUFFLE: def, 12/3? This allows you to randomly permute glyphs on the map. There are @@ -682,7 +652,6 @@ KMONS: ? = orc priest / w:3 deep elf priest 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 @@ -822,7 +791,7 @@ Crawl will see "potion ofhealing", not "potion of healing". E. Conditionalising levels ------------------------------ +============================= Crawl translates level (.des) files into Lua code chunks and runs these chunks to produce the final level that is generated. While you don't need to use Lua @@ -962,7 +931,7 @@ reference section. F. Validating levels ------------------------ +======================= If you have a map with lots of transforms (SUBST and SHUFFLE), and want to guarantee that the map is sane after the transforms, you can @@ -1020,17 +989,10 @@ validate {{ G. Hints for level makers ----------------------------- +============================ * Technical stuff: - If your map is not a minivault or a floating vault, make sure the - side(s) forming the border have a rock wall padding at least 6 deep. For - instance, if your map is ORIENT: north, you must have a 6 deep border of - rock wall (or any other kind of wall) along the northern, eastern, and - western edges of the map. If you're doing a fullscreen map (encompass), - you must pad all around the map with 6 layers of wall. - You do not have to place all of the stairs unless the level is full screen, in which case you must place all except the extra stairs (> and <). The <> stairs can be put anywhere and in any quantities but do not @@ -1065,23 +1027,19 @@ G. Hints for level makers feature in mind, please add comments stating this - else somebody may just add @'s later on. :) - Non-rectangular maps will be padded (to the right) with rock walls - (or with floor spaces for minivaults) for the smallest rectangle - containing them. Unfortunately. - Entry levels should be rather small. Their intention is to provide some atmosphere for the starting room, not to get a grip on the whole of D:1. Minivaults should be rather small, as well, in order to increase the chances they may actually be chosen during level generation. * Randomise! - The level making syntax is now very supportive for making a single map - appear in many versions. Use the SHUFFLE: and SUBST: directives and look - at the existing entry vaults. Besides reducing tedium, this avoids giving - veterans a spoiled edge. For example, if a secret chamber with loot is - always at the same place, it's a no-brainer for those who know. The same - goes for traps. This is much less so if there are several places for the - chamber (or trap) and there's even a chance it doesn't exist. + The level making syntax is very supportive for making a single map appear + in many versions. Use the SHUFFLE: and SUBST: and NSUBST: directives and + look at the existing entry vaults. Besides reducing tedium, this avoids + giving veterans a spoiled edge. As an example, if a secret chamber with + loot is always at the same place, it's a no-brainer for those who know. + The same goes for traps. This is much less so if there are several places + for the chamber (or trap) and there's even a chance it doesn't exist. You can also use CHANCE to create modified versions of the same map. In order to do this, make several maps and endow each with a chance such @@ -1100,16 +1058,16 @@ G. Hints for level makers rich in treasure (Tomb:3, Cocytus etc.) to get a feeling for this. * Have a theme. - It is often worthwhile (to me at least) to have a theme in mind before - making the actual level. For entry vaults, something simple like - 'fortress' or 'forest' may be enough. For later (or larger) maps, try - to think of distinguishing features your map may have. Being cool can - be good enough, but possessing some gameplay value (for example by being - easier for particular skills/capabilities like ranged attacks or - necromancy or Traps & Doors) is even better. + It is often worthwhile (for me at least) to have a theme in mind before + making the actual level. For entry vaults, something simple like 'forest' + or 'fortress' may be enough. For later (or larger) maps, try to think of + distinguishing features your map may have. Being cool can be good enough, + but possessing some gameplay value (for example by being easier for + particular skills/capabilities like ranged attacks or Traps & Doors or + necromancy) is even better. * Testing your maps. - This is easy for entry vaults. Temporarily introducing a CHANCE: 5000 + This is easy for entry vaults. Temporarily introducing a CHANCE: 50000 will make your entry appear almost always. For other vaults, you can for the moment declare them as entry vaults with a huge CHANCE: as above (and preferably in wizard mode). For more intricate things like @@ -1120,11 +1078,10 @@ G. Hints for level makers which makes it very likely that the minivault will appear in the chosen level. - Larger vaults can be conjured up in wizard mode using the &L command. - You don't need to specify the full name of the vault, a substring which - uniquely determines the vault is enough. You can playtest portal vaults - using the &P wizard command. Branch ends can be conveniently tested with - the &~ command. + Vaults can be conjured up in wizard mode using the &L command. You don't + need to specify the full name of the vault, a substring which uniquely + determines the vault is enough. You can playtest portal vaults using the &P + wizard command. Branch ends can be conveniently tested with the &~ command. If the .des file syntax is incorrect, Crawl will tell you on which line of which des file it found the syntax error, making for easier debugging. @@ -1167,7 +1124,7 @@ G. Hints for level makers H. Lua reference -------------------- +=================== How maps are processed ---------------------- @@ -1306,7 +1263,6 @@ num_matching_markers, feature_desc, feature_desc_at, item_from_index, mons_from_index, change_level_flags, change_branch_flags - Lua API - global game state --------------------------- @@ -1332,7 +1288,7 @@ stop_activity, floor_items, where, branch, subdepth, absdepth I. Feature Names ------------------- +================== These are the feature names usable in MARKER declarations: @@ -1367,7 +1323,7 @@ dry_fountain_sparkling, dry_fountain_blood, permadry_fountain J. Map Statistics -------------------- +=================== Full-debug Crawl builds (this does not include normal Crawl builds that have wizard-mode) can produce map generation statistics. To @@ -1389,13 +1345,37 @@ crawl -mapstat 1 K. Portal Vaults ------------------- - -Portal vaults are vaults accessed by portals in the dungeon (bazaars -are a special case of portal vaults). You can create custom portal -vaults as follows: - -Define a vault to hold the portal itself: +================== + +Portal vaults are vaults accessed by portals in the dungeon (labyrinths +and bazaars are special cases of portal vaults). You can create custom +portal vaults in the following steps (no compilation is necessary): + +* Create a new file name.des in the dat/ folder. Rules: + The "name" should be descriptive of the vault you're adding. + The "name" should not exceed eight letters. + The ending must be "des". +* Add "name.des" to the list of local files in dat/clua/loadmaps.lua. +* "name.des" should contain a comment at the top, explaining flavour and + gameplay goals of the portal vault (and perhaps additional ideas etc.) +* Define at least one vault containing the portal (see below). +* Define at least one destination map (see below). +* Add a short in-game description for the string "desc" (see below) to + dat/descript/features.txt. + +Before going into the details of portal vault creation, some words about +their uses: Portal vaults are different from branches in that they are +not guaranteed. Furthermore, there is only one go at a portal vault - if +you leave, it's gone for good. Finally, you can apply special rules to a +portal vault, like disabling mapping. Bazaars and labyrinths are typical +examples. + +In order to test a portal vault, you can either use PLACE: D:2 for an +entry vault, or use the wizard mode command &L for conjuring up the entry. + + +Define a vault to hold the portal itself +---------------------------------------- # Bare-bones portal vault entry NAME: portal_generic_entry @@ -1417,6 +1397,10 @@ This will produce a portal, but attempting to use it will trigger an ASSERT since there's no map for the destination. So we create a destination map like so: + +Define a destination map +------------------------ + NAME: portal_generic_generic # Tag must match dst value of portal in entry. TAGS: generic_portal allow_dup @@ -1439,3 +1423,51 @@ Stairs will not work right in portal vaults, do not use them. You can use multiple maps with the destination tag (generic_portal), and the dungeon builder will pick one at random. + + +The MARKER parameters +--------------------- + +The lines + MARKER: O = lua:one_way_stair { desc = "A portal to places unknown", \ + dst = "generic_portal" } + KFEAT: O = enter_portal_vault +ensure that an 'O' glyph will be turned into a portal. Upon leaving the portal +vault, you will be placed on its entry which has been turned into a floor. You +can turn it into something different (usually an empty stone arch), by adding + floor = 'stone_arch' +to the lua:one_way_stair parameters. + +Note that the desc string is what you will see upon examining the portal. +The dst string is used for Crawl's right hand stat area; it will show + Place: generic portal +in the above example. The dst string is also used to link the destination maps +to the entry maps. + +You can replace lua:one_way_stair by lua:timed_marker in order to make timed +portal vaults (which will disappear after some time). bazaar.des and lab.des +contain examples. + + +Using lua functions as shortcuts +-------------------------------- + +If you are making several entry and destination vaults, you will note a +lot of duplicated header statements. This can be lessened using lua. +Define a lua block right at the top (after your comments) as follows: + +{{ + +function generic_portal(e) + e.marker([[O = lua:one_way_stair { desc = "A portal to places unknown", \ + dst = "generic_portal", \ + floor = "stone_arch" }]]) + e.kfeat("O = enter_portal_vault") + e.colour("O = magenta") +end + +}} + +Instead of the MARKER and KFEAT lines introduced above you now just use + :generic_portal(_G) +and the resulting portal glyphs will even be magenta!
\ No newline at end of file diff --git a/crawl-ref/source/dat/crypt.des b/crawl-ref/source/dat/crypt.des index 1aa39095c0..43fc2565b6 100644 --- a/crawl-ref/source/dat/crypt.des +++ b/crawl-ref/source/dat/crypt.des @@ -211,8 +211,7 @@ ENDMAP ########################################################### # she sells tomb entry shells by the sea shore NAME: tomb_entry_shell_bobbens -TAGS: tomb_entry no_monster_gen no_item_gen -FLAGS: no_rotate +TAGS: tomb_entry no_monster_gen no_item_gen no_rotate MONS: guardian mummy MONS: mummy priest MAP @@ -356,8 +355,7 @@ ENDMAP # NAME: cryptofortress_bobbens ORIENT: encompass -TAGS: no_monster_gen no_item_gen no_pool_fixup -FLAGS: no_rotate no_vmirror +TAGS: no_monster_gen no_item_gen no_pool_fixup no_rotate no_vmirror PLACE: Crypt:5 KFEAT: A = w KMONS: A = flying skull diff --git a/crawl-ref/source/dat/hells.des b/crawl-ref/source/dat/hells.des index b0bbb2ab3a..d1e7f77e83 100644 --- a/crawl-ref/source/dat/hells.des +++ b/crawl-ref/source/dat/hells.des @@ -199,7 +199,7 @@ ENDMAP NAME: Lemuel_Dis_Dragons DEPTH: Dis:2-6 ORIENT: float -FLAGS: no_rotate +TAGS: no_rotate MONS: iron dragon, iron dragon SHUFFLE: ]}) SUBST: 1=1. , }=}}> , )=))> , ]=]]> diff --git a/crawl-ref/source/dat/lair.des b/crawl-ref/source/dat/lair.des index 866f55fa65..5d103a529e 100644 --- a/crawl-ref/source/dat/lair.des +++ b/crawl-ref/source/dat/lair.des @@ -892,7 +892,7 @@ ENDMAP # NAME: snake_hunt PLACE: Snake:5 -FLAGS: no_rotate +TAGS: no_rotate ORIENT: northwest KFEAT: Z = weight:2 teleport trap / . KFEAT: z = teleport trap / Zot trap / weight:20 . @@ -960,7 +960,7 @@ ENDMAP NAME: snake_pit PLACE: Snake:5 ORIENT: southwest -FLAGS: no_rotate +TAGS: no_rotate MONS: greater naga / nothing MONS: naga MONS: naga mage / nothing @@ -1012,7 +1012,7 @@ ENDMAP NAME: swamp PLACE: Swamp:5 ORIENT: southeast -FLAGS: no_rotate +TAGS: no_rotate MONS: swamp dragon / nothing MONS: swamp drake / nothing MONS: hydra / nothing @@ -1061,8 +1061,7 @@ ENDMAP # NAME: swamp_alternative PLACE: Swamp:5 -TAGS: no_pool_fixup -FLAGS: no_rotate +TAGS: no_pool_fixup no_rotate ORIENT: float MONS: swamp dragon, swamp drake, hydra, firedrake ITEM: nothing diff --git a/crawl-ref/source/dat/mini.des b/crawl-ref/source/dat/mini.des index f66d83818e..e03d932937 100644 --- a/crawl-ref/source/dat/mini.des +++ b/crawl-ref/source/dat/mini.des @@ -458,7 +458,7 @@ ENDMAP # NAME: anthell DEPTH: D:12-19, Lair:2-, Hive -FLAGS: no_rotate +TAGS: no_rotate MONS: queen ant, soldier ant, giant ant, soldier ant / w:20 giant ant SUBST: ? = . x MAP diff --git a/crawl-ref/source/dat/temple.des b/crawl-ref/source/dat/temple.des index 604bfc77d3..b24ec5af41 100644 --- a/crawl-ref/source/dat/temple.des +++ b/crawl-ref/source/dat/temple.des @@ -472,7 +472,7 @@ ENDMAP # Zaba's temple NAME: zaba_temple_1 PLACE: Temple -FLAGS: no_rotate +TAGS: no_rotate ORIENT: encompass COLOUR: c = magenta SHUFFLE: {[ |