File: syntax.txt

package info (click to toggle)
crawl 2%3A0.28.0-1.1
  • links: PTS
  • area: main
  • in suites: bookworm, trixie
  • size: 66,188 kB
  • sloc: cpp: 326,715; ansic: 31,227; javascript: 9,209; python: 5,410; perl: 3,311; makefile: 1,770; java: 792; sh: 665; objc: 250; xml: 32; cs: 15; sed: 9; lisp: 3
file content (1692 lines) | stat: -rw-r--r-- 81,471 bytes parent folder | download
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
-----------------------------------------------
How to make levels for Dungeon Crawl Stone Soup
-----------------------------------------------

Part II:      SYNTAX
              ======

Contents:  G. Glyphs
           H. Header information

This document contains the syntax needed for making maps and vaults. It
does not say anything about principles of vault making; for this, see
introduction.txt. For more technical aspects, including tests, lua and
portal vaults, refer to advanced.txt. For Triggerables, please see
triggerables.txt.

G.   Glyphs
===========

By default, a glyph that has no mapping is turned into floor (DNGN_FLOOR).

Terrain
-------
 x - rock wall                                            (DNGN_ROCK_WALL)
 X - permanent rock wall - always undiggable         (DNGN_PERMAROCK_WALL)
 c - stone wall                                          (DNGN_STONE_WALL)
 m - clear rock wall                                (DNGN_CLEAR_ROCK_WALL)
 n - clear stone wall                              (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_CRYSTAL_WALL)
 t - tree - combustible                                        (DNGN_TREE)

 . - floor                                                    (DNGN_FLOOR)
 + - closed door                                        (DNGN_CLOSED_DOOR)
 = - runed door                                          (DNGN_RUNED_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! You can avoid this
     with the no_monster_gen TAG or KMASK.
 l - lava - again, use the no_monster_gen TAG or KMASK when appropriate!

Features
--------
 @ - Entry point - must be on outside edge. This point will be connected to the
     rest of the level with a corridor for both normal vaults and minivaults.
     If a vault has no entry points defined, random traversable squares on
     its edge will be chosen and connected, as if they had the @ glyph. (In
     the rare event where you don't want this - usually completely enclosed
     vaults accessible through some other means - use the "no_exits" tag.)

     The + and = glyphs, when placed on the edge of the map, are also considered
     entry points.

 }{ - 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 arrival vaults.
 )( - Stone stairs, set 2.
 ][ - Stone stairs, set 3 - minivaults often fail to get this pair if
      the level isn't very interconnected or if any larger vaults are using
      any stairs.

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

 A - Stone arch.
 B - Altar. These are assigned specific types (e.g. of Zin etc) in dungeon.cc,
     in order.
 C - Random altar.

 G - Granite statue (does nothing) - you can see through but not walk through.
     Also, sight-based effects like smiting work past granite statues.
 I - orcish idol. As granite statue, generally used for theme.

 T - Water fountain
 U - Magic fountain
 V - Permanently dry fountain
 Y - Blood fountain (use sparingly!)

Items
-----
 $ - gold
 % - normal item

 * - higher quality item, with the quality level increasing with absolute
     depth. The level is 2 * absdepth + 5, capped at 50.
 | - superb quality item, the highest quality level. It's a special class
     above the "*" glyph, similar to the "good_item" modifier described
     below, but with a different distribution of item classes: this glyph
     generates only weapons, armour, jewellery, books, staves, and
     miscellaneous items.
 d-k - item array item. See section below on ITEM: arrays for more info.

Monsters
--------
 0 - normal monster
 9 - random monster from placement_depth + 5 ("moderate out-of-depth")
 8 - random monster from (placement_depth + 2) * 2 ("super out-of-depth")
 1-7 - monster array monster. See section below on MONS: arrays for more
     information

Both 8 and 9 in early dungeon (through D:8) are capped to 2 * placement_depth.

H.   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.

DESC:     readable name
          A map may optionally have a description. If provided, and if
          the character dies in the vault, the map description will be
          shown along with the place at end of game. This is normally used
          only for the Sprint game type.

          Map descriptions are also written to scores and logfile
          entries.

ORDER:    <integer>
          Used only for special game types (Sprint, Tutorial).
          When the user is prompted to select a map, the available maps are
          sorted by the integer value (ascending). Maps without an ORDER:
          line follow those that have one. Maps with the same value of
          ORDER: are sorted by description (if present) or name.

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

          A ORIENT: line is not 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.
          * "encompass": The dungeon builder uses your vault as the entire map.
          * "centre": The vault is placed in the centre of the map.
          * "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: D:7-13

          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.

          You can constrain a map by branch:

            DEPTH: Lair:3-6

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

            DEPTH: Lair

          (Anywhere in the Lair. Can also be expressed as "DEPTH: Lair:*".)

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

            DEPTH: Lair, !Lair:4-6

          (Anywhere in the Lair, except for Lair:4, Lair:5, or Lair:6.)

            DEPTH: Orc, !Orc:$

          (Anywhere in Orc except for the last level.)

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

            DEPTH:

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

          A plain 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 is treated as depth 10 for this purpose.)
          In general, you should avoid using such unconstrained DEPTHs.

          If there are multiple DEPTH: declarations, later ones will be added
          to previous ones.

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

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

          There are two ways to specify the CHANCE roll:

          CHANCE: 501
          or
          CHANCE: 5.01%

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

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

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

          Dummy vaults (vaults with the "dummy" tag) use CHANCE to specify
          an absolute chance of using the dummy instead of a real map. A CHANCE
          of 80% means the dummy will be used in 80% of vault placement
          attempts.

          The Lua equivalent of CHANCE is:

          : chance(<number>)

          These lines are all equivalent:
          CHANCE: 5%
          CHANCE: 500
          : chance(500)

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

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

          NAME: portal_b
          CHANCE: 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. You can combine use of CHANCE with WEIGHT (see below) to have
          the same overall chance of selecting from the set while giving
          different likelihoods to maps within the set.

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

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

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

          The Lua equivalent of depth-constrained CHANCE:
          CHANCE: 2% (D:*, Lair:2-4), 50% (Geh)
          is as:
          : depth_chance("D:*, Lair:2-4", 200)
          : depth_chance("Geh", 5000)


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

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

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

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

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

PLACE:    Used to specify certain special levels. Existing special levels
          include most branch ends.
          The branches need to use the official abbreviations also used e.g. in
          the overmap (Ctrl-O): D, Temple, Orc, Elf, Lair, Swamp, Shoals,
          Spider, Snake, Slime, Vaults, 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 or Pandemonium.

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

TAGS:     Tags go on a TAGS: line and are space-separated. You can have several
          TAGS: lines, or use \ for very long ones. Valid tags are:
          * Any KPROP name ("no_tele_into", "no_tide", etc.): applies the
             property to every square of the vault. See KPROP: below.
          * "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. This is tracked
             separately for the abyss and the rest of the dungeon.
          * "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.
          * "decor": this tag indicates that the vault is purely decorative,
             and has neither threats nor items. Levels of Dungeon deeper than
             D:14 and all of Depths have an 80% chance to place an extra vault
             with this tag; see dungeon_decor in builder/decor.des.
          * "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. These vaults should have a CHANCE statement to
             define this probability; see CHANCE: above.
          * "arrival": this tag MUST be there for a vault to be pickable as a
             D:1 arrival vault.
          * "extra": requests that the dungeon builder treat this as
             an extra vault. This forbids the vault from being placed as
             a primary vault if it has an ORIENT: tag; instead it will be
             placed after all other vaults. For minivaults, if the map is
             selected, the builder will attempt to place another minivault
             immediately afterwards. "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" and your map is
             tagged "allow_dup", it is a good idea to use a "luniq" tag so
             that the same map does not place more than once on a given level.
          * "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.
          * "no_exits": In the absence of explicit exits, requests that the
             dungeon builder does not try to pick its own exits from the
             (mini)vault. Usually only used when the vault is completely
             enclosed and accessible through other means.
          * "no_monster_gen": Prevents random monster generation at the time of
             the vault's creation. Highly advised for arrival vaults with a
             player-hostile geography, MUST-HAVE for those with water/lava.
             Can be applied only to particular symbols with KMASK.
          * "no_pool_fixup": prevents water squares next to land from being
             randomly converted from deep water (the default) to shallow.
          * "no_wall_fixup": In Dis, the Vaults and the Crypt a vault's
             rock walls will be changed to be the same as the wall type of
             the rest of the level. If you don't want that to happen then
             use this tag.
          * "no_trap_gen": Prevents random trap generation at the time of the
             vault's creation.
          * "uniq_BAR": (uniq_ with any suffix) specifies that only one of
             the vaults with this tag can be used in a game. In particular,
             late-Dungeon encompass vaults have the tag uniq_d_encompass, so
             that only one will occur per game. This is tracked separately
             for the abyss and the rest of the dungeon.
          * "luniq": specifies that this vault can be used only once on a
             given level. "luniq" is only relevant when used with "allow_dup".
          * "luniq_BAR": (luniq_ with any suffix) specifies that only one
             of the vaults with this tag can be used on any given level.
             "luniq_BAR" is only relevant when used with "allow_dup".
          * "branch_entry" eg. "orc_entry", "lair_entry" etc.
             If chosen, these maps will contain the stairs for that branch.
             If a branch has very few entries, a dummy entry is advisable to
             make sure the player doesn't get bored of the same few entries
             recycled ad nauseam.
             Note: if any TAG argument contains an "entry", the vault will
                   be no longer eligible for random placement. (Currently,
                   this just affects your choice of BAR when using uniq_BAR.)
          * "mnoleg" or the name of some other pandemonium lord. This makes
             the map eligible for said pan lord's lair. See pan.des.
          * "no_rotate":  Normally, the dungeon builder can, at its whim,
             rotate your vault. This flag tells it, "hey, don't do that to my
             vault!"
          * "no_hmirror": Like no_rotate, but for horizontal mirroring.
          * "no_vmirror": Like no_rotate, but for vertical mirroring.
          * "overwritable": Lets the dungeon builder overwrite this vault with
             other ones. Don't use this casually.
          * "overwrite_floor_cell": Tells the dungeon builder that this vault
             intends to overwrite a single floor cell, possibly inside another
             vault, even if that vault does not have the "overwritable" tag.
             This tag can only be applied to 1x1 vaults. Don't use it casually.
          * "layout": Makes the vault eligible for use as a level layout. Do
             not use this unless you know what you are doing.
          * "layout_foo": Indicates what sort of level layouts this vault is
             compatible with, for vaults that don't fit in with all layouts;
             the absence of this type of tags means it can go with any
             layout. Multiple layout_foo tags can be used if it can be used
             with multiple layouts. Current values for "foo" are:
             * corridors: Mostly 1-cell-wide corridors
             * rooms: Corridors connecting rooms
             * passages: Mostly multi-cell corridors
             * narrow_caves: Corridor-like caves
             * open_caves: Open caves
             * city: A large open room with "building" rooms in it
             * open: Layout is mostly open but not cavelike
             * divisions: Just ajoining rooms
             * vaults: Used in the Vaults branch (no normal vault placement)
             * shoals: Used in the Shoals branch
             * swamp: Used in the Swamp branch
             * forest: Was used in the now-defunct Forest branch
             For more details on the layout types and the layouts that place
             there, see Layout Types on the devwiki at
             crawl.develz.org/wiki/doku.php?id=dcss:brainstorm:dungeon:layout_types
          * "no_species_xx": Disables the vault for a given player species
             (two-letter abbreviation). Note that the current design rules
             strictly disallow varying the map generation based on the
             character -- this tag is only for acquirement-like effects,
             sprint, or tutorial.
          * "ruin": requests the level builder to damage the vault by
             removing walls near the edges, making it look like a ruin.
             You can request that a vault be ruined only in a particular
             branch using "ruin_<branch>". For instance: "ruin_lair".
          * "no_dump": Don't dump out this vault's name in the list of
             vaults generated during the game. Use this if the vault
             is predictable (like the Vaults:5 and Slime:6 vaults) or
             are for weird internal uses (like the shoalhut vaults).
          * "unrand": Don't pick this vault randomly by DEPTH. Can still be
             picked by tag or PLACE. Almost exclusively used by layouts and
             subvaults.
          * "transparent": Marks the vault as potentially passable for the
             purposes of level connectivity. By default, vaults are considered
             non-passable regardless of their contents. With this tag, the
             actual terrain of the vault affects its passability as seen by the
             dungeon builder. A disconnected region inside a transparent vault
             will cause a veto of the level (but see the "opaque" KMASK below).
          * "passable": Rather than "transparent", which causes terrain checks
             to be performed, this indicates that the entire vault should be
             considered passable. This tag does not have an effect except in
             the Vaults branch, and is used for rooms in Vaults where normal
             opacity would invalid the layout, but the room might contain
             internal geometry that we wish to ignore due to features the map
             controls, such as transporters. When using this tag, please
             ensure that your vault contains a path (for example, surround the
             outside with floor); otherwise, the builder will be able to create
             disconnected zones. In most circumstances, outside of transporter
             vaults, this tag should not be used.

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_wax")
          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, potion of haste, ring of ice

          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 occurrence
          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 cloak with
          50% chance, or hat or helmet with 25% chance each:

            ITEM: cloak / w:5 hat / w:5 helmet

          Modifiers:
          * "q:N" sets the item quantity to N (if N > 0). Does nothing
             if the item is not stackable.
          * "charges:N" sets the number of charges for wands.
          * "plus:N" sets the item plus for weapons, armour, and jewellery
            (such as rings of intelligence or slaying). Do not override fixed
            plusses for jewellery unless you know what you are doing.
          * "no_uniq" prevents the item from being turned into an artefact,
            unless cancelled by an "allow_uniq" modifier.
          * "good_item" makes the builder try to make the item a good one
            (acquirement quality). This is independent of the level's depth, in
            contrast to placing items with the "*" glyph, which just adds a
            bonus to depth for the item generation. The "|" item glyph uses
            this quality level (but with a different distribution of item
            classes, see above).
          * "acquire" requests the use of the acquirement code
            itself, ensuring that the player gets wearable armour, etc. You can
            also use acquire:<god> to request that the acquired item be
            treated as a god gift. Examples: "acquire any", "acquire armour",
            "acquire:sif_muna book", "acquire:trog weapon". Use of this outside
            of specialized portals as part of the builder is *deprecated*,
            because conditioning level generation on player properties
            interferes with seeding.
          * "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. This modifier does not
            affect jewellery.
          * "any" by itself gives a random choice; you can combine "any" with
            "good_item". A lone "%" may be used as an alias for "any".
          * "useful" tries to select an item usable by the player, but may
            give an useless one if it has trouble finding one
          * "star_item" by itself makes an item equivalent to the "*" glyph.
            A lone "*" may be used as an alias for "star_item".
          * "superb_item" by itself makes an item equivalent to the "|" glyph.
            A lone "|" may be used as an alias for "superb_item".
          * "any book", "any misc" etc. gives a random item of that class.
            Valid item class names are: gold, weapon, missile, armour, wand,
            scroll, jewellery, potion, book, magical staff, orb, misc, carrion.
            All of these are usable in map definitions, apart from "orb" and
            "carrion".
          * "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. The full lists
            are in the str_to_ego() function in mapdef.cc.
          * "randart" will force a randart. Most of the above modifiers
            will be ignored, except for "ego" (for weapons only).
          * "mundane" acts as a shortcut for "ego:none" and forces the plusses
             to be +0.
          * "ident:" will make the item pre-identified. You need to specify
            a "|"-separated list of what is to be known:
            * "type"
            * "pluses"
            * "properties"
            * "all"
          * "unobtainable" hints that the item is supposed to never fall into
            the player's hands. It doesn't actually keep it from doing so,
            just tells that to acquirement and (TODO) troves.
          * "mimic:N" gives the item one chance in N of being turned into a
            mimic. The ":N" can also be omitted for a guaranteed mimic.
          * "no_pickup" prevents monsters from picking up the item, for vaults
            intending to have an impressive display of loot (although in most
            cases monsters should be allowed to pick up and use loot against
            the player).
          * "tile:" and "wtile:" will set the item's inventory/ground and
            worn (player/monster doll) tiles. Generally you'd want to set
            both to ensure they match.

          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 armours, 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.

          Corpses
          -------
          You can create corpses and skeletons using "<monster> corpse" or
          "<monster> skeleton".

          For instance: "rat corpse", "18-headed hydra skeleton".

          Corpses and skeletons are by default created with maximum freshness
          (210). They may still rot away before the player finds your vault.
          To prevent corpses from decaying, you can define them using a
          "never_decay" property as:

          ITEM: never_decay human corpse

          However, direct use of "never_decay" is not recommended,
          since such items will not behave as the player expects.
          Instead, you can set corpses to stay fresh until seen by the
          player with a delayed_decay marker. Instead of:

             KITEM: e = orc corpse / orc skeleton

          you'd use:
             : dgn.delayed_decay(_G, "e","orc corpse / orc skeleton")

          (Note the leading ":" - this is a Lua call).

          delayed_decay generates the corpse with the "never_decay"
          item property and creates a trigger that fires when the
          player enters LOS of the square in question. When triggered,
          it clears the "never_decay" property, allowing the item to
          start decaying normally. Note that this does not work with
          "/ nothing" alternatives (or other non-corpse items);
          for those cases, use SUBST with a second glyph and KITEM.

          If you need to put additional non-corpse items at the same location,
          use delayed_decay_extra:
             : dgn.delayed_decay_extra(_G, "e", "human corpse", "mace, shield")

          IMPORTANT: the delayed_decay line should always come after any
          shuffles or substitutions of the relevant glyphs. This is because
          it is equivalent to a KITEM plus a MARKER; the former applies to
          the glyph after all substitutions, while the latter considers only
          those substitutions that precede the delayed_decay call.

          Unrands
          -------------------
          You can specify fixed artefacts, e.g. the scythe of curses, by
          naming them: "KITEM: e = scythe of curses". If the desired unrand's
          names has something between double quotes, use that: e.g, rift.

          If this unrand has already been placed, a randart of the same type
          will be created instead. Staff unrands, since they have no
          corresponding type that can be transformed into a randart, are
          replaced by an appropriate magical staff. (E.g. a staff of poison.)
          You should not use `you.unrands` to check whether an unrand has been
          seen in normal levelgen scenarios, as it will impact seeding. Some
          details about default fallbacks can be specified in art-data.txt.

          Randart spell books
          -------------------
          You can specify random artefact spell books using:

          * "any fixed theme book" will generate a book with a fixed theme
            (set of spell schools).
          * "any fixed level book" will generate a book with a fixed set of
            spells around the same level.

          You can further specify artefact spell books using "randbook" and any
          combination of the following tags:

          * "numspells:number" maximum number of spells to include in the book.
            A book may contain at most 8 spells.
          * "owner:name" will be used to make the title include the
            apostrophised owner (or author) of the book if provided. For
            example, "owner:Roxanne" may create "Roxanne's Treatise on
            Mountains". You can use the keyword "player" (i.e. "owner:player")
            to use the player's name instead.

          In addition, themed books allow the use of the following tags:

          * "disc:spell_school", the first spell school that should be included
            in the book. For example, "disc:earth" or "disc:ice".
          * "disc2:spell_school" an optional second spell school that can be
            included in the book. Note: specifying two spell schools doesn't
            mean that they will both definitely be included, just that they
            might be.
          * "slevels:max_levels" the total, combined level of spells to include
            in the book. "slevels:6" will use three level two spells, two level
            three spells, a level two and a level four spell, and so on.
          * "spells:spell_1&spell_2" a list of spells to include in the book.
            Spells must be separated by "&" without spaces. Within a spell name,
            all of "_" will be replaced with " " and will be parsed as such.
            A book may contain at most 8 spells.
          * "title:title" will define the title of the book.

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


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 arrival 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.

          A hydra can be given a specific number of heads by calling it
          an "n-headed hydra" (with a maximum of 20 heads):
              MONS: four-headed hydra

          A mutant beast can be customized by prefacing it with a maturity level
          and/or hyphen-separated set of traits, as follows:
              MONS: mature shock-weird mutant beast

          A slime creature's size can be set to other than normal using
          the prefixes "large", "very large", "enormous" or "titanic":
              MONS: very large slime creature

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

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

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

          The colour "any" can be given, in which case a random colour
          will be chosen when the monster is placed.

          You can override the displayed monster tile using the "tile:"
          specifier as follows:
              MONS: rat tile:mons_giant_bat

          In tiles version, this would create a monster that uses the
          "mons_giant_bat" tile, but is otherwise identical to a rat.
          Obviously, this substitution of one monster onto another should
          never be used, but it can be useful for customised vault monsters
          if an alternate tile exists. In ASCII mode, this will do nothing.

          You can set the monster's god using the "god:" specifier as
          follows:
              MONS: orc god:the_shining_one

          If the monster is to be a gift of the specified god, this should
          be suffixed with "god_gift" (without the quotes):
              MONS: orc god:the_shining_one god_gift

          Note that the monster will not be considered a god gift unless
          god_gift is explicitly set.

          You can set the monster's faction by specifying "att:" one of:

          * att:hostile -- the default
          * att:friendly -- tame, will follow you
          * att:neutral -- hostile to both you and att:hostile monsters
          * att:good_neutral -- hostile to att:hostile
          * att:fellow_slime -- tame, won't follow you

          Note that the glyphs 8, 9, 0 (without MONS) also place monsters:
             0 - normal monster (this is equivalent to MONS: random)
             9 - +5 depth monster
             8 - (+2) * 2 depth monster.

          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:3 zombie
          or
              MONS: place:Zot:5 simulacrum
          or
              MONS: place:Vaults:5 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 ; rapier | quick blade . chain mail | plate armour

          will generate an orc wielding either a rapier or a quick blade
          and wearing either chain mail or plate armour. Randarts and
          ego items are only generated if they are explicitly requested.
          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

          Limitations: If an item in the item list has alternatives,
          there's no way to force all monsters derived 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.

          You can specify that a monster will always generate a corpse by
          using the tag "always_corpse", and that it will never generate
          a corpse by using "never_corpse". This should only be used in
          vaults where it is absolutely necessary, tutorial maps, etc.

          Overriding Monster Names:
          -------------------------

          Individual monsters can be given names as follows:
              MONS: kobold name:Durwent

          This will cause the monster to appear as "Durwent the kobold".
          Spaces can be placed in the name by substituting them with the _
          symbol. It is worth noting that "the <race>" will be appended
          to all names, which should be considered when coming up with them.

          The name tag is also useable in KMONS. It should be used carefully
          to avoid having multiple monsters named the same (ie, as above,
          and then using the glyph "1" multiple times will result in multiple
          "Durwent the Kobold"s).

          There are three different modifiers that can be used on a name:
          name_adjective, name_suffix and name_replace. name_adjective
          makes the name act as an adjective. For example:
              MONS: kobold name:ugly name_adjective

          Will cause "An ugly kobold", "The ugly kobold hits you",
          and so on.

          name_suffix does the same, but after the monster's base name:
              MONS: kobold name:wearing_mittens name_suffix

          Will give "A kobold wearing mittens", "The kobold wearing
          mittens hits you", and so on.

          name_replace causes the base name to be replaced by given
          name, as if the monster was a unique:
              MONS: kobold name:Durwent name_replace

          Will result in "Durwent" rather than "Durwent the Kobold". The
          corpse will still be a "kobold corpse of Durwent".

          In combination with name_replace or name_species, there are two
          further tags that can be used when renaming monsters, but not
          giving them an actual "name": name_descriptor, and name_definite.

          For example:
              MONS: kobold name:goblin name_replace

          Will result in "goblin hits you". However, adding name_descriptor
          from the above flags will result in "The goblin hits you" and in the
          description of the monster, "A goblin".
              MONS: kobold name:goblin name_replace name_descriptor

          The name_definite flag ensures that it is never referred to as "a" or
          "an", but that the definite object is always used. Therefore, you will
          see "The goblin hits you", as per above, but also "The goblin" in its
          description. Setting name_definite will automatically set the flag
          name_descriptor, therefore meaning that:
              MONS: kobold name:goblin name_replace name_definite

          Is exactly the same as:
              MONS: kobold name:goblin name_replace name_descriptor name_definite

          name_species uses the name for corpses as-is, without prefixing it
          with "kobold corpse of X" for name_replace. It also avoids the usual
          name tag that displays above unique and renamed monsters in local
          tiles.

          name_zombie can be used to redefine already zombified monsters
          (including skeletons, simulacra and spectrals).

          Finally, name_nocorpse will cause the name to be completely ignored
          for corpses. For example:
              MONS: wizard name:sad name_adjective name_nocorpse
          will result in "a sad wizard" that leaves "a wizard corpse".

          For instances where space in definitions is limited, you can use
          abbreviated forms of these tags:

              name_suffix     -> n_suf
              name_adjective  -> n_adj
              name_replace    -> n_rpl
              name_species    -> n_spe
              name_descriptor -> n_des
              name_definite   -> n_the
              name_zombie     -> n_zom
              name_nocorpse   -> n_noc

          Monster names should be used very sparingly.

          Every renamed monster needs a description as well (place it in
          dat/descript/monsters.txt). If you want to have multiple monsters
          share descriptions and speech, you can do it with "dbname:".

          Overriding Monster Stats:
          -------------------------

          Further monster customisation can be made by using "hd" and "hp".
          These two tags allow you to completely overwrite the original hit dice
          and hit points of a monster:
              MONS: kobold hd:20

          Creates a kobold with a hit dice of 20. As its hp is randomised, based
          on its hit dice, this will also be re-rolled. Monsters with a specific
          hit point value will not have this value change.

          You can also have a specific value for hit points:
              MONS: kobold hp:20

          Creates a kobold with 20 hit points. This is also useful for monsters
          (such as statues) which come with non-randomised HP values.

          Monsters can be marked as summoned by using "dur" and "sum" tags. The
          "dur" tag accepts an integer between 1 and 6 inclusive. The "sum" tag
          accepts the name of a spell (parsed as per the spells tag, described
          below) or any of "clone" (Rakshasa), "animate" (from animate dead),
          "chaos" (made from pure chaos), "miscast" (summoned from by spell
          miscast effect), "zot" (summoned by a Zot trap), "wrath" (summoned by
          a god in an act of retribution), "aid" (summoned by a god in order to
          give aid).

          Of the spells, "shadow_creatures" has the most significant effect, in
          that monsters will dissipate into the shadows rather than disappear in
          a puff of smoke. Using non-summoning spells will also have no effect.

          Tagging a monster with "seen" will override the system and force that
          monster to be marked as already viewed; this means that it won't
          generate messages such as "XYZ comes into view".

          Overriding Monster Spells:
          --------------------------
          Monster spell sets can be overridden with a spells: tag,
          used as follows:

              MONS: goblin spells:throw_flame.50.wizard
              MONS: ancient lich spells:symbol_of_torment.26.wizard;\
                                        glaciate.51.wizard

          (a list of spell slots, consisting of a spell name with
          spaces replaced with underscores, a frequency of casting and
          set of spell slot flags specified afterwards with .,
          with slots separated by ";" with no spaces around the ";" or
          after the spells: prefix)

          Spell names must exactly match the names in spl-data.h, with
          spaces replaced by underscores. Spell frequencies are an
          (x in 200) chance that that spell will be cast. Spell flags
          include:
          - "natural", "magical", "demonic", "wizard", or "priest" -
            the manner in which this spell is being cast. Wizards and
            priests can be silenced and will trigger appropriate conducts
            (Trog will appreciate killing wizards, Beogh will appreciate
            killing priests). Magical, demonic, and wizard spells
            are subject to anti-magic effects. Natural spells do not
            generate noise.
          - "emergency" - the monster will only cast the spell when low
            on health.
          - "breath" - the spell is a breath weapon, and using it
            triggers a breath timeout during which the spell cannot be
            cast again.
          - "no_silent" - the spell cannot be used while silent, even if
            it is an ability type normally not subject to silence.
          - "instant" - the spell does not expend the monster's energy;
            they may take another action on the same turn.
          - "noisy" - forces the spell to make noise even if it is a
            natural ability.

          You may use "none" specify that a slot should be left empty.
          You can force a spell-less monster with:
              MONS: orc wizard spells:none

          Setting enchantments:
          ---------------------
          You may give a monster any number of enchantments. It may
          start hasted, blind, have permanent RMsl, etc. The syntax is
          "ench:<name>:<degree>:<duration>" or "perm_ench:<name>:<degree>".
          The <degree> and <duration> fields may be omitted. Note that
          the enchantment will start the moment the monster is created and
          thus most likely time out before the player has a chance to
          notice the monster -- non-permanent ones make sense mostly only
          if created from a lua trigger.

          MONS: orc perm_ench:blind perm_ench:mad
          MONS: dream sheep ench:sticky_flame
          MONS: stone giant dur:1 ench:berserk


FHEIGHT:  xyz = 40

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

          Heightmaps are currently only useful in the Shoals, as a means of
          influencing how the tide interacts with your vault. The Shoals
          heightmap uses these heights when the tide's height is 0, i.e.
          at neutral tide:
               >= 0     Floor
               >= -14   Shallow water
               <= -15   Deep water

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


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

          You can use : to specify that all glyphs get the same colour:
          COLOUR: x : red / blue
          will colour all rock walls in the map red, or all rock
          walls blue.

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

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

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

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

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

          {{
              colour.add_colour("checkerboard", function(rand, x, y)
                  if (x + y) % 2 == 0 then
                      return "red"
                  else
                      return "white"
                  end
              end)
          }}

          and then in your map definition, you can use "checkerboard" as a
          valid colour name. In the colour definition function, "rand" is a
          random number between 0 and 119 (chosen randomly each time this
          function is called), and "x" and "y" are the coordinates of the tile
          that this is supposed to be colouring.

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

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

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

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

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

          Like COLOUR, this should be used sparingly.

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

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

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

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

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

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

          To override doors, use the specific tile set in combination with the
          "no_random" specifier. Example:
              + = no_random dngn_fleshy_orifice

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

CLEAR:    Clear is a special kind of SUBST that only swaps glyphs to " ",
          i.e. a blank space. This makes the resulting areas not part of
          the map, so they won't overwrite the underlying level. The
          syntax is simply:

          CLEAR: xyz

          This will erase the glyphs x, y and z from the map by turning
          them into spaces.

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

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

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

          KFEAT features are specified as a feature name (see feature-data.h
          in the source/ directory for a full list of feature names). As
          another example, you can place a portal to the Abyss as:

          KFEAT: A = enter_abyss

          If you want no feature as an option in a KFEAT line, use "." or
          "floor". If you do not want to specify the type of shop, use "any
          shop" or "random shop". If you wish to specify more complex options
          for shops, see the section on shop definitions at the end of this
          document.

          You can also place feature mimics using the same syntax as item
          mimics. For example this altar has a 1 in 10 chance of being
          turned into a mimic:

          KFEAT: C = C mimic:10

          Some features (specifically shops and portal vault entries) may
          be randomly turned into mimics by the dungeon builder. You can
          prevent this with "no_mimic":

          KFEAT: S = any shop no_mimic

          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.

          KFEAT overrides the normal meaning of the glyph: In the absence
          of further declarations,
            KFEAT: 1 = shallow_water
          will result in 1 producing shallow water with no monster.

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

          Shop definitions
          ----------------

          It's possible to customise shops further than simply specifying the
          type of shop to place. There are a number of options, which are
          enumerated below:

            use_all:    If true, and items have been specified, all items
                        specified will be placed in the shop, without using
                        random selection to determine a number of items from
                        the list.
            name:       If provided, this is apostrophised and becomes the
                        shop-keeper's name. For example, name:Ploog would
                        result in "Ploog's <X shop>".
            type:       If provided, this is used as the "type" name for the
                        shop. For example, type:Wand would result in "X's Wand
                        shop". Please note: this is *not* the type of shop,
                        simply the name. Setting this will not change the
                        content of the shop. You will still need to specify the
                        type in the definition, i.e., "antique armour shop".
            suffix:     If provided, this is used instead of "Emporium",
                        "Shop", etc, in the shop name. For example,
                        suffix:Bazaar results in "X's x Bazaar".
            count:      If specified, this restricts the number of items placed
                        in the shop to this number. For example, "any shop
                        count:1" results in a single shop with a single item in
                        it.
            greed:      If specified, this increases the cost of items for sale
                        in the shop. Someone should fill the algorithm here!

          Shop items
          ----------

          It's possible to also specify a list of items that should be placed
          in a shop. This syntax specifies a number of items separated with |,
          which is further separated from the individual shop specification
          using the ; symbol. Individual shop items are parsed as per standard
          item definitions, identical to those used for monster items, and
          so-on.

          Examples
          --------

          KFEAT: a = any shop name:Ploog type:Wand suffix:Emporium count:3
                       use_all greed:10 ; any wand | any wand | any wand

          In theory, this will create "Ploog's Wand Emporium", which has
          exactly three items, each of which is a randomly chosen wand.

          Note: Transporters are placed in vaults via lua markers, and
          shouldn't need placement via KFEAT. See the Transporters section
          below.

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, Maggie or Erica or a generic human
          (whoever is available, in that order, you can use):
            KMONS: n = Terence, Maggie, Erica, human
          Or if you want to pick randomly:
            KMONS: n = Terence / Maggie / Erica, human

          KMONS overrides the normal meaning of the glyph: In the absence
          of further declarations,
            KMONS: W = rat
          will result in W producing a rat on a floor tile, not shallow water.

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

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.
          * "no_trap_gen": Prevents random trap generation on that symbol.
          * "no_pool_fixup": Prevents a water square next to land from being
             randomly converted from deep water (the default) to shallow.
          * "no_wall_fixup": Prevents (rock) walls from being converted to
             the level's default wall type, such as in Vaults.
          * "opaque": Overrides the "transparent" tag for this particular
             symbol. The symbol is considered impassible for level-building
             purposes. A "transparent" vault with a deliberately disconnected
             region must use this mask on the disconnected part.

          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. Or, to make only part of a vault transparent for
          level-connectivity purposes:

            KMASK: .12 = !opaque

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

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

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

          Unlike KFEAT etc., KPROP is applied to the cells of the map that
          currently have that glyph, applying only the shuffles and
          substitutions before the KPROP declaration. That is:
            KFEAT: ' = rock_wall
            KPROP: ' = bloody
            SUBST: ' = '.
          causes ' to produce a bloody wall or a bloody floor at random,
          while:
            KFEAT: ' = rock_wall
            SUBST: ' = '.
            KPROP: ' = bloody
          causes ' to produce either a bloody wall or a bloodless floor.

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

          Available properties are:

          * "bloody": Causes features to appear as though splattered with
             blood. This should be used very, very sparingly!
          * "no_cloud_gen": Prevents clouds from being generated over this
             feature (usually lava). Does not stop fog generators or clouds
             entering from nearby squares.
          * "no_tele_into": Prevents teleportation from choosing to use this
             square. Also prevents this square from being the destination of
             a shaft or hatch. Use this tag to prevent nasty situations like
             the player ending up in a closet or an extremely dense monster
             array (like a hellion island); or for vaults with loot where the
             player is not supposed to get it by teleporting alone.
          * "no_tide": Shoals tides will not affect this square.
          * "no_jiyva": No spawning jellies, no off-level eating.

          One more named property exists, but should be avoided:

          * "highlight": The square will be highlighted in the X map in wizard
            mode, and will appear in dumps as "?". For debugging use only; this
            property should be removed before submitting vaults.

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

KITEM:    ? = potion of curing / potion of haste
          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: ? = potion of curing, potion of haste, potion of magic

          KITEM overrides the normal meaning of the glyph: In the absence
          of further declarations,
            KITEM: W = any weapon
          will result in W producing a weapon on a floor tile, not shallow
          water.

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

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

          Lua markers are used for more complex triggers such as entry to the
          Slime loot areas when the Royal Jelly dies, fog generators,
          transporters, etc.

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

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

          Feature names used in markers must be names matching the names in
          feature-data.h, e.g. "escape_hatch_up".

          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>

SUBVAULT: X : some_vault_tag / some_other_vault_tag:20

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

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

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

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

              ......
              ..XXX.
              ..XXX.
              .XXX..
              ......

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

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

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

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

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

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

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

          is_subvault()

              This function returns true if the current map is being used as a
              subvault and false if the current map is a normal vault.

          local width, height = subvault_size()

              This function returns the width and height of the subvault.
              If not a subvault, it returns 0.

          iter.subvault_iterator(_G)

              Can be used to iterate through all the 0-indexed coordinates
              in the subvault that will get copied back to the parent vault.
              It will return no points if this is not a subvault.

          default_subvault_glyphs()

              This is a convenience function that replaces the current
              subvault map with one that is the exact size of the bounding
              box. For any valid square that the parent map will replace with
              the subvault, it will place a "." in the map. For any invalid
              square that will not be replaced by the subvault, it will place
              a " " in the map. If not a subvault, it does nothing.

              The advantage of this is that a vault author can then use nsubst
              on the "." feature to ensure that a fixed number of objects will
              be created in the parent vault.

              NOTE: This function will also entirely clear the current map, so
              call it first in the subvault definition.


Handling long lines
-------------------

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

KMONS: * = orc ; rapier | 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 curing \
              , potion of haste
Right:
        ITEM: potion of curing, \
              potion of haste

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

Preferred:
        ITEM: potion of curing
        ITEM: potion of haste

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\
      curing

Crawl will see "potion ofcuring", not "potion of curing".

Assigning multiple glyphs at once
---------------------------------

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

    FTILE: .[{( = floor_orc

This case is identical to the longer syntax:

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

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

    KITEM: ABC : gold / nothing

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

    # Among all A, B, and C glyphs, make one a floor and the rest walls.
    NSUBST: ABC = 1:. / *:x

    # Make one A glyph floor, one B glyph floor, and one C glyph floor.
    # Make the rest of the A, B, and C glyphs walls.
    NSUBST: A = 1:. / *:x
    NSUBST: B = 1:. / *:x
    NSUBST: C = 1:. / *:x

Transporters
------------

Transporters are placed in vaults via two lua marker classes, which can be
created with the functions transp_loc(name) and transp_dest_loc(name). Here
`name' is a string shared between the transporter marker and the the
transporter destination marker. For example,

    MARKER: E = lua:transp_loc("the_bubble_entry")
    MARKER: F = lua:transp_dest_loc("the_bubble_entry")

will place a transporter on any glyph E that leads to the location of glyph F.
This form of placement works both within a vault and when the transporter and
its destination are in different vaults/subvaults, since transporters are
placed from the markers after the level is generated.

You may have multiple glyphs with the same transporter markers name, and they
will all lead to the same destination after placement. Note that it's not valid
to have multiple glyphs with the same destination marker. Any randomization of
destinations can be done through normal SUBST/NSUBST/SHUFFLE operations before
the MARKER statements.