DGN_COMP(6)

πŸ’– DGN_COMP(6) β€” the NetHack dungeon compiler, bestie edition πŸ’–

okay so. this is a page from the Games Manual, and it's about a lil tool called dgn_comp. sit down, hydrate, and let me tell you everything. 🫢


✨ NAME ✨

dgn_comp β€” the NetHack dungeon compiler πŸ‘‘


✨ SYNOPSIS ✨

dgn_comp [ file ]

If you don't hand it any arguments at all, bestie, it just reads from standard input. no biggie. πŸ’…


✨ DESCRIPTION ✨

So Dgn_comp is the dungeon compiler for NetHack version 3.2 and higher. You give it a description file as an argument and it spits out a dungeon "script" that NetHack loads up at runtime. iconic behavior, honestly.

The whole point of this tool? It gives NetHack administrators and implementors a convenient way to build a custom dungeon for the game without having to recompile the entire world. no full rebuild, no suffering, we love that for us. πŸŽ€


✨ GRAMMAR ✨

okay this is the part where it gets real. here's the grammar, verbatim, don't @ me:

DUNGEON: name bonesmarker ( base , rand ) [ %age ]
  • name β€” the dungeon name
  • bonesmarker β€” a letter for marking bones files
  • ( base , rand ) β€” the number of levels
  • %age β€” its percentage chance of being generated (and if it's absent, it's a 100% chance)

DESCRIPTION: tag
  • tag β€” currently one of HELLISH, MAZELIKE, or ROGUELIKE.

ALIGNMENT | LEVALIGN: [ lawful | neutral | chaotic | unaligned ]

This gives the alignment of the dungeon/level. the default is unaligned, fyi. πŸ’œ


ENTRY: level

This is the dungeon entry point. The dungeon connection attaches at this level of the given dungeon. If the value of level is negative, the entry level gets calculated from the bottom of the dungeon, with -1 being the last level. And if this line isn't present in a dungeon description at all? The entry level just defaults to 1. easy.


PROTOFILE: name

The prototypical name for dungeon level files in this dungeon. for example, the PROTOFILE name for the dungeon Vlad's Tower is tower. 🏰


LEVEL: name bonesmarker @ ( base , rand ) [ %age ]
  • name β€” the level name
  • bonesmarker β€” a letter for marking bones files
  • ( base , rand ) β€” the location
  • %age β€” the generation percentage, same as above

RNDLEVEL: name bonesmarker @ ( base , rand ) [ %age ] rndlevs
  • name β€” the level name
  • bonesmarker β€” a letter for marking bones files
  • ( base , rand ) β€” the location
  • %age β€” the generation percentage, same as above
  • rndlevs β€” the number of similar levels available to choose from

CHAINLEVEL: name bonesmarker prev_name + ( base , rand ) [ %age ]
  • name β€” the level name
  • bonesmarker β€” a letter for marking bones files
  • prev_name β€” the name of a level defined previously
  • ( base , rand ) β€” the offset from the level being chained from
  • %age β€” the generation percentage

RNDCHAINLEVEL: name bonesmarker prev_name + ( base , rand ) [ %age ]
rndlevs
  • name β€” the level name
  • bonesmarker β€” a letter for marking bones files
  • prev_name β€” the name of a level defined previously
  • ( base , rand ) β€” the offset from the level being chained from
  • %age β€” the generation percentage
  • rndlevs β€” the number of similar levels available to choose from

LEVELDESC: type
  • type β€” the level type, (see DESCRIPTION, above). The type is used to override any pre-set value used to describe the entire dungeon, for this level only.

BRANCH: name @ ( base , rand ) [ stair | no_up | no_down | portal ] [ up
| down ]
  • name β€” the name of the dungeon to branch to
  • ( base , rand ) β€” the location of the branch

The last two optional arguments are the branch type and the branch direction. The type of a branch can be a two-way stair connection, a one-way stair connection, or a magic portal. A one-way stair is described by the types no_up and no_down, which specify which stair direction is missing. The default branch type is stair. The direction for a stair can be either up or down; direction is not applicable to portals. The default direction is down. πŸšͺ


CHAINBRANCH: name prev_name + ( base , rand ) [ stair | no_up | no_down
| portal ] [ up | down ]
  • name β€” the name of the dungeon to branch to
  • prev_name β€” the name of a previously defined level
  • ( base , rand ) β€” the offset from the level being chained from

The optional branch type and direction are the same as described above. πŸ’«


✨ GENERIC RULES ✨

okay bestie, read this section twice. it's giving "rules of the universe." πŸ”₯

Each dungeon must have a unique bonesmarker, and each special level must have a bonesmarker unique within its dungeon β€” though letters may be reused in different dungeons, so no drama there. If the bonesmarker has the special value "none", no bones files will be created for that level or dungeon.

The value base may be in the range of 1 to MAXLEVEL (as defined in global.h).

The value rand may be in the range of -1 to MAXLEVEL.

If rand is -1 it will be replaced with the value (num_dunlevs(dungeon) - base) during the load process (ie. from here to the end of the dungeon). 🌈

If rand is 0 the level is located absolutely at base.

Branches don't have a probability. Dungeons do. If a dungeon fails to be generated during load, all its levels and branches are skipped. πŸ’€

⚠️ No level or branch may be chained from a level with a percentage generation probability. This is to prevent non-resolution during the load. In addition, no branch may be made from a dungeon with a percentage generation probability, for the same reason. do not test this. i'm serious. 😭

As a general rule using the dungeon compiler:

  • If a dungeon has a protofile name associated with it (eg. tower) that file will be used.
  • If a special level is present, it will override the above rule and the appropriate file will be loaded.
  • If neither of the above are present, the standard generator will take over and make a "normal" level.
  • A level alignment, if present, will override the alignment of the dungeon that it exists within.

✨ EXAMPLE ✨

Here's the current syntax of the dungeon compiler's "language", in all its glory:

#
#       The dungeon description file for the "standard" original
#       3.0 NetHack.
#
DUNGEON:        "The Dungeons of Doom" "D" (25, 5)
LEVEL:          "rogue" "none" @ (15, 4)
LEVEL:          "oracle" "none" @ (5, 7)
LEVEL:          "bigroom" "B" @ (12, 3) 15
LEVEL:          "medusa" "none" @ (20, 5)
CHAINLEVEL:     "castle" "medusa" + (1, 4)
CHAINBRANCH:    "Hell" "castle" + (0, 0) no_down
BRANCH:         "The Astral Plane" @ (1, 0) no_down up

DUNGEON:        "Hell" "H" (25, 5)
DESCRIPTION:    mazelike
DESCRIPTION:    hellish
BRANCH:         "Vlad's Tower" @ (13, 5) up
LEVEL:          "wizard" "none" @ (15, 10)
LEVEL:          "fakewiz" "A" @ (5, 5)
LEVEL:          "fakewiz" "B" @ (10, 5)
LEVEL:          "fakewiz" "C" @ (15, 5)
LEVEL:          "fakewiz" "D" @ (20, 5)
LEVEL:          "fakewiz" "E" @ (25, 5)

DUNGEON:        "Vlad's Tower" "T" (3, 0)
PROTOFILE:      "tower"
DESCRIPTION:    mazelike
ENTRY:          -1

DUNGEON:        "The Astral Plane" "A" (1, 0)
DESCRIPTION:    mazelike
PROTOFILE:      "endgame"

NOTES:
Lines beginning with '#' are considered comments.
A special level must be explicitly aligned.  The alignment of the
dungeon it is in only applies to non-special levels within that dungeon.

✨ AUTHOR ✨

M. Stephenson (from the level compiler by Jean-Christophe Collet). shoutout to the ogs 🫢


✨ SEE ALSO ✨


✨ BUGS ✨

Probably infinite. πŸ˜­πŸ’€ (that's it. that's the whole bug report. iconic.)


This file is Copyright (C) Kenneth Lorber and was last modified 2018/04/25 (version NetHack-3.6.0:1.6). NetHack may be freely redistributed. See license for details.


okay that's the whole page bestie, you're officially a dungeon compiler girlie now πŸ’…βœ¨ this was the NETHACK manual, dated 25 May 2015, filed under DGN_COMP(6). go forth and branch responsibly πŸ¦‹πŸ’–πŸŒΈ