summaryrefslogtreecommitdiffstats
path: root/crawl-ref/docs/level_design.txt
blob: 91df249b33f65e143db4fd528eb48323184db0ce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
-----------------------------------------------
How to make levels for Dungeon Crawl Stone Soup
-----------------------------------------------

Contents:  A. Introduction
           B. Sample map
           C. Map symbols
           D. Header information
           E. Conditionalising levels
           F. Validating levels
           G. Hints for level makers
           H. Portal vaults
           I. Lua reference
           J. Feature names
           K. Map statistics


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
the existing ones and modify them. Currently, the following .des files are in
use:

 altar.des    - minivaults containing altars
 arena.des    - arenas for the arena mode
 bazaar.des   - entrances to bazaar portal vaults, and bazaars proper
 crypt.des    - random vaults for Crypt, the Crypt:5 branch ends, and the
                predefined maps for Tomb:1, Tomb:2 and Tomb:3
 didact.des   - lua and vaults for syntax checking - not used in-game
 dummy.des    - global dummy balancers
 elf.des      - arrival and random vaults for Elf, and Elf:7 branch ends
 entry.des    - entry vaults (each game - but not tutorial games - uses one of
                these premade maps for the vicinity of the entrance)
 float.des    - floating vaults
 hells.des    - hell entrances, Geryon's vestibule, Coc:7, Tar:7, Dis:7, Geh:7
 hive.des     - hive entrances, random hive vaults, Hive:2
 icecave.des  - the ice cave portal vault
 lab.des      - labyrinths exits and flavour vaults
 lair.des     - lair entrances, random vaults for lair proper and sub-branches,
                and the branch ends: Shoals:5, Swamp:5, Snake:5, Slime:6
 large.des    - all regular vaults which have ORIENT:encompass/northwest etc
 layout.des   - level layout code that has been moved from dungeon.cc and
                rewritten in Lua.
 mini.des     - minivaults (no ORIENT line at all)
 minitomb.des - the minitomb portal vault
 orc.des      - orcish mine entrances, orc only vaults
 pan.des      - vaults of the Pan demon lords, Pan minivaults
 rooms.des    - special monster rooms, such as orc, kobold and jelly rooms
 sewer.des    - the sewer portal vault
 temple.des   - Ecumenical Temples, and Temple entrances
 vaults.des   - entrances for the Vaults, Vaults-specific vaults, the
                Hall of Blades, and Vaults:8
 ziggurat.des - the ziggurat entry vaults, pillars and arenas
 zot.des      - vaults for the Zot branch and the maps for Zot:5

Kinds of Vaults
---------------
The different kinds of vaults used by Crawl are described briefly below.

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
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:
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
include other vaults).

Minivaults are distinguished from normal vaults by the absence of an
ORIENT: declaration. Any map without a specified ORIENT: is a
minivault. Minivaults are handled like floating vaults (ORIENT: float
vaults) in most respects. The differences are:

1. Floating vaults may be placed before the rest of the level layout
   is generated, and the rest of the level may be built around the floating
   vault. This is never the case for minivaults.

2. Floating vaults may be placed anywhere in the map, including places
   completely separated from the rest of the level by rock. The
   dungeon builder will then connect the exits from the floating vault
   to the rest of the level, usually producing obvious "passages" from
   the floating vault to the main body of the level.

   In contrast, minivaults are placed such that at least one square of
   the minivault overlaps with an existing part of the level, and are
   thus more likely to look like part of the level. Unlike floating
   vaults, the dungeon builder assumes that any one square of overlap
   is enough to connect the minivault to the rest of the level and
   makes no effort to connect exits from the minivault to the level.
   You can ask the dungeon builder to connect exits from your
   minivault with the "mini_float" tag.



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:    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
in detail in the following sections.


C.   Map symbols
================

Terrain
-------
 x - rock wall                                            (DNGN_ROCK_WALL)
 X - permanent rock wall  - always undiggable        (DNGN_PERMAROCK_WALL)
 c - stone wall - only affected by Shatter               (DNGN_STONE_WALL)
 m - clear rock wall                                (DNGN_CLEAR_ROCK_WALL)
 n - clear stone wall - only affected by Shatter   (DNGN_CLEAR_STONE_WALL)
 o - clear permanent rock wall - always undiggable (DNGN_CLEAR_PERMAROCK_WALL)
 v - metal wall - grounds electricity                    (DNGN_METAL_WALL)
 b - crystal wall - reflects cold and fire       (DNGN_GREEN_CRYSTAL_WALL)
 a - wax wall - can melt                                   (DNGN_WAX_WALL)

 . - floor                                                    (DNGN_FLOOR)
 + - closed door                                        (DNGN_CLOSED_DOOR)
 = - secret door                                        (DNGN_SECRET_DOOR)

 W - shallow water
 w - deep water - can be randomly turned into shallow water by the
     level-builder; you can prevent this conversion with the no_pool_fixup TAG.
     Also, water may automatically receive water creatures! For entry
     vaults, avoid this with the no_monster_gen TAG or KMASK.
 l - lava - again, use the no_monster_gen TAG or KMASK for entry vaults!

Features
--------
 @ - entry point - must be on outside edge. If you use ORIENT: float, and do
     not use any @, the dungeon builder will connect at least one floorspace on
     the edge of your map to the rest of the level; if there is no floorspace
     on the edge of your map, it will be isolated.
 }{ - Stone stairs - You must be able to reach these from each other. The
      { upstair is also the stair on which the player will enter the
      dungeon for entry vaults.
 )( - Stone stairs, set 2.
 ][ - Stone stairs, set 3.

 >< - escape hatches - you can leave the level by these but will usually
      not land on stairs/hatches

 I - orcish idol (does nothing)

 ^ - random trap.
 ~ - random trap suitable for the branch and depth the map is being used.

 A - Vestibule gateway (opened by Horn).
 B - Altar. These are assigned specific types (e.g. of Zin etc) in dungeon.cc,
     in order.
 C - Random Altar.

 F - Usually a Granite Statue, but may be Orange or Silver or Ice (1 in 100)
 G - Granite statue (does nothing) - you can see through but not walk through.
     Also, sight-based effects like smiting work past granite statues, as does
     apportation.

 T - Water fountain
 U - Magic fountain
 V - Permanently dry fountain
 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 (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, most of the other feature glyphs can be replaced with KFEAT:
lines. The same goes for some item glyphs ('R', 'Z') which could be replaced
by KITEM: lines.

Items
-----
 $ - gold
 % - normal item
 * - higher level item (good)
 | - acquirement-level item (almost guaranteed excellent)
 O - place an appropriate rune here. For portal vaults, place the portal here.
 P - maybe place a rune here (50%)
 R - honeycomb (2/3) or royal jelly (1/3)
 Z - the Orb of Zot
 d-k - item array item. See section below on ITEM: arrays for more info.

Monsters
--------
 0 - normal monster
 9 - +5 depth monster
 8 - (+2) * 2 depth monster (aargh!). Can get golden dragons and titans
     this way.
 1-7 - monster array monster. See section below on MONS: arrays for more
     information


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.

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:
              xxxxxxxxxx       xxxxxxxxxxxxx
              xORIENT:Nx       xORIENT:NW|..
              x.VAULT..x       x.VAULT...|..
              x--------x       x---------|..
              xrest....x       xrest........
              x...of...x       x.....of.....
              x...levelx       x.......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.

DEPTH:    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.)

          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.

CHANCE:   <priority>:<roll> or <roll>

          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: 500
          or
          CHANCE: 5%

          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.
          Note that CHANCE accepts only integers, no fractions or
          decimals.

          For any map with alternatives, a CHANCE influences how
          likely the map is to be picked instead of the alternatives.
          If a map 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.

          If there are multiple alternative maps with CHANCE, they
          will be tested in an unspecified order; the first map that
          makes the CHANCE roll will be used. If you'd like to specify
          an order of testing CHANCEs, specify a CHANCE with a
          priority:

             CHANCE: 10 : 20%

          This specifies a CHANCE of 20%, with a priority of 10, which
          means this vault will be checked before any other vault with
          a lower priority (the default priority is 0).

          If no map with a CHANCE is picked, Crawl will select a map
          based on WEIGHT, ignoring vaults with a CHANCE set.

          Note that the Lua equivalent for CHANCE is a two-argument
          function:

          : chance(<priority>, <number>)

          These lines are all equivalent:
          CHANCE: 5%
          CHANCE: 500
          CHANCE: 0 : 5%
          CHANCE: 0 : 500
          : chance(0, 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.

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]

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.

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.
          * "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.
          * "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.
          * "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.
             Use "O" to place the stairs. 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.
          * "layout": Lua code that dungeon.cc uses for generating level
             layouts.  Do *NOT* use or mess with unless you know what
             you're 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).
          * "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.

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
          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 lair.des, and the vaults in hell.des and elf.des.

          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
          level of a particular branch. These flags can later be altered
          using Lua markers; see the Tomb vaults in vaults.lua for an
          example.

          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.

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

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

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.

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

          Modifiers:
          * "q:N" sets the item quantity to N (if N > 0). Does nothing
             if the item is not stackable.
          * "no_uniq" prevents the item from being turned into an artefact.
          * "good_item" makes the builder try to make the item a good one
            (acquirement quality).
          * "level:N" sets the object's item level (can't be used with
            "good_item").  If set to -2 then the object's item level will
            be the same as a "*" symbol item (five plus twice the
            vault's level number).
          * "damaged" sets the item plusses to -1..-4.
          * "cursed" gets a curse plus plusses as in "damaged".
          * "any" by itself gives a random choice; you can combine "any" with
            "good_item."
          * "any book", "any misc" etc. gives a random item of that class.
            Valid item class names are: gold, weapon, missile, armour, wand,
            food, scroll, jewelry, potion, book, staff, orb, misc, carrion.
            All of these are usable in map definitions, apart from "orb" and
            "carrion".
          * "race:race_name", where "race_name" is "elven", "dwarven" or
            "orcish"; it can also be "none" or "no_race" to prevent the item
            from being randomly being made racial.  Has no effect if the item
            can't take that kind of racial setting.
            NOTE: Can result in a non-racial item if used with "any" and the
            chosen item isn't compatible with the desired race.
          * "ego:ego_name", where "ego_name" is something like  "running" or
            "fire_resistance", and so on; "none" can be used to prevent the
            item from getting an ego.  The item must be fully specified, so
            trying "any weapon ego:vorpal" or "any armour ego:positive_energy"
            will result in an error.  Trying to give an ego to something which
            can't accept an ego will also result in an error.
          * "fixed:item_name" will make a given fixedart by a given name,
            like "long sword fixed:singing_sword".  If the unique already
            exists, the base item will be given instead.

            WARNING: While checks are done to make sure that an armour ego
            isn't given to a weapon, a weapon ego to a missile, and so on, and
            also to make sure that egos are only given to amrours, weapons and
            missiles, no other checking is done.  Thus it is possible to create
            a demonic weapon of holy wrath or a helmet of running.

          Limitations: You can't specify specific pluses or number of charges
          or force a randart.  You also can't lay down corpses, skeletons, or
          chunks.

MONS:     (list of monsters)
          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.

          Individual monsters may be prefixed with the "generate_awake"
          (without the quotes). Use this sparingly:
              MONS: generate_awake giant beetle

          Individual monsters may be prefixed with the "patrolling"
          (without the quotes). Use this sparingly:
              MONS: patrolling naga guardian

          Monsters can also be given colours that override their default
          colour. Use this *very* sparingly:
              MONS: col:darkgrey fungus

          Note that 8, 9, 0 also place monsters (see the table).

          If you want to place a random monster suitable for the level
          the map is generated on, you can use
              MONS: random

          If you want to place a random monster suitable for some other
          place, you can use a place: tag in the monster spec:
              MONS: place:Abyss
          or
              MONS: place:Slime:6

          Using place: with MONS implies that you want a random monster.
          You can also request zombies from random monsters suitable
          for some other depth as:
              MONS: place:Elf:7 zombie
          or
              MONS: place:Zot:5 simulacrum
          or
              MONS: place:Vault:8 spectre

          The available modifiers are "zombie", "skeleton",
          "simulacrum" and "spectre".

          If a monster is a member of a band, you can request that it
          be eligible for band members by adding the keyword "band" to
          the name. For instance:
              MONS: orc warlord band

          Specifying "band" doesn't force bands to be placed - it
          requests that the game use the normal chances of creating a
          band. If you use "band", leave some empty space around the
          monster for its band members to be placed.

          A monster can be given specific items by following the monster
          name with a semi-colon and then with an item list as described
          in ITEM:, but with slashes replaced with pipes and commas replaced
          with periods.  For example:
              MONS: orc ; katana | quick blade . chain mail | scale mail

          will generate an orc wielding either a katana or a quick blade
          and wearing either a chain mail or a scale mail.  Randarts are
          never generated, and ego items are only generated if the ego
          is explicitly stated.  Note that any items that the monster was
          originally generated with will be removed and destroyed.  This
          can be used to force a monster to have no items whatsoever:
              MONS: orc; nothing

          Items given to an orc or an elf will be made orcish or elven
          unless the item's race type is explicitly set otherwise.

          Limitations: If an item in the item list has alternatives,
          there's no way to force all monsters dervied from that monster
          spec to choose the same alternative.  If a monster is given
          a random launcher, there is no way to force the ammo type to
          match the launcher type.

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.

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.

RTILE:    x = wall_hive:15 / wall_lair / none
          Identical to FTILE, but for rock walls.  Not useful for anything
          but the rock wall feature.

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: ? = TUV
          replaces occurrences of ? with one of TUV. Since whitespaces are
          irrelevant, this is the same as
          SUBST: ? = T U V

          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.

          SUBST: ? : TUV
          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 SUBST: lines can be used, and mixed with SHUFFLE:, and
          will be applied in order. Multiple substitutions can be performed
          on one line, using commas.

NSUBST:   ? = 3:w / *:l

          NSUBST is similar to SUBST, replacing placeholders with
          replacement values. Unlike SUBST, however, it allows you to
          replace different instances of the same placeholder with
          completely different substitutions. For instance:

          ? = 3:w / *:l

          replaces three occurrences (randomly selected) of ? with w
          and all others 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

          Each specifier is preceded by the number of symbols to apply
          it to, followed by : or = (: to use one substitution for all
          occurrences, = to randomly pick for each occurrence). If you
          omit the initial N: or N=, then 1= is assumed, except for the
          last spec where *= is assumed.

KFEAT:    Z = 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 Z
          with C (random altar), a needle trap, an antique armour shop, or
          an altar of Zin. Different instances of Z may receive different
          replacements. To force a single replacement for all Z,  use:

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

          You'll notice that 'Z' is the symbol of the Orb of Zot. Kxxx
          directives allow you to assign arbitrary definitions to any symbol.

          KFEAT features are specified as a feature name (see section I
          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'.

          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.

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,
            KFEAT: Z = W
            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

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_pool_fixup": prevents a water square next to land from being
             randomly converted from deep water (the default) to shallow.
          * "no_secret_doors": prevents a door from randomly being turned
             into a secret door.

          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.

KITEM:    ? = potion of healing / potion of restore abilities
          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 "gold" or "$" to place gold:
            KITEM: ? = nothing / gold
            KITEM: ? = nothing / $

          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

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/clua/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 section I
          (Feature names) at the end of this document.

          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>
          SHUFFLE: Oa/|c

          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:

          SHUFFLE: Oa/|c
          MARKER: O = lua:<expr>

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:

Wrong:
        ITEM: potion of healing \
              , potion of speed
Right:
        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:

Preferred:
        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\
      healing

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
for most levels, using Lua allows you to conditionalise or randomise levels
with greater control.

Let's take a simple example of randomisation:

NAME: random_test
# Put it on D:1 so it's easy to test.
PLACE: D:1
ORIENT: float
MAP
xxxxxxxxxxxxxxxxxxx
x........{........x
xxxAxxxxxBxxxxxCxxx
xxx.xxxxx.xxxxx.xxx
xxx@xxxxx@xxxxx@xxx
ENDMAP

Now let's say you want A, B, and C to be randomly rock or floor, but B should
be floor if both A and C are rock. Here's one way to do it (add these lines
to the map definition):

: local asolid, csolid
: if crawl.random2(2) == 0 then
:   asolid = true
:   subst("A = x")
: else
:   subst("A = .")
: end
: if crawl.random2(2) == 0 then
:   csolid = true
:   subst("C = x")
: else
:   subst("C = .")
: end
: if asolid and csolid then
:   subst("B = .")
: else
:   subst("B = .x")
: end

This code uses crawl.random2(N) which returns a number from 0 to N-1
(in this case, returns 0 or 1). So we give A a 50% chance of being
rock, and the same for C. If we made both A and C rock, we force B to
be floor, otherwise we use a subst that gives B the same 50% chance of
being rock.

You can conditionalise on various factors, such as player experience
level:

NAME: condition_002
DEPTH: 1-27
ORIENT: float
: if you.xl() > 18 then
MONS: greater mummy
: else
MONS: deep elf priest / deep elf sorcerer / deep elf demonologist
: end
MAP
xxxxxx
x1...x
x1...+
x1...x
xxxxxx
ENDMAP

Or based on where the map is being generated:

NAME: condition_003
DEPTH: Elf:*, Orc:*
ORIENT: float
: if you.branch() == "Orc" then
MONS: orc priest, orc high priest
: else
MONS: deep elf priest, deep elf high priest
: end
MAP
xxxxxx
x1...x
x2...+
x1...x
xxxxxx
ENDMAP

When conditionalising maps, remember that your Lua code executes in
two contexts:

1) An initial compilation phase before the game starts.
2) The actual mapgen phase when the dungeon builder is at work.

In context (1), you will not get useful answers from the Crawl Lua API
in general, because the game hasn't started. This is generally
ignorable (as in the case above) because the compilation phase just
checks the syntax of your Lua code. If you conditionalise your map,
however, you may run into compile failures. Take this variant, which
(incorrectly) attempts to conditionalise the map:

NAME: condition_004
DEPTH: Elf:*, Orc:*
ORIENT: float
: if you.branch() == "Orc" then
MONS: orc priest, orc high priest
MAP
xxxxxx
x1...x
x2.I.+
x1...x
xxxxxx
ENDMAP
: elseif you.branch() == "Elf" then
MONS: deep elf priest, deep elf high priest
MAP
xxxxxx
x1...x
x2.U.+
x1...x
xxxxxx
ENDMAP
: end

This map will break the compile with the cryptic message "Must define
map." (to compound the confusion, the line number for this error will
be the first line number of the map following the buggy map).

This error is because although the map is Elf or Orc only, at compile
time, the branch is *neither* Elf nor Orc, so the level-compiler
thinks you've neglected to define a map.

Lua code can detect the compile phase using crawl.game_started() which
returns true only when the player has started a game (and will return
false when the map is being initially compiled).

For more details on the available Lua API and syntax, see the Lua
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
use a validation hook.

To take a very contrived example:

NAME: contrived_001
PLACE: D:2
ORIENT: float
TAGS: no_pool_fixup
SUBST: .=.w
SUBST: c=x.
MAP
xxxxxx
x{.+.c
x..+>x
xxxxxx
ENDMAP

This map has a chance of leaving the player stuck on the upstair
without access to the rest of the level if the two floor squares near
the doors are substituted with deep water (from the SUBST line), or
the 'c' glyph is substituted with rock. Since a cut-off vault is
uncool, you can force connectedness with the rest of the level:

validate {{ return has_exit_from_glyph('{') }}

The has_exit_from_glyph() function returns true if it is possible to
leave the vault (without digging, etc.) from the position of the {
glyph. (This takes things like the merfolk ability to swim into
account, so a merfolk character may see deep water between the stair
and door.)

The validate Lua returns false (or nil) to indicate that the map is
invalid, which will force the dungeon builder to reapply transforms
(SUBST and SHUFFLE) and validate the map again. If the map fails
validation enough times, the dungeon builder will discard the entire
level and retry (this may cause a different map to be selected,
bypassing the buggy map).

Going back to the example, if you just want to ensure that the player
can reach the > downstair, you can use:

validate {{ return glyphs_connected('{', '>') }}

NOTE: You cannot use the colon-prefixed syntax for validation Lua. If
you have a big block of code, use the multiline syntax:

validate {{
    -- This level is always cool.
    crawl.mpr("This level is guaranteed perfect!")
    return true
}}


G.    Hints for level makers
============================

* Technical stuff:

  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
  have to be there. Any of the other stairs which are not present in the
  vault will be randomly placed outside it. Also generally try to avoid
  rooms with no exit (use at least > or < to make it possible for players
  to get away).

  Minivaults can use explicit @ exits, or be completely surrounded by
  one space of floor for accessibility. Alternatively, you can request
  that the dungeon builder pick appropriate exits as it does for
  floating vaults by using the "mini_float" tag.

  The entry point '@' must be present for all vaults (except
  full-screen vaults where it must not, and floating vaults and
  minivaults where it is optional). All @ will be connected to floor
  space in the rest of the map (multiple @ close together may merge
  into the same exit corridor). Make sure that no part of your entry
  level can be cut off! If no @ is present in a floating vault (and
  there are no doors on the edge of the map, see below), the level
  builder will use one or more random floor spaces '.' or doors at the
  circumference as exits. Note that it is not possible to predict
  which spaces the level builder will choose to connect; if you need
  predictability, use explicit @ exits on the edge.

  The level-builder will also implicitly treat doors and secret doors
  on the edge of a map as explicit exits (the same as using @) and
  connect them to the rest of the level.

  Not using @ and allowing the level-builder to pick exits is
  acceptable in floating vaults, but when you use no @'s with this
  feature in mind, please add comments stating this - else somebody
  may just add @'s later on. :)

  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 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 WEIGHT to create modified versions of the same map. In
  order to do this, make several maps and endow each with a chance such
  that the sum of chances add up to 10.

  Randomisation does not just apply to layout: you could also have
  different monster population sets (for example make a branch end skewed
  for either melee or ranged opponents), or perhaps couple difficulty to
  loot.

* Not too much loot.
  For example, entry vaults should in general have very little loot - in
  particular no good_xxx or '*' items lest they might give incentive for
  start-scumming. For random vaults, there needn't be loot at all and, in
  any case, there shouldn't be too much of it. Compare with the branch ends
  rich in treasure (Tomb:3, Cocytus etc.) to get a feeling for this.

* Have a theme.
  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 WEIGHT: 50000
  will make your entry appear almost always. For other vaults, you can
  for the moment declare them as entry vaults with a huge WEIGHT: as
  above (and preferably in wizard mode). For more intricate things like
  new branch ends, you have to resort to wizard mode and use the &~ command
  to go directly to the place where the map is used, say Snake:5. You may want
  to use a high WEIGHT: again, if the map has alternatives (like Snake:5, or
  Coc:7). Minivaults can also be tested by adding a PLACE: to the definition,
  which makes it very likely that the minivault will appear in the chosen
  level.

  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.

* Be fair!
  Crawl is hard but try to balance your monsters. While it is true that Orc:1
  can show an orcish knight, this is very rare. Hence it's probably a bad idea
  to use orcish knights for an entry to the Orcish Mines.

  Phrased more generally, do not use OOD (out-of-depth) monsters unless you
  really know what you want.

  Be especially fair when creating entry vaults. If your entry is too hard,
  it might get just trashed. Keep in mind that your vault will be played
  very very often, so even small chances of something stupid happening
  (like creation of a really nasty monster) will kick in often enough.

* Minivaults vs. random vaults.
  Minivaults are handled very differently from regular vaults and special
  levels. They're placed *after* normal map generation, whereas normal
  vaults are placed before generating the rest of the level. There's no
  way to guarantee generation of a minivault on a particular level, although
  using a PLACE: attribute makes the dungeon builder try very hard to place
  the minivault on the specified level. Regular vaults can always be forced to
  appear using a PLACE: attribute.

  Technically, you make a minivault like a normal floating vault but
  without an ORIENT: line. Note that minivaults used to be exclusively of
  size 12x12 but this restriction is gone. Still, the smaller the better.

  Where possible, use minivaults instead of regular vaults, because the dungeon
  builder has greater freedom with the rest of the level layout when using
  minivaults.

* levdes.vim.
  If you use vim, the levdes.vim syntax highlighting script (provided
  in the dat directory) can make level-editing far more pleasant by colouring
  different features in maps and syntax-highlighting .des-file syntax. vim is
  available for nearly all operating systems, including Windows.


H.   Portal Vaults
==================

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. Also, there is only one go at a portal vault - if you
leave, it's gone for good. You can apply special rules to a portal vault,
like enforcing maprot.

Portal vaults can be particulary thematic, using specialised monster
sets, fitting loot, coloured dungeon features etc. Avoid death traps; it
is no fun to enter a vault, being unable to leave and be killed outright.
In order to provide fun and reduce spoiler effects, randomise. For portal
vaults, it is desirable to have several different layouts (ideally each
of the maps has some randomisation on its own). Often, it is a good idea
to skew the map distribution: e.g. with four destination vaults, weights
like 40,30,20,10 might be more interesting than 25,25,25,25.

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
TAGS: allow_dup
ORIENT: float
MARKER: O = lua:one_way_stair { desc = "A portal to places unknown", \
                                dst = "generic_portal" }
KFEAT: O = enter_portal_vault
MAP
O
ENDMAP

Portal entries must contain a portal vault entry (enter_portal_vault).
This feature must always have a marker that provides the portal with a
description ("A portal to places unknown") and a destination
("generic_portal").

In case you want to make sure that the portal vault entry is only used
once, you add a TAGS: uniq_BAR line. It should be noted that the label
BAR may *not* end in _entry (otherwise the level builder assumes that
the vault is a branch entry).

If you want the place name displayed while in the vault to be different
than the destination name, then you can give one_way_stair() a "dstname"
parameter.  If you want the place origin for items in a character
dump to be different than the default you can give one_way_stair a
"dstorigin" parameter (i.e., dstname = "garden", dstorigin = "in the gardens").
If you want the place name abbreviation used when displaying notes to be
different than than the default you can use the "dstname_abbrev" parameter.

You can dynamically change the origin string using the lua function
dgn.set_level_type_origin(), and dynamically change the place name
abbreviation with dgn.set_set_level_name_abbrev().

Known portal vault entries will be displayed on the overmap.  By default
the name shown on the overmap will be the "dstname" parameter, or if
that isn't present the "dst" paremeter.  It can be set to something else
with the "overmap" parameter.  A note can be made to accompany the
portal's position on the overmap with the "overmap_note" parameter.

Bones files for characters killed in the portal vault will normally
use an extension derived from the first three letters of the 'dst'
property. You can override this by setting the 'dstext' property to
your preferred extension.

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
ORIENT: encompass
MONS: ancient lich
KFEAT: > = exit_portal_vault
MAP
xxxxxxxxxxx
x111111111x
x1A111111>x
x111111111x
xxxxxxxxxxx
ENDMAP

Note that the entry point into the map will be a stone arch. You must
provide an exit to the dungeon explicitly (KFEAT: > = exit_portal_vault)
or the player will not be able to leave.

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. Here is a lost of the parameters that can be used
within one_way_stair (taken from icecave.des):
        desc = "A frozen archway",    # description of the portal before entry
        dst = "ice_cave",             # label used for maps and entry vaults
        dstname = "Ice Cave",         # used for PLACE: on the main screen
        dstname_abbrev = "IceCv",     # used in the notes
        dstorigin = "in an ice cave", # appendix for items picked up there
        overmap = "frozen archway",   # used on the overmap (X)
        floor = "stone_arch"          # feature left after escaping the portal

The dst string is also used to link the destination maps to the entry maps.
In case dstname is missing, dst will be used.

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. For timed portals, you may want to add messages to the file
dat/clua/lm_tmsg.lua.

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!

Defining a random monster set
-----------------------------

Portal vaults require a defined random monster set to make the Shadow
Creatures spell work. This is done by calling dgn.set_random_mon_list()
manually. Here's an example from ice_cave_small_02 in icecave.des:
  : dgn.set_random_mon_list("ice beast w:90 / ice dragon / nothing")
You can use "nothing" to have the spell fail sometimes.

If you are using the same random monster list in several destination maps,
you can define a lua block and call it from the destination map definition.
This example is from sewer.des:

{{
function sewer_random_monster_list(e)
  e.set_random_mon_list("giant bat w:20 / giant newt w:20 / small snake / \
                         ooze / worm / snake / giant mosquito w:15")
end
}}

You can then use this line in the map definition to execute the lua block:
  : sewer_random_monster_list(_G)

You can also set env.spawn_random_rate() to have monsters generated from the
list during play.

Milestones for portal vaults
----------------------------

This example is from icecave.des, defined in the lua preludes:

{{
function ice_cave_milestone(e)
  crawl.mark_milestone("br.enter", "entered an Ice Cave.")
end
}}

The function is called from each of the destination map definitions:

: ice_cave_milestone(_G)

This marks down entering the portal vault in the milestones. When the portal
is entered, the destination map is chosen and the call to crawl.mark_milestone
is executed along with the rest of the map definition.

Adding milestones in a .des does have the slight catch of creating multiple
milestones if the map fails validation for some reason, so it's best used
in maps that will never fail validation.

I.    Lua reference
===================

How maps are processed
----------------------

Under the hood, Crawl translates everything in a .des file to Lua. You
don't need to know what the underlying Lua looks like to design
levels, but it helps.

Crawl uses Lua 5.1 from http://www.lua.org (the site has information
on the Lua language). Let's examine how Crawl converts a map
definition into Lua code with an example map:

NAME: statue_in_pool
TAGS: no_rotate no_pool_fixup
: if you.absdepth() < 7 then
MONS: plant
: else
MONS: oklob plant
: end
MAP
1...1
.www.
.wGw.
.www.
1...1
ENDMAP

Crawl will convert this map into the following Lua code, wrapped in an
anonymous function (this is called a Lua chunk):

function ()
  tags("no_rotate")
  tags("no_pool_fixup")
  if you.absdepth() < 7 then
    mons("plant")
  else
    mons("oklob plant")
  end
  map(".....")
  map(".www.")
  map(".wGw.")
  map(".www.")
  map(".....")
end

If your level defines prelude or validation Lua code, such code is
extracted into separate prelude and validation chunks. The prelude and
validation chunks are empty unless specified.

Apart from the special NAME map header, every map header translates to
a Lua function with the same name in lowercase. For instance, KFEAT:
<xyz> is translated into kfeat("<xyz>").

If you have a space or comma separated list (such as TAGS, MONS, ITEM,
etc.), then each space/comma separated item is passed into a separate
call to the corresponding Lua function. For instance:

TAGS: no_rotate no_pool_fixup
->
tags("no_rotate")
tags("no_pool_fixup")

MONS: orc, gnoll
->
mons("orc")
mons("gnoll")

Knowing what the generated Lua looks like under the hood is useful
because it allows you to extract repeated boilerplate in similar
vaults into a Lua function in the .des file's prelude. For instance,
if you were planning to write a whole slew of vaults featuring statues
in water guarded by plants, you could extract the common code into the
top of the .des file as:

# This block has to be placed before any other vault in the .des file.
{{
function statue_pool_map(e)
  e.tags("no_rotate")
  e.tags("no_pool_fixup")
  if you.absdepth() < 7 then
    e.mons("plant")
  else
    e.mons("oklob plant")
  end
end
}}

NAME: statue_in_pool
# Pass in the Lua environment global _G to the prelude function.
: statue_pool_map(_G)
MAP
1...1
.www.
.wGw.
.www.
1...1
ENDMAP

You can also use arbitrary Lua directly in vault definitions, which is
handy when randomizing things:

NAME: statue_in_pool
: local plant_weight = crawl.random_range(1,10)
: mons("plant w:" .. plant_weight ..
:      " / oklob plant w:" .. (10 - plant_weight))
MAP
1...1
.www.
.wGw.
.www.
1...1
ENDMAP

How Lua chunks are associated with a C++ map object
---------------------------------------------------

A map's Lua chunk consists of calls to functions such as tags(),
mons(), etc. These functions are defined in the dgn table (see the Lua
API reference below), and they expect to act on an instance of Crawl's
C++ mapdef object. Given:

tags("no_rotate")

the actual Lua call needs to be:

dgn.tags(<map>, "no_rotate")

Where <map> is the C++ map object to which the tag should be added.
Since calling dgn.<foo>(<map>, <xxx>) is tedious, dat/clua/dungeon.lua
wraps the Lua chunk for the map into an environment that defines
wrappers for all the functions in 'dgn' as:

    function <xyz>(...)
      dgn.<xyz>(<map>, ...)
    end

i.e. for every function <xyz> in the 'dgn' table, we define a new
function <xyz> that just calls dgn.<xyz>() with the current map as the
first parameter, and the other parameters as passed in. Thus Lua code
that you write as:

tags("no_rotate")

is translated to the correct dgn.tags(<map>, "no_rotate").

While this is done automatically for map code, if you need to call Lua
code that was not defined in the scope of the map, as in the example
statue_pool_map() function, you need to pass in the map environment to
that function if you want it to modify the map. Thus the call to
statue_pool_map looks like:

: statue_pool_map(_G)

Steps involved in processing .des files
---------------------------------------

* Level files are compiled into a series of Lua chunks. Each map can
  have one or more Lua chunks associated with it: the prelude, the
  body, and a validation chunk. The body is mandatory, but validation
  and prelude chunks are necessary only if your map needs validation
  or fancy selection criteria.

* When first compiling a .des file, Crawl compiles each map's Lua
  chunks, then compiles and runs the prelude, body and validation
  immediately to verify that the Lua code is not broken. Lua errors at
  this stage will cause Crawl to exit with an error message (hopefully
  relevant). Note that the validation Lua chunk's return code is
  completely ignored at this stage - it is only run to check for
  syntax errors in the code.

* When a new game is started, Crawl will run the Lua preludes for all
  maps (most maps should have no prelude - map preludes slow the game
  down). At this point, preludes can change the map's placement or
  availability.

* When the dungeon builder selects a map (based on TAGS, DEPTH,
  PLACE), it re-runs the map prelude and the map body, applies
  transforms (SUBST, SHUFFLE) if any, then calls the map's validation
  Lua. If the map passes validation, the dungeon builder continues
  with level-generation; otherwise, it restarts from the map prelude.

The global prelude
------------------

Every .des file can have (at the start of the file) Lua code that is
not associated with any specific map, but with all maps in the file.
This is called the global prelude. The global prelude is run before
running any other Lua code in the file, once during compilation, and
once at start of game.

You can use the global prelude to define functions and set up globals
that the rest of the maps in the .des file use. If you have a lot of
common code, you should probably add it to dungeon.lua instead.

Syntax for using Lua in .des files
----------------------------------

* Colon-prefixed lines are individual Lua lines, extending to the end
  of the line. E.g.

   : crawl.mpr("Hello")

  Colon-prefixed lines are always in the main Lua chunk, unless they occur
  before any map definitions, in which case they go to the global prelude.

* Lua blocks for the main (body) Lua
   lua {{ <code> }}
  or
   lua {{
       <code>
   }}
  The "lua" word is optional; you can also use:
   {{ <code> }}
  and
   {{
   <code>
   }}

NOTE: Colon-prefixed lines, or lua {{ }} blocks defined before any
map's NAME: directive will add the Lua code to the global prelude.

* Lua blocks for the prelude:
   prelude {{ <code> }}
  or
   prelude {{
       <code>
   }}

* Lua blocks for the validate chunk:
   validate {{ <code> }}
  or
   validate {{
       <code>
   }}

Debugging Lua
-------------

Since Lua action happens in the guts of Crawl, it can be hard to tell
what's going on. Lua debugging involves the time-honoured method of
peppering your code with print statements:

* Use error() or print() for compile-time work (i.e. when Crawl reads
  the .des file). Note that print() just writes to the terminal and
  keeps going, while error() forces Crawl to exit immediately (at
  compile time; errors during level-generation are handled
  differently).

* Use crawl.mpr() for output when the game has started (at
  level-generation time).

It's very important that your finished level never croaks during
level-generation. A Lua error at this stage is considered a validation
failure.


Lua API reference
-----------------
a. The Map.
b. Global game state.
c. Character information.


Lua API - the Map
-----------------

Lua functions dealing with the map are mostly grouped under the "dgn"
module. For convenience, .des file Lua chunks are run in an environment
such that function calls written as:

 fn(x, y, ...)

are translated to

 dgn.fn(map, x, y, ...)

where "map" is the reference to the map that the currently executing
Lua chunk belongs to. This is only for Lua chunks that belong to a
map, Lua code in the global prelude does not get this treatment
(because the global prelude is not associated with any map).

Functions in the dgn module:

default_depth, name, depth, place, tags, tags_remove, chance, weight,
orient, shuffle, shuffle_remove, subst, subst_remove, map, mons, item,
kfeat, kitem, kmons, grid, points_connected, gly_point, gly_points,
original_map, glyphs_connected, orig_glyphs_connected, orig_gly_point,
orig_gly_points, load_des_file, feature_number, feature_name,
dgn_event_type, register_listener, remove_listener, remove_marker,
num_matching_markers, feature_desc, feature_desc_at, item_from_index,
mons_from_index, change_level_flags, change_branch_flags,
set_random_mon_list


Lua API - global game state
---------------------------

The "crawl" module provides functions that describe the game state or
provide utility methods.

mpr, mesclr, random2, coinflip, one_chance_in, redraw_screen,
input_line, c_input_line, getch, kbhit, flush_input, sendkeys,
playsound, runmacro, bindkey, setopt, msgch_num, msgch_name, regex,
message_filter, trim, split, game_started, err_trace, args,
mark_milestone


Lua API - character information
-------------------------------

The "you" module provides functions that describe the player character.

turn_is_over, spells, abilities, name, race, class, god, hp, mp,
hunger, strength, intelligence, dexterity, xl, exp, res_poison,
res_fire, res_cold, res_draining, res_shock, res_statdrain,
res_mutation, res_slowing, gourmand, levitating, flying, transform,
stop_activity, floor_items, where, branch, subdepth, absdepth


J.   Feature Names
==================

These are the feature names usable in MARKER declarations:

unseen, rock_wall, stone_wall, closed_door, metal_wall, secret_door,
green_crystal_wall, orcish_idol, wax_wall, permarock_wall,
silver_statue, granite_statue, orange_crystal_statue,
statue_reserved_1, statue_reserved_2, lava, deep_water, shallow_water,
water_stuck, floor, exit_hell, enter_hell, open_door, trap_mechanical,
trap_magical, trap_iii, undiscovered_trap, enter_shop,
enter_labyrinth, stone_stairs_down_i, stone_stairs_down_ii,
stone_stairs_down_iii, escape_hatch_down, stone_stairs_up_i,
stone_stairs_up_ii, stone_stairs_up_iii, escape_hatch_up, enter_dis,
enter_gehenna, enter_cocytus, enter_tartarus, enter_abyss, exit_abyss,
stone_arch, enter_pandemonium, exit_pandemonium, transit_pandemonium,
builder_special_wall, builder_special_floor, enter_orcish_mines,
enter_hive, enter_lair, enter_slime_pits, enter_vaults, enter_crypt,
enter_hall_of_blades, enter_zot, enter_temple, enter_snake_pit,
enter_elven_halls, enter_tomb, enter_swamp, enter_shoals,
enter_reserved_2, enter_reserved_3, enter_reserved_4,
return_from_orcish_mines, return_from_hive, return_from_lair,
return_from_slime_pits, return_from_vaults, return_from_crypt,
return_from_hall_of_blades, return_from_zot, return_from_temple,
return_from_snake_pit, return_from_elven_halls, return_from_tomb,
return_from_swamp, return_from_shoals, return_reserved_2,
return_reserved_3, return_reserved_4, enter_portal_vault,
exit_portal_vault, altar_zin, altar_shining_one, altar_kikubaaqudgha,
altar_yredelemnul, altar_xom, altar_vehumet, altar_okawaru,
altar_makhleb, altar_sif_muna, altar_trog, altar_nemelex_xobeh,
altar_elyvilon, altar_lugonu, altar_beogh, fountain_blue,
fountain_sparkling, fountain_blood, dry_fountain_blue,
dry_fountain_sparkling, dry_fountain_blood, permadry_fountain


K.   Map Statistics
===================

Full-debug Crawl builds (this does not include normal Crawl builds
that have wizard-mode - you must build Crawl with "make debug", not
"make wizard") can produce map generation statistics. To generate
statistics, run crawl from the command-line as:

crawl -mapstat

This will generate 100 Crawl dungeons and report on the maps used in a
file named "mapgen.log" in the working directory.

You can change the number of dungeons to generate:

crawl -mapstat 10

Will generate 10 dungeons. If you merely want statistics on the
probabilities of the random map on each level, use:

crawl -mapstat 1