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