1
2
3
4LEV_COMP(6)                   1996                    LEV_COMP(6)
5
6
7
8NAME
9     lev_comp - NetHack special levels compiler
10
11SYNOPSIS
12     lev_comp [ -w ] [ files ]
13
14     If no arguments are given, it reads standard input.
15
16DESCRIPTION
17     Lev_comp is a special level compiler for NetHack version 3.2
18     and  higher.   It  takes  description files as arguments and
19     produces level files that can be loaded by NetHack  at  run-
20     time.
21
22     The purpose of this tool is to provide  NetHack  administra-
23     tors  and implementors with a convenient way for adding spe-
24     cial levels to the game, or modifying existing ones, without
25     having to recompile the entire world.
26
27     The -w option causes lev_comp to perform extra checks on the
28     level and display extra warnings, however these warnings are
29     sometimes superfluous, so they are not normally displayed.
30
31
32GRAMMAR
33     file            : /* nothing */
34                     | levels
35                     ;
36
37     levels          : level
38                     | level levels
39                     ;
40
41     level           : maze_level
42                     | room_level
43                     ;
44
45     maze_level      : maze_def flags lev_init messages regions
46                     ;
47
48     room_level      : level_def flags lev_init messages rreg_init rooms corridors_def
49                     ;
50
51     level_def       : LEVEL_ID ':' string
52                     ;
53
54     lev_init        : /* nothing */
55                     | LEV_INIT_ID ':' CHAR ',' CHAR ',' BOOLEAN ',' BOOLEAN ',' light_state ',' walled
56                     ;
57
58     walled          : BOOLEAN
59                     | RANDOM_TYPE
60
61
62
63May                      Last change: 16                        1
64
65
66
67
68
69
70LEV_COMP(6)                   1996                    LEV_COMP(6)
71
72
73
74                     ;
75
76     flags           : /* nothing */
77                     | FLAGS_ID ':' flag_list
78                     ;
79
80     flag_list       : FLAG_TYPE ',' flag_list
81                     | FLAG_TYPE
82                     ;
83
84     messages        : /* nothing */
85                     | message messages
86                     ;
87
88     message         : MESSAGE_ID ':' STRING
89                     ;
90
91     rreg_init       : /* nothing */
92                     | rreg_init init_rreg
93                     ;
94
95     init_rreg       : RANDOM_OBJECTS_ID ':' object_list
96                     | RANDOM_MONSTERS_ID ':' monster_list
97                     ;
98
99     rooms           : /* Nothing  -  dummy room for use with INIT_MAP */
100                     | roomlist
101                     ;
102
103     roomlist        : aroom
104                     | aroom roomlist
105                     ;
106
107     corridors_def   : random_corridors
108                     | corridors
109                     ;
110
111     random_corridors: RAND_CORRIDOR_ID
112                     ;
113
114     corridors       : /* nothing */
115                     | corridors corridor
116                     ;
117
118     corridor        : CORRIDOR_ID ':' corr_spec ',' corr_spec
119                     | CORRIDOR_ID ':' corr_spec ',' INTEGER
120                     ;
121
122     corr_spec       : '(' INTEGER ',' DIRECTION ',' door_pos ')'
123                     ;
124
125     aroom           : room_def room_details
126
127
128
129May                      Last change: 16                        2
130
131
132
133
134
135
136LEV_COMP(6)                   1996                    LEV_COMP(6)
137
138
139
140                     | subroom_def room_details
141                     ;
142
143     subroom_def     : SUBROOM_ID ':' room_type ',' light_state ',' subroom_pos ',' room_size ',' string roomfill
144                     ;
145
146     room_def        : ROOM_ID ':' room_type ',' light_state ',' room_pos ',' room_align ',' room_size roomfill
147                     ;
148
149     roomfill        : /* nothing */
150                     | ',' BOOLEAN
151                     ;
152
153     room_pos        : '(' INTEGER ',' INTEGER ')'
154                     | RANDOM_TYPE
155                     ;
156
157     subroom_pos     : '(' INTEGER ',' INTEGER ')'
158                     | RANDOM_TYPE
159                     ;
160
161     room_align      : '(' h_justif ',' v_justif ')'
162                     | RANDOM_TYPE
163                     ;
164
165     room_size       : '(' INTEGER ',' INTEGER ')'
166                     | RANDOM_TYPE
167                     ;
168
169     room_details    : /* nothing */
170                     | room_details room_detail
171                     ;
172
173     room_detail     : room_name
174                     | room_chance
175                     | room_door
176                     | monster_detail
177                     | object_detail
178                     | trap_detail
179                     | altar_detail
180                     | fountain_detail
181                     | sink_detail
182                     | pool_detail
183                     | gold_detail
184                     | engraving_detail
185                     | stair_detail
186                     ;
187
188     room_name       : NAME_ID ':' string
189                     ;
190
191     room_chance     : CHANCE_ID ':' INTEGER
192
193
194
195May                      Last change: 16                        3
196
197
198
199
200
201
202LEV_COMP(6)                   1996                    LEV_COMP(6)
203
204
205
206                     ;
207
208     room_door       : DOOR_ID ':' secret ',' door_state ',' door_wall ',' door_pos
209                     ;
210
211     secret          : BOOLEAN
212                     | RANDOM_TYPE
213                     ;
214
215     door_wall       : DIRECTION
216                     | RANDOM_TYPE
217                     ;
218
219     door_pos        : INTEGER
220                     | RANDOM_TYPE
221                     ;
222
223     maze_def        : MAZE_ID ':' string ',' filling
224                     ;
225
226     filling         : CHAR
227                     | RANDOM_TYPE
228                     ;
229
230     regions         : aregion
231                     | aregion regions
232                     ;
233
234     aregion         : map_definition reg_init map_details
235                     ;
236
237     map_definition  : NOMAP_ID
238                     | map_geometry MAP_ID
239                     ;
240
241     map_geometry    : GEOMETRY_ID ':' h_justif ',' v_justif
242                     ;
243
244     h_justif        : LEFT_OR_RIGHT
245                     | CENTER
246                     ;
247
248     v_justif        : TOP_OR_BOT
249                     | CENTER
250                     ;
251
252     reg_init        : /* nothing */
253                     | reg_init init_reg
254                     ;
255
256     init_reg        : RANDOM_OBJECTS_ID ':' object_list
257                     | RANDOM_PLACES_ID ':' place_list
258
259
260
261May                      Last change: 16                        4
262
263
264
265
266
267
268LEV_COMP(6)                   1996                    LEV_COMP(6)
269
270
271
272                     | RANDOM_MONSTERS_ID ':' monster_list
273                     ;
274
275     object_list     : object
276                     | object ',' object_list
277                     ;
278
279     monster_list    : monster
280                     | monster ',' monster_list
281                     ;
282
283     place_list      : place
284                     | place ',' place_list
285                     ;
286
287     map_details     : /* nothing */
288                     | map_details map_detail
289                     ;
290
291     map_detail      : monster_detail
292                     | object_detail
293                     | door_detail
294                     | trap_detail
295                     | drawbridge_detail
296                     | region_detail
297                     | stair_region
298                     | portal_region
299                     | teleprt_region
300                     | branch_region
301                     | altar_detail
302                     | fountain_detail
303                     | mazewalk_detail
304                     | wallify_detail
305                     | ladder_detail
306                     | stair_detail
307                     | gold_detail
308                     | engraving_detail
309                     | diggable_detail
310                     | passwall_detail
311                     ;
312
313     monster_detail  : MONSTER_ID chance ':' monster_c ',' m_name ',' coordinate
314                      monster_infos
315                     ;
316
317     monster_infos   : /* nothing */
318                     | monster_infos monster_info
319                     ;
320
321     monster_info    : ',' string
322                     | ',' MON_ATTITUDE
323                     | ',' MON_ALERTNESS
324
325
326
327May                      Last change: 16                        5
328
329
330
331
332
333
334LEV_COMP(6)                   1996                    LEV_COMP(6)
335
336
337
338                     | ',' alignment
339                     | ',' MON_APPEARANCE string
340                     ;
341
342     object_detail   : OBJECT_ID object_desc
343                     | COBJECT_ID object_desc
344                     ;
345
346     object_desc     : chance ':' object_c ',' o_name ',' object_where object_infos
347                     ;
348
349     object_where    : coordinate
350                     | CONTAINED
351                     ;
352
353     object_infos    : /* nothing */
354                     | ',' curse_state ',' monster_id ',' enchantment optional_name
355                     | ',' curse_state ',' enchantment optional_name
356                     | ',' monster_id ',' enchantment optional_name
357                     ;
358
359     curse_state     : RANDOM_TYPE
360                     | CURSE_TYPE
361                     ;
362
363     monster_id      : STRING
364                     ;
365
366     enchantment     : RANDOM_TYPE
367                     | INTEGER
368                     ;
369
370     optional_name   : /* nothing */
371                     | ',' NONE
372                     | ',' STRING
373                     ;
374
375     door_detail     : DOOR_ID ':' door_state ',' coordinate
376                     ;
377
378     trap_detail     : TRAP_ID chance ':' trap_name ',' coordinate
379                     ;
380
381     drawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state
382                     ;
383
384     mazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION
385                     ;
386
387     wallify_detail  : WALLIFY_ID
388                     ;
389
390
391
392
393May                      Last change: 16                        6
394
395
396
397
398
399
400LEV_COMP(6)                   1996                    LEV_COMP(6)
401
402
403
404     ladder_detail   : LADDER_ID ':' coordinate ',' UP_OR_DOWN
405                     ;
406
407     stair_detail    : STAIR_ID ':' coordinate ',' UP_OR_DOWN
408                     ;
409
410     stair_region    : STAIR_ID ':' lev_region ',' lev_region ',' UP_OR_DOWN
411                     ;
412
413     portal_region   : PORTAL_ID ':' lev_region ',' lev_region ',' string
414                     ;
415
416     teleprt_region  : TELEPRT_ID ':' lev_region ',' lev_region teleprt_detail
417                     ;
418
419     branch_region   : BRANCH_ID ':' lev_region ',' lev_region
420                     ;
421
422     teleprt_detail  : /* empty */
423                     | ',' UP_OR_DOWN
424                     ;
425
426     lev_region      : region
427                     | LEV '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
428                     ;
429
430     fountain_detail : FOUNTAIN_ID ':' coordinate
431                     ;
432
433     sink_detail : SINK_ID ':' coordinate
434                     ;
435
436     pool_detail : POOL_ID ':' coordinate
437                     ;
438
439     diggable_detail : NON_DIGGABLE_ID ':' region
440                     ;
441
442     passwall_detail : NON_PASSWALL_ID ':' region
443                     ;
444
445     region_detail   : REGION_ID ':' region ',' light_state ',' room_type prefilled
446                     ;
447
448     altar_detail    : ALTAR_ID ':' coordinate ',' alignment ',' altar_type
449                     ;
450
451     gold_detail     : GOLD_ID ':' amount ',' coordinate
452                     ;
453
454     engraving_detail: ENGRAVING_ID ':' coordinate ',' engraving_type ',' string
455                     ;
456
457
458
459May                      Last change: 16                        7
460
461
462
463
464
465
466LEV_COMP(6)                   1996                    LEV_COMP(6)
467
468
469
470     monster_c       : monster
471                     | RANDOM_TYPE
472                     | m_register
473                     ;
474
475     object_c        : object
476                     | RANDOM_TYPE
477                     | o_register
478                     ;
479
480     m_name          : string
481                     | RANDOM_TYPE
482                     ;
483
484     o_name          : string
485                     | RANDOM_TYPE
486                     ;
487
488     trap_name       : string
489                     | RANDOM_TYPE
490                     ;
491
492     room_type       : string
493                     | RANDOM_TYPE
494                     ;
495
496     prefilled       : /* empty */
497                     | ',' FILLING
498                     | ',' FILLING ',' BOOLEAN
499                     ;
500
501     coordinate      : coord
502                     | p_register
503                     | RANDOM_TYPE
504                     ;
505
506     door_state      : DOOR_STATE
507                     | RANDOM_TYPE
508                     ;
509
510     light_state     : LIGHT_STATE
511                     | RANDOM_TYPE
512                     ;
513
514     alignment       : ALIGNMENT
515                     | a_register
516                     | RANDOM_TYPE
517                     ;
518
519     altar_type      : ALTAR_TYPE
520                     | RANDOM_TYPE
521                     ;
522
523
524
525May                      Last change: 16                        8
526
527
528
529
530
531
532LEV_COMP(6)                   1996                    LEV_COMP(6)
533
534
535
536     p_register      : P_REGISTER '[' INTEGER ']'
537                     ;
538
539     o_register      : O_REGISTER '[' INTEGER ']'
540                     ;
541
542     m_register      : M_REGISTER '[' INTEGER ']'
543                     ;
544
545     a_register      : A_REGISTER '[' INTEGER ']'
546                     ;
547
548     place           : coord
549                     ;
550
551     monster         : CHAR
552                     ;
553
554     object          : CHAR
555                     ;
556
557     string          : STRING
558                     ;
559
560     amount          : INTEGER
561                     | RANDOM_TYPE
562                     ;
563
564     chance          : /* empty */
565                     | PERCENT
566                     ;
567
568     engraving_type  : ENGRAVING_TYPE
569                     | RANDOM_TYPE
570                     ;
571
572     coord           : '(' INTEGER ',' INTEGER ')'
573                     ;
574
575     region          : '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
576                     ;
577
578     NOTE:
579     Lines beginning with '#' are considered comments.
580
581     The contents of a "MAP" description of a maze is a rectangle
582     showing  the  exact  level  map  that should be used for the
583     given part of a maze.  Each character in the map corresponds
584     to  a  location on the screen.  Different location types are
585     denoted using different  ASCII  characters.   The  following
586     characters are recognized.  To give an idea of how these are
587     used, see the EXAMPLE, below.  The maximum size of a map  is
588
589
590
591May                      Last change: 16                        9
592
593
594
595
596
597
598LEV_COMP(6)                   1996                    LEV_COMP(6)
599
600
601
602     normally 76 columns by 21 rows.
603
604     '-'     horizontal wall
605     '|'     vertical wall
606     '+'     a doorway (state is specified in a DOOR declaration)
607     'A'     open air
608     'B'     boundary room location (for bounding unwalled irregular regions)
609     'C'     cloudy air
610     'I'     ice
611     'S'     a secret door
612     'H'     a secret corridor
613     '{'     a fountain
614     '\'     a throne
615     'K'     a sink (if SINKS is defined, else a room location)
616     '}'     a part of a moat or other deep water
617     'P'     a pool
618     'L'     lava
619     'W'     water (yes, different from a pool)
620     'T'     a tree
621     'F'     iron bars
622     '#'     a corridor
623     '.'     a normal room location (unlit unless lit in a REGION declaration)
624     ' '     stone
625
626EXAMPLE
627     Here is an example of a  description  file  (a  very  simple
628     one):
629
630     MAZE : "fortress", random
631     GEOMETRY : center , center
632     MAP
633     }}}}}}}}}
634     }}}|-|}}}
635     }}|-.-|}}
636     }|-...-|}
637     }|.....|}
638     }|-...-|}
639     }}|-.-|}}
640     }}}|-|}}}
641     }}}}}}}}}
642     ENDMAP
643     MONSTER: '@', "Wizard of Yendor", (4,4)
644     OBJECT: '"', "Amulet of Yendor", (4,4)
645     # a hell hound flanking the Wiz on a random side
646     RANDOM_PLACES: (4,3), (4,5), (3,4), (5,4)
647     MONSTER: 'd', "hell hound", place[0]
648     # a chest on another random side
649     OBJECT: '(', "chest", place[1]
650     # a sack on a random side, with a diamond and maybe a ruby in it
651     CONTAINER: '(', "sack", place[2]
652     OBJECT: '*', "diamond", contained
653     OBJECT[50%]: '*', "ruby", contained
654
655
656
657May                      Last change: 16                       10
658
659
660
661
662
663
664LEV_COMP(6)                   1996                    LEV_COMP(6)
665
666
667
668     # a random dragon somewhere
669     MONSTER: 'D', random, random
670     # 3 out of 4 chance for a random trap in the EAST end
671     TRAP[75%]: random, (6,4)
672     # an electric eel below the SOUTH end
673     MONSTER: ';', "electric eel", (4,8)
674     # make the walls non-diggable
675     NON_DIGGABLE: (0,0,8,8)
676     TELEPORT_REGION: levregion(0,0,79,20), (0,0,8,8)
677
678     This example will produce a file named "fortress"  that  can
679     be integrated into one of the numerous mazes of the game.
680
681     Note especially the  final,  TELEPORT_REGION  specification.
682     This   says  that  level  teleports  or  other  non-stairway
683     arrivals on this level can land anywhere on the level except
684     the  area  of  the  map.  This shows the use of the ``levre-
685     gion'' prefix  allowed  in  certain  region  specifications.
686     Normally, regions apply only to the most recent MAP specifi-
687     cation, but when prefixed with ``levregion'', one can  refer
688     to any area of the level, regardless of the placement of the
689     current MAP in the level.
690
691AUTHOR
692     Jean-Christophe Collet, David Cohrs.
693
694SEE ALSO
695     dgn_comp(6), nethack(6)
696
697BUGS
698     Probably infinite.  Most importantly, still needs additional
699     bounds checking.
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723May                      Last change: 16                       11
724
725
726
727