A GUIDE TO MAKING NEW NETHACK LEVELS Version 1.2.2 Sept 28, 2002 Rob Ellwood rob.ellwood@shaw.ca CONTENTS 0.0 INTRODUCTION 0.1 Acknowledgements 1.0 FILES TO DOWNLOAD 1.1 The Source Code 1.2 The Utility Programs 1.3 "Nethack Sources How-To", by German Martin 2.0 BACKGROUND 2.1 Example Level Files 2.2 What Level Files Contain 2.2 The Two Types Of Levels 2.3 Map Coordinates 2.4 Example Commands 2.4.1 Example Commands for Maze-type Levels 2.4.2 Example Commands for Room-type Levels 3.0 DESIGNING LEVELS 3.1 Level Concept 3.2 Level Map 4.0 COMPILING YOUR .des FILE 4.1 Background 4.2 A Very Short Tutorial on MS-DOS 4.3 Procedure 4.4 Example error messages 5.0 TELLING NETHACK WHERE YOUR LEVEL GOES 5.1 Edit dungeon.def 5.1.1 If You Changed An Old Level 5.1.2 If You Added A Variant Of An Old Level 5.1.2.1 The old level already had more than one version 5.1.2.2 The old level had only one version 5.1.3 If You Added A New Level 5.1.4 If You Added A New Branch 5.2 Run makedefs 5.3 Run dgn_comp 6.0 ADDING YOUR LEVEL TO NETHACK 6.1 Background 6.2 Test dlb_main 6.3 Getting Ready 6.4 Procedure 6.5 Batch file for testing. 7.0 TESTING YOUR LEVEL 7.1 Errors I've seen 8.0 ADDING NEW BRANCHES 9.0 RANDOM NOTES 9.1 Tiles 9.1.1 Getting Ready to Edit Tiles 9.1.2 Changing Old Tiles 9.1.3 Adding New Tiles 9.2 Adding New Classes 10.0 TRICKS AND IDEAS 11.0 OPEN QUESTIONS APPENDIX 1: SECTION 5 OF "nethack sources how-to" APPENDIX 2: A SIMPLE .des FILE APPENDIX 3: MAZE-TYPE LEVEL TEMPLATE APPENDIX 4: ROOM-TYPE LEVEL TEMPLATE APPENDIX 5: TABLES AND LISTS 5.1 Terrain symbols 5.2 Object symbols 5.3 Monster symbols 5.4 Types of traps 5.5 Types of rooms APPENDIX 6: OPTIONS FOR THE MAP COMMANDS APPENDIX 7: COMMANDS FOR MAZE-TYPE LEVELS 7.1 Commands At The Start Of The Level 7.2 Commands For Each Map 7.2.1 Commands To Start A Map 7.2.2 Commands Defining A Map 7.2.3 Commands To End A Map 7.2.4 Vaults on Maze-type Levels. APPENDIX 8: COMMANDS FOR ROOM-TYPE LEVELS 8.1 Background For Room-type Levels 8.2 Commands At The Start Of The Level 8.3 Commands For Each Room 8.3.1 Commands To Start A Room 8.3.2 Commands Defining A Room 8.3.3 Commands To End A Room APPENDIX 9: DIFFERENCES BETWEEN MAZE- AND ROOM-TYPE LEVELS APPENDIX 10: KELLY BAILEY ON "MAZEWALK" 0.0 INTRODUCTION This file explains how to add a new level to NetHack. I want to make it easy for people who aren't computer experts to add levels. (If you can compile Nethack, you're a computer expert, OK?) I'll assume that: - You aren't a computer expert; - You haven't worked on any levels before; - You know how to edit a file; - You're using Windows (or you really are a computer expert). Warning: a lot of this was deduced. Some of my deductions will be wrong. If something doesn't work the way I say, play with it until you get it right. 0.1 Acknowledgements: o I used German Martin's "Nethack Sources How-To" to learn how to make changes to the source, including adding new levels. (German: thanks for letting me include your section 5.) o Kelly Bailey got me interested in making new levels with his new minetown and mine end levels. He can read c a lot better than me, and he filled in several blanks and fixed a couple of errors in the "commands" appendices. Thanks, Kelly. o I've got level-building info from Kelly, Dylan O'Donnell, and someone who prefers staying anonymous. And Penguin helped confirm that the GOLD command worked. o Mariusz Wojsyk sent me copies of the utility programs for the Windows version of 3.4.0. o Pasi Kallinen figured out a lot about how the level compiler works. He passed that on to me, and proofread this writeup. 1.0 FILES TO DOWNLOAD Here are the files to download, why you need them, and where to get them. 1.1 The Source Code You only need this for the existing level design files, plus a file that says which level goes where. It has tons of other files you don't need and can ignore. To get it, go to: http://nethack.org/ Search around for the downloads page. As of 2001, the source code download is at the bottom of that page. Ignore the "diffs" version; go for the 3M download of the source code. All the files are compressed into a type of ZIP file. If you double-click on the file, it will probably uncompress. (If not, get WinZip at http://www.winzip.com/ ) Everything gets put into a folder called something like "NetHack3.3.1". Rename the folder to "source". (Otherwise, your DOS window will show it as "NetHac~1".) There are instructions in the file for How To Compile Every- thing. Ignore them. You're just adding new levels, which is vastly easier. (If you decide you want to modify and compile NetHack yourself, you can get a free C compiler for MS-DOS at: http://www.delorie.com/djgpp/ There are extra zip files which you don't normally download. Find and download the file(s) with "touch" and "ls".) 1.2 The Utility Programs You need four programs to add new levels: lev_comp.exe Takes your level description file and translates it into something NetHack understands. makedefs.exe Takes a file that says where all the levels go and makes a couple of minor changes. dgn_comp.exe Takes the file with the minor changes and translates it into something NetHack understands. dlb_main.exe Takes dozens of data files and bundles them into one really big file (nhdat) for NetHack. The Official Way to get these is to compile NetHack. If you aren't a computer expert, that's a pain. Instead: o Go to the newsgroup: news:rec.games.roguelike.nethack ...and ask if someone can e-mail you their programs. Say if you want the Windows version, the DOS version, or both. o E-mail me. (April 2002: the DOS and Windows versions for 3.4.0 are at: http://members.shaw.ca/rob.ellwood/HowToChangeNethack.html ) NOTE: the version of lev_comp.exe must match the version of Nethack you're playing. o The DOS version and the Windows version are incompatible. If you use the lev_comp from one, the level won't work in the other. o If you've made a variant with extra objects or monsters, you need the version of lev_comp.exe that knows about the extra stuff. o If you're playing SLASH'EM, Nethack's lev_comp.exe does you no good at all: it has extra objects and monsters. Put all four programs into the source\dat folder. 1.3 "Nethack Sources How-To", by German Martin (Skip to the next section unless you're thinking of changing Nethack's program.) This has a section on adding levels. I included it in appendix 1. Only get the entire file if you want to modify more than just the levels. (He explains how to add new monsters, objects, room types, and shop types. He also documents some useful functions for anyone who wants to change the code.) The file name is sources.txt. As of 2001, SLASH'EM's source files include a copy, but not NetHack's. Try these sites: http://www.lab3.kuis.kyoto-u.ac.jp/members/aoki/nethack/files/Tips/sources.gui http://avrc.city.ac.uk/nethack/slashem/slashem-0.0.5E7F1/sources.txt ...or do a web search, or ask on the newsgroup. 2.0 BACKGROUND Appendix 1 has section 5 of "nethack sources how-to", by German Martin. He outlines how to build new levels, but he does not go into the full details. That's what I do, here. Please skim Appendix 1 now. I don't re-explain things that he goes into. 2.1 Example Level Files Go to where you unzipped the NetHack source files. Look in the \dat folder. The .des files are the level design files. When you want to do something, try to remember a level which does the same thing. You can then pull up the .des file and see how it's done. Here are some example file names: - Arch.des: all the archeologist quest levels. - Gehennom.des: the gehennom levels. - Mines.des: the minetown and mine end levels, plus the "filler" levels (= the random levels you get between the designed levels). 2.2 What Level Files Contain Inside the files, you'll see a long section for each level being defined. (Most files define several levels.) For each level, you'll see: - A few comments, starting with "#". - A line naming the level, and saying what "type" of level it is. (I'll explain the two types later.) - You'll often see a map of the level, with different letters representing walls, secret doors, and whatnot. - Commands describing each and every area inside the level: where it is, what it is, and whether it is lit or unlit. - Commands describing each and every object or monster inside the level: where it is, what it is, and some other odds and ends. Appendix 2 has a short example .des file. Have a look. 2.2 The Two Types Of Levels There are two different types of levels. A lot of commands only work for one type or the other. You have to keep an eye on this. It's painful having to redo your .des file because you used the wrong commands. The two types of levels are "room" and "maze". ("Maze" should really be called something else. Maze-type levels are more than just the Gehennom maze levels, which is what everyone will think of.) The key difference is that maze levels have those maps with all the letters. This is an easy way to build a lot of the level. Meanwhile, room-type levels do not have a map, and you have to carefully explain where each and every wall, door, and corridor goes. 2.3 Map Coordinates Before I forget: the coordinates used are a bit strange. The square in the upper left corner is (0,0). I keep thinking of it as (1,1). (40,0) is about half-way across the screen: good. But (0,10) is 10 squares BELOW (0,0). My brain insists that it is 10 squares above. I've set up templates for level maps. They make the map co- ordinates easier to deal with. 2.4 Example Commands When you're designing a level, you have to specify things like: where a shop is, that the shop is lit, and that the shop is part of a bigger room called "town". Don't bother memorizing commands. Once you've decided what to add, look up how to do it. All the reference material is in the appendices. 2.4.1 Example Commands for Maze-type Levels Maze-type levels are easier to build. I'm trying to push you towards maze-type levels. Here are a few examples. When you need the full details, go to appendix 6 ("Options for the Map Commands") and 7 ("Commands for Maze-type Levels"). You specify a lot of the details with "region" commands: REGION:(19,02,27,08),lit,"armor shop" The command starts by giving the two corners of the region: at (19,02) and (27,08). It's a big room: 9 squares by 7. This entire region is lit. And the entire region is an armor shop. It will automatically be given a shopkeeper, things to sell, and maybe some mimics. The two main uses of regions are making special rooms and making areas lit or unlit (which you do for several rooms at once, or even the entire level). OBJECT:'*',"amethyst",(21,08) OBJECT:'*',random,(21,08) In Nethack 3.3.1, one of the possible levels at the bottom of the mines had a heap of jewels behind two secret doors. This puts an amethyst and a random jewel (or rock) onto the heap. # The treasure of Shaman Karnov OBJECT:'(',"chest",(34,02) Comments start with "#". A '(' object is a tool. When you place a tool, scroll, or whatever, you have to say what symbol that type of object uses. Appendix 5 lists the symbols. OBJECT:random,random,random A random type of object, then a random item of that type, put in a random location. Generic loot. MONSTER:'D',"Chromatic Dragon",(23,10),asleep Appendix 1 shows that all dragons use 'D', even baby dragons. Hey, you can specify asleep! I can use that. TRAP:"pit",(57,10) A pit trap goes at a particular location. TRAP:random,random A trap of a random type goes to a random location. 2.4.2 Example Commands for Room-type Levels Room-type levels are harder to build. I'm trying to steer you away from room-type levels. These are just examples. When you need the full details, go to appendix 8 ("Commands for Room-type Levels"). Room-type levels can have either a bunch of rooms connected by random corridors, or one big area, which you then fill with whatever you want, or both. Here's how minetown-1's central area is defined: ROOM: "ordinary" , lit, (3,3), (center,center), (31,15) NAME: "town" o "ordinary": this is just an ordinary type of room. o "lit": all of the room is lit, unless you say otherwise for a subroom. o "(3,3)": this roughly positions the ROOM on the level. Imagine a 5x5 grid laid out over a level. The upper left corner is (1,1). The lower right corner is (5,5). Here, (3,3) is the middle of the screen. o "(center,center)": the ROOM is centered at the (3,3) spot on the 5x5 grid. I expect that "(1,1), (left, upper)" gives you a room jammed into the upper left corner of the level. o "(31,15)": the room is 31 squares by 15. o "town": this doesn't matter to the player. Instead, it lets the level designer refer to this ROOM as "town" when he's adding SUBROOMs. This room is the area that the entire minetown fits into. The minetown shops are added with "subroom" commands (subroom = a room that fits inside a bigger room). You specify a lot of the details with "room" commands. (Or "subroom" commands, which are basically the same.) Each "room" command is followed by a list of commands which apply to that par- ticular room. Here's the general store in the upper left corner of minetown-1: SUBROOM: "shop" , lit, (2,2), (3,4), "town" CHANCE: 90 DOOR: false, closed, south, random OK, it's a shop (= general store). It is lit. It starts at location (02,02). (This is its location inside the minetown area, not its location inside the level.) It extends for three squares to the right and four squares down. It goes inside the room called "town". Whenever Nethack creates this level, there's a 90% chance that this subroom will be a shop. The other 10% of the time, it's an empty, ordinary room. The DOOR command says that the door is... is what? Appendix 8, "Commands for Room-type Levels", explains: | DOOR: [secret], [door state], [which wall], [door location] | | Secret: true or false. | Door state: open, closed, locked, nodoor, broken, or random. | Direction: north, east, south, or west. | Door location: this is where along the wall the door goes. So, the shop's door isn't secret, it starts off closed, it is on the south wall of the shop, and it goes on some random square along that wall. SUBROOM: "temple", lit, (15,9), (4,4), "town" DOOR: false, closed, north, random ALTAR:(02,02),random,shrine MONSTER: 'G', "gnomish wizard", random MONSTER: 'G', "gnomish wizard", random This is in the minetown again (with one confusing part changed). Going to appendix 8, I see that the altar is a random alignment. "Shrine" means that there is a priest in attendance. Two gnomish wizards start right there in the temple. 'G' is the symbol for gnomish wizards. (See appendix 1 for what letters to use for each type of monster.) "random" means a random location in this subroom. In contrast, for a maze-type level, saying "random" for a monster means it is placed anywhere on the level: MONSTER: '@', "watchman", random, peaceful For a maze-type level, this puts a peaceful watchman at a random location on the level. If you leave off "peaceful", you get the normal NetHack behaviour: almost everything is hostile. (Anyone for peaceful mind flayers?) 3.0 DESIGNING LEVELS 3.1 Level Concept I really think that, to be good, a level has to have "flavor". It has to be unique and memorable. A minetown with everything the same, only re-arranged to different locations, is not memorable. The generic dungeon levels are all unique, but are not at all memor- able. Suggestion: have a theme. One of my levels has the theme "a minetown which has been taken over by the Wizard of Yendor's troops". The normal inhabitants are gone, there are soldiers everywhere, and the shops have been replaced by armories and a mess hall. Write down six or twelve interesting ideas before you start work. You'll throw some of them out when you build the level. In any case, I don't expect anyone to ever complain that a level is too interesting, and could you make it more boring, please. I also suggest signing your work in some distinctive way. Maybe even have a trademark. For one level, I was thinking of having a doorless 1x1 room with the corpse of a dwarf (I'm an engineer; a dwarf seems closest). Engraved in the floor (in blood if possible) will be "Rob did this". Another level will have the statue of a dwarf king, with the engraving "King Rob". This sort of thing adds flavor, which gives a more interesting level. Think of ways to add flavor to your level. (The Juiblex level has an island in the shape of a skull, with potions for the teeth. You did notice this, right?) Rough out the level on a sheet of paper. Don't bother showing walls and corridors. Just put words in the right relative locations: "lava flow", "art gallery", "ambush", and so on. (Doing this will give you an early warning of space problems. If your drawing has "King Rob statue" in the center, but your map has it nearly off the screen, stop and think.) I suggest glancing at the first table in appendix 5, just to see if there are any terrain types you didn't know about. Then skim appendices 6 and 7. Don't bother trying to learn the commands. Instead: - Can you do everything you want to do in a maze-type level? - If not, skim appendix 8. Can you do it in a room-type level? - Some commands have special options. Do any of these give you new ideas for your level? 3.2 Level Map What existing .des file does your map belong in? (If you're adding a completely new branch, make a completely new .des file.) Make a backup copy of the .des file, just in case. Edit the file. Windows won't know what to do with .des files. Tell it to open the file using whatever editor you favor. Use Wordpad if you don't know which editor is best. Appendices 3 and 4 have templates for maze-type and room-type levels. Copy and paste a template over to the end of your .des file. I included a blank map in the room-type template, even though room-type levels don't allow maps. Like I said, I really think you need a map to keep track of everything. I found that counting squares was a pain, and it was very easy to make mistakes. So, I added number lines at the top and bottom. The "#" at the start of the number lines makes them comments (but don't put comments in the MAP to ENDMAP section, where "#" means a corridor). As of 3.4.0, the level compiler lets you put *one* digit right at the start of a line in a MAP. This makes it easy to find out the line number. (Your editor probably uses a fixed-width font. If not, use one, or nothing will line up.) "." means "normal floor". You'll have to change a lot of that to wall ("-" and "|") or solid rock (spaces: " "). (If you add ten spaces worth of solid rock, you'll then have to delete 10 spaces of floor. Hint: get out of "insert" mode when you're changing letters on the map. Return to "insert" mode when you're doing anything else. The INSERT key changes which mode you're in.) 4.0 COMPILING YOUR .des FILE From here on down, it's like threading a dozen needles. It's a bit finicky, some steps can take more than one try, and you need a bit of patience to finish. But, you will finish. 4.1 Background A special program takes a .des file and makes a .lev file for each level. The .lev files describe the levels in a way that the main NetHack program can understand easily. So, step 1 is: run the special program and get back a .lev file. 4.2 A Very Short Tutorial on MS-DOS Lesson 1: starting MS-DOS. Somewhere in your START menu there will be an option called "MS-DOS prompt". For Windows ME, it's under PROGRAMS, then ACCESS- ORIES. Click on that. You'll get a black DOS window, or maybe DOS will take over the entire screen. You have finished lesson 1. (You can issue DOS commands when you're in that window. If DOS took over the entire screen, ALT-TAB gets you back to Windows.) Lesson 2: finding out what directory you're in. DOS looks at only one (1) directory (= folder) at a time. Your DOS window will start in the wrong directory. Look for the cursor. That line probably starts with "C:\windows> ". OK, you're on C drive and you're in the WINDOWS directory. Continue to lesson 3. If you see "C:\[some other directory]", continue to lesson 3. If you just have "C>", then type in: prompt $p$g ...and hit enter. (This tells DOS to start each line with the dir- ectory name. Note: once you close the DOS window, DOS will forget you ever said this. Enter the command every session.) Lesson 3: changing directories and listing files. Type these commands in (but without the notes I put on each line). In the example, I pretend that the directory with the source files is C:\games\nethack\source cd .. (".." moves you up one directory. Are you at C:\ ?) cd .. (Repeat this until you get up to C:\ , OK?) cd games (or whatever directory has the NetHack source files.) cd nethack (or whatever the next directory down is called.) cd source (or NetHac~1 or whatever. Are we there yet?) dir *.* (lists all files.) dir /A:d (lists directories inside the current directory.) cd dat (There should be a directory called dat. Honest.) dir *.des (lists about 25 .des files.) dir *.lev (lists the .lev files. There are none, right?) You have finished lesson 3. (On my system, pushing the up-arrow brings earlier commands back to the screen. I can change 'em and enter 'em again. This saves on typing. Dunno if it will work for you.) Lesson 4: leaving MS-DOS To close the MS_DOS window, enter the command: EXIT You may as well leave your window open for now. 4.3 Procedure I haven't told you much about using DOS. Have the \dat folder open in a normal window. You can do most things in the normal win- dow, where it's easier. Required files: In section 1.2, I listed four utility programs you need. If they aren't in the \dat directory, please download copies and put them there. Test run: If you've closed your MS-DOS window, open another one and move to the \dat directory. Let's use lev_comp.exe on a file that you haven't modified. This will show you how to use, and also confirm that it works. Enter the command: lev_comp barb.des lev_comp will finish nearly instantly. A file called barb.lev should appear. If it did, then you've got it working. (If you already had the .lev files around, enter the command: dir bar*.lev If the file's date is one minute ago, it worked.) Real run: If your .des file is, say, gehennom, then enter the command: lev_comp gehennom.des ...and you'll get 1-100 errors messages. Computers are very picky. For every character you got wrong, you'll get an error message. If I can't make a .des file without lots of error messages, neither can you. Fortunately, most errors are very easy to fix. You used a ';' instead of a ':'? Change one character: done. 4.4 Example error messages These are from the the first minetown I built. On the first try, I only got one error message before lev_comp gave up: line 13 : syntax error. I look at line 13. It's the first line of the MAP. Remember how the MAP template has the row numbers at the end of each line? I forgot to take those out. Oops. I fix that and try again. This time lev_comp gets further: line 43 : WARNING : Monster placed in wall at (06,03)?! line 45 : WARNING : Monster placed in wall at (06,17)?! line 48 : WARNING : Illegal object name! Making random object. line 48 : WARNING : Object placed in wall at (06,03)?! line 49 : WARNING : Illegal object name! Making random object. line 50 : WARNING : Illegal object name! Making random object. line 50 : WARNING : Object placed in wall at (06,17)?! line 51 : WARNING : Illegal object name! Making random object. line 58 : WARNING : Illegal object name! Making random object. line 85 : WARNING : Illegal object name! Making random object. line 86 : WARNING : Illegal object name! Making random object. line 87 : WARNING : Illegal object name! Making random object. line 88 : WARNING : Illegal object name! Making random object. line 122 : syntax error Things are placed inside walls? (I check my map.) Those squares are actually open doors. But, if lev_comp doesn't like it, OK: I'll move those things a bit. (Note that these aren't errors, just warnings: "this looks wrong". I should still fix them, though, or everyone who compiles this file later will see the warnings and figure that the file is no good.) The first "illegal object name" error is for this command: OBJECT: '!', "potion of invisibility", (06,03) Let's see: it's spelled correctly. Is '!' the right symbol for a potion? (I check appendix 5.) Yes. When you're wishing for artifacts, you have to get the capital- ization correct for at least some items. Does 'potion' need to be capitalized? Do I even need to say "potion of" after I've specified the symbol? Yes, that's probably it. Vlad's tower has several non-random items, like an amulet of life saving. Does it say "amulet of life saving" or just "life saving"? (I check tower.des.) It says "amulet of life saving". So much for that theory. And it isn't capitalized, either. ...I want to double check that. I can't think of anything else that would cause the problem. One of the tourist levels has two scrolls of blank paper. (I check tourist.des.) Ha! They just say "blank paper"! You don't have to specify "scroll of" or "potion of" after you give the object's symbol. I also get warnings when I say how many items I want: OBJECT: '(', "7 wax candles", (16,18) This is no big deal: I'll ask for the candles one at a time. [I found that I got a random number of candles, seven times over, for a total of 21 candles.] So all those warnings are really just two problems: not knowing that things shouldn't start in doorways, and not knowing exactly how to specify objects. I don't know where the last error is. WordPad doesn't display line numbers. I know where line 88 is, so I count down from there. OBJECT: '%', "corpse", (09,10), "watchman" This looks OK. The Valley of the Dead has some corpses; what does it show? (I check gehennom.des.) OBJECT: '%', "corpse", random, "barbarian", 0 The only difference is the ", 0" at the end. What's that for? (I check the OBJECT command in appendix 7.) I said the corpse was specifically a watchman. This is one of the special options. And, "if you use any of [the special options], you must give the enchant- ment". OK, no problem: I'll add ", 0" at the end of the corpse- placing commands. I try again, and get another mystery message: line 138 : syntax error I counted down 16 lines from the watchman corpse command at line 122: OBJECT: '(', random, (26,03) This looks fine. (I closely compare it to the OBJECT command just above it.) This is fine. What's the problem? Oops: the original file tried to place several objects with just one command. I had to split that up, which added nine extra lines. I should really count down 7 lines from the watchman corpse command. Trying again: REGION: (20,03, 26,07), "armor shop" Should "armor shop" really just be "armor"? (I check the list of room types.) "armor shop" is fine. Does the REGION command use (a,b) (c,d) instead of (a,b,c,d)? (I check appendix 7.) No. Here's a side-by-side comparison of my command with one of my example commands from the appendix: REGION: (20,03, 26,07), "armor shop" REGION: (25,04, 28,07), lit, "temple" There's the problem: I have to say if the region is lit or not. I fix it and try again. And this time, lev_comp finishes without any messages. I see five new .lev files for the minetown and mine-end levels: good. That wasn't nearly as bad as I thought it would be. 5.0 TELLING NETHACK WHERE YOUR LEVEL GOES 5.1 Edit dungeon.def The file to change is \dat\dungeon.def. The documentation is in \doc\dgn_comp.txt. You do different things for different changes: 5.1.1 If You Changed An Old Level No problem: NetHack already knows where that level goes. Jump ahead to section 6. 5.1.2 If You Added A Variant Of An Old Level There are multiple versions of the minetown and mine end levels. To have multiple versions of a level, have a command like: RNDLEVEL: [level name prototype] [1st letter of bones files] '@' '(' [earliest level] [range of levels it can be on] ')' [optional: % chance it shows up] [number of versions] RNDLEVEL: "minetn" "T" @ (3, 2) 9 I'm not going to fully explain this. (I think I've left out some options, anyway.) Instead, see doc\dgn_comp.txt. It's relatively good. I just want to document how the file names work: The "9" at the end is how many versions there are. "minetn" is the first part of the level names. NetHack adds a dash, then numbers from 1 to [number of versions]. This means the individual levels must be named "minetn-1" to "minetn-9". The level name prototype can only be 6 characters long. 5, if you want to allow 10-99 versions. 5.1.2.1 The old level already had more than one version If you're adding a fifth version of a level which already has four versions, find the RNDLEVEL line and change the "4" at the end to a "5". 5.1.2.2 The old level had only one version If you're taking a level which only has one version now and giving it more, replace the existing LEVEL command with RNDLEVEL and add the number of versions at the end of the line. Example if I make two new versions of the juiblex level: LEVEL: "juiblex" "J" @ (4, 4) becomes: RNDLEVEL: "juiblx" "J" @ (4, 4) 3 The level name prototype can now only be 6 letters long, so I changed "juiblex" to "juiblx". Also, in the .des file, I have to change the name of the original level from "juiblex" to "juiblx-1". My two new levels will be "juiblx-2" and "juiblx-3". 5.1.3 If You Added A New Level LEVEL: [level name prototype] [special letter of bones files] '@' '(' [earliest level] [range of levels it can be on] ')' ...or RNDLEVEL if you already have more than one version of your new level. The special level for bones files must be unique for the dungeon that the level belongs in. As of 3.4.0, the main dungeon uses "R", "O", and "B". 5.1.4 If You Added A New Branch A branch is a complete set of levels. The Gnomish Mines is a branch. The quest levels are branches. I haven't done this, so I don't have a procedure. Section 8 explains some bits that I've learned. 5.2 Run makedefs Background: makedefs.exe does about ten different things involving data files. We only want to do one thing: make a file called dungeon.pdf from our dungeon.def file. Open a DOS window. Go to the \dat folder. Enter this command: makedefs -e ...and you should now have a new dungeon.pdf file. (If your folder isn't named \dat, you get an error message: "../dat/dungeon.def: No such file or directory (ENOENT)" ) 5.3 Run dgn_comp Background: dgn_comp.exe translates the dungeon.pdf file into something that NetHack can understand. Open a DOS window. Go to the \dat folder. Enter this command: dgn_comp dungeon.pdf ...and you should get a new dungeon file: a file called "dungeon" with no extension. 6.0 ADDING YOUR LEVEL TO NETHACK 6.1 Background There are a lot of .lev files. The quests alone have 50+ files. There are also a few other data files floating around. They used to be all separate, in the same folder as nethack.exe. This cluttered up the folder. Nowadays, the files are lumped together into one big file called "nhdat". So, the next step is: put any data files you've changed or added into "nhdat". dlb_main is the "data librarian". It can reach into the big nhdat file and make whatever changes you need. (dlb_main is called dlb in the documentation, which seems to be its name under Unix.) There's a writeup for dlb in the \doc folder. Read it if this procedure is flawed or unclear. 6.2 Test dlb_main The "nhdat" file is in whatever folder you play NetHack out of. (The source code doesn't include a copy.) Put a copy over in the \dat folder. Open a DOS window. Move to the \dat folder. Type in the command: dlb_main tv Several screens of information should flash by. The last screen should show the names of some of the files in the \dat folder. The very last line should look something like: Revision:1 File count:129 String size:1667 If you get something close to this, continue to the next step. (If there's a problem, confirm that your current folder has both dlb_main.exe and nhdat, and that you entered the command correctly.) 6.3 Getting Ready Background: the data librarian needs a file DLB.LST, which lists all of the files stored in nhdat. An old DLB.LST is no good, because you've probably added levels, which adds new .lev files. This setup procedure creates a new DLB.LST file. Once you've done this step, you only have to repeat it if you add a new level to a .des file (which lev_comp turns into a new .lev file). 1. Create a new folder under \dat called dlb. (If you already have it, delete everything in it, just to be safe.) 2. Copy nhdat and dlb_main.exe to the new folder. 3. Go into the new folder and enter this command: dlb_main x About 100 files will show up. (Your windows folder won't show them until you use View Refresh.) 4. Copy your new .lev files into the new folder. You'll have one new .lev file for every level you added. 5. Delete nhdat and dlb_main.exe from the new folder. 6. Enter this command: dir /b > ..\DLB.LST Confirm that the \dat folder now have a DLB.LST file. 7. Copy DLB.LST and dlb_main.exe to the new folder. 6.4 Procedure 1. If you've created any new levels since you did the "getting ready" procedure in section 6.3, then go back to 6.3 and do it again. 2. You probably changed dungeon.def back in section 5. If so, then copy your new dungeon file into the \dlb folder. (That file is "dungeon", without a filename extension.) 3. Copy any new or changed .lev files into the \dlb folder. (Reminder: every level you worked on gets a .lev file. If you worked on three levels in the same .des file, you will have three .lev files to copy, not just one.) 4. Enter this command: dlb_main cI DLB.LST Confirm that you have a nhdat file with today's date. It should be a bit over half a megabyte. 4. Copy the new nhdat file over to whatever directory you play Nethack out of. 6.5 Batch file for testing. Kelly Bailey had the idea of putting new levels into oracle.des. That way, you can start playing in wiz mode, teleport down to the oracle level, and see the new level quickly. This saves time, espec- ially if the new level is just one version of several for a level. Here's a batch file I wrote to automate compiling and testing a new level. I have the batch file pause at places where errors might show up. Create a new text file, change the name to MakeMyLev.bat, and enter the following: del oracle.des copy my_lev.des oracle.des lev_comp oracle.des pause del dlb\oracle.lev copy oracle.lev dlb\oracle.lev cd dlb dlb_main cI DLB.LST pause del c:\nethack\source\nethack\nhdat copy nhdat c:\nethack\source\nethack\nhdat *Always* edit the my_lev.des file. The oracle.des file will be overwritten sooner or later. Suggestions: rename oracle.des to oracle.old before starting. Name your test file my_lev.des. I play nethack out of the c:\nethack\source\nethack\ folder; change the batch file to use wherever you keep nethack. Keep a backup copy of your file on a floppy, and update it every time you save your .des file. 7.0 TESTING YOUR LEVEL Open a DOS window. Go to the directory that you play Nethack out of. Type in this command: nethack -uwizard -D You are now in Wizard mode. CTRL-W lets you wish for items. CTRL-T lets you level teleport. CTRL-O tells you where all the levels are. To see all the wiz-mode commands, push "?" and select the last option on the help screen. You have to get your character to the point that he can explore your level safely. CTRL-W to wish for 20 blessed potions of gain level, blessed +10 gray dragon scale mail, and whatever else you need. Equip up and teleport down. You'll probably see half a dozen minor errors. Make notes about what to fix, #quit, and go back to the .des file. Change it, use lev_comp, then jump directly to step 3 of section 6.4. If you fix up your .des file, come back, and the errors are still there, you probably forgot one of these steps: o Run lev_comp. If there are errors, fix them and try again. o Copy the new .lev file to \dlb. o Enter dlb_main c to get a new nhdat file. o Copy nhdat to your Nethack directory. ...or, if you're using the batch file for the first time, there's a mistake there. 7.1 Errors I've seen Skip this section until you're trying to compile your level. I should dump this into an appendix. Compile errors: Case matters. "DOOR:" works; "door:" doesn't. lev_comp says "syntax error", if I recall correctly. "Map too large": I got this for a map where one of the lines had some extra " " at the end. The cause of the problem wasn't obvious. "Syntax error" when you use double quotes instead of single quotes when specifying an object or monster. Use '@', not "@". Compilers give error messages when they first realize that there's an error. This isn't always where the error is. I got a "parse error" for line 66 once. The actual error was on the previous command: I left a comma at the end of the line. OBJECT: '$', "gold", random is rejected. OBJECT: '$', random, random works. How the level looks: For levels that are partly lit and partly unlit, you'll often see little bits of wall that are lit when they should be dark, or vice versa. Fix: go to your REGION command, where you say "lit" or "unlit". Make it big enough to include the walls, as well as the floor of the room. A shop was always "this shop appears to be deserted", with no shopkeeper or inventory. Problem: I didn't include a DOOR: command for the shop door. 8.0 ADDING NEW BRANCHES I have not studied how to add new branches of levels. I will not document dgn_comp. German Martin's writeup has a section. For me, the hard part is figuring out how the related map commands work. See PORTAL, STAIRS, and TELEPORT in appendix 7. \include\decl.h defines names for levels and branches. Best guess: this only matters for wizard mode; you have to compile all of Nethack to get it to work properly. \src\dungeon.c has some sort of "level map" built in. 9.0 RANDOM NOTES I'm including brief writeups on some other things I've figured out. This is mostly for my own reference. If you decide to make other types of changes to NetHack, check these notes. Otherwise, ignore them completely. If I start making other changes myself, I'll likely go into another documentation frenzy. 9.1 Tiles This section assumes that you're adding new monsters or objects to Nethack. That requires editing the source code and recompiling. Recompiling updates the tiles, so I have not looked for a shortcut method of updating just the tiles. See also source\win\share\tile.doc Unfortunately, the author casually assumes that you have several more clues than I do. New monsters and objects need new tiles. There are a few programs around to help you. I used TileScan and TileEdit. I have not looked at the "Draw It Yourself" kit, available at: http://www.geocities.co.jp/SiliconValley-SanJose/9606/nh/eng.html WinZip complained that it was not a valid archive. 9.1.1 Getting Ready to Edit Tiles Go to: http://www.nethack.de/ Go to the "programs" section. Download tileedit and tilescan. Create a new folder called TileEdit. (I don't want to edit the "official" tiles.) Unzip tileedit into it. Unzip tilescan into TileEdit\Win\Share\ Go to wherever you keep the NetHack source code. Go into the directory \Win\Share. The files OBJECTS.TXT, MONSTERS.TXT, and OTHER.TXT contain the tile definitions. (I'll call these the "tile files".) TileEdit has out-of-date copies of the tile files. Copy and paste OBJECTS.TXT, MONSTERS.TXT, and OTHER.TXT over to the TileEdit\Win\Share folder. Overwrite the out-of-date tile files there. Next, go to the TileEdit\Win\Share folder. Use copy-and-paste to make backup copies of all three files. Rename "copy of OBJECTS.TXT" to "OBJECTS", and the same for the other two. (If you make a mistake, the file RESTORE.BAT can now restore the original tile files. You can then copy these to the "official" tile files, since you've probably messed those up, too.) Double-click on TileScan.EXE. You will probably get the error message "Cannot find VBRUN300.DLL". Your system probably has several copies of VBRUN300.DLL in other folders. Find one and copy it in. (If you don't have a copy on your system, search the internet for a copy or ask a friend.) Start TileScan again. If it works, go to the upper left corner and select a tile file: objects, monsters, or other. Two random tiles will be shown. There are pull-down menus for selecting which tile you want to look at. NOTE: if you move to another window and back to TileScan, TileScan's tiles go to blank white. Click on the "Refresh" button to get the tiles back. Create a shortcut to TileScan and put it in some convenient spot. Documentation: there are readme files for both programs. Also see \win\share\tile.doc. (Put a copy in the \doc folder.) I hope that this writeup is good enough that you can ignore these other documents. 9.1.2 Changing Old Tiles Start TileScan. Select the tile you want to change. Double- click on the image of the tile. TileEdit will start up. Where it says "colors", there are 16 little colored squares. Click on, say, red. If you now left-click on one of your tile's "pixels", it will turn red. (Right-clicking sets pixels to the background color.) Click on "save" if you're satisfied with your changes. Or click on "exit" if you were just playing around. And click on "refresh" if the tile ever changes to blank white. 9.1.3 Adding New Tiles Pick a tile that's reasonably close to what you want. Go into TileEdit\Win\Share. Edit the appropriate tile file (OBJECTS.TXT or whatever). Find the tile. Copy and paste to make a second copy of that tile. (Don't put the copy at the end of the file. Tile- Edit gave an error message when I did this.) Rename the copy to whatever your tile should be called. If the very last tile in the file is number, say, 432, make your tile number 433. (And later tiles 434, 435....) Save it when you're done. If you're happy, copy your modi- fied file tile over to the \win\share\ folder in the source code. Adding a new tile is part of adding new objects or monsters. Your new code should be inside an #ifdef. If it is, then do this procedure, too: Go to your source code folder, then into \win\share. Edit tilemap.c. In the "struct conditionals", add a "#ifndef" line like this: #ifndef KOPS { OBJ_GLYPH, CLUB, "rubber hose" }, #endif OBJ_GLYPH means "the tile of an object". "Rubber hose" is the tile which should be ignored if KOPS aren't being used. CLUB is an object tile that sorta looks like a rubber hose. (I don't know why this is needed.) To update the tiles, compile Nethack. Remarks about what tile.doc says: - tile.doc says that you can re-use an existing tile number. DON'T. NetHack doesn't mind, but TileEdit will change BOTH tiles with that number when you edit either one. - tile.doc explains how to resequence all the tiles. This lets you keep all the related tiles together. I'm not doing this. It's extra work. I don't see a benefit. And I plan on distri- buting my changes via a "patch file". If all the tile numbers change, it will make my patch file a lot bigger. 9.2 Adding New Classes Adding a new class might take 40 hours of work. Less for professional programmers, more if you have no coding skills. First, though, note that the Dev Team doesn't like classes that aren't clearly differentiated from the other classes. Steps: - Get and install a C compiler. http://www.delorie.com/djgpp/ has DJGPP for DOS, which is free. - Download and compile the NetHack source code. http://www.nethack.org/ - Make up the quest levels. - [Dylan O'Donnell:] "Also, make up the Quest text. Messages for every circumstance of interaction between you and your Quest Leader and Nemesis, etc. There's 49 of these." - Modify some data files. (See German Martin's writeup. New object: the quest artifact. New monsters: quest nemesis, leader, and the leader's toadies. Dylan: "And a new monster for the new class itself.".) Darshan Shaligram: [Some classes get one particular artifact as their guaranteed "first sacrifice gift". This is done in] "...the artifact definition, where you specify the class the artifact is associated with. Look at the declaration for Magicbane, for instance:" A("Magicbane", ATHAME, (SPFX_RESTR|SPFX_ATTK|SPFX_DEFN), 0, 0, STUN(3,4), DFNS(AD_MAGM), NO_CARY, 0, A_NEUTRAL, PM_WIZARD, NON_PM ), ^^^^^^^^^ Wizards gets this as their first gift. - Modify the source code as required. (Add code for the quest artifact. Add YAFMs and abilities unique to your class.) Dylan: "Once you've added the structure in role.c, the 'select class' menu should handle itself, provided there's no more than two classes starting with the same letter. There's lots more to be done, though; all the class-specific u_init.c stuff, attrib.c... go around looking for Role_switches. And that's just things you need to do for _every_ class, not the fun stuff you want to add to make your new class individually interesting." - Add tiles. - Dylan: "'Add documentation'; the new class needs a write-up in the Guidebook, and preferably in the database as well." - Make up a diff file. If possible, make up a DOS binary. Distribute them via webpage. If you can cover most of the above, you can ask for volun- teers to do the rest. For example, I might do the quest levels. At least two people in the group know how to make tiles. 10.0 TRICKS AND IDEAS Randomly placing doors: On the MAP, do not put "+" at the potential door locations. Leave them as solid wall: "-" or "|". Next, to place one door: RANDOM_PLACES: (all),(the),(potential),(door),(locations) DOOR: closed, place[0] RANDOM_PLACES can only be used once per MAP, but there's a way around that: Using RANDOM_PLACES more than once: If you're part-way through a level, and suddenly want to have a second list of RANDOM_PLACES, add a second MAP. Make it identical to the first MAP. Give it its own RANDOM_PLACES. Example: GEOMETRY:center,center MAP -------------- - - + - - ---------- - - - + - + ---------- + - - + - - ---------- - - - + - -------------- ENDMAP RANDOM_PLACES:(03,01),(03,03),(03,05),(03,07) OBJECT:'(',"chest",place[0] GEOMETRY:center,center MAP -------------- - - + - - ---------- - - - + - + ---------- + - - + - - ---------- - - - + - -------------- ENDMAP RANDOM_PLACES:(02,01),(02,03),(02,05),(02,07) DOOR:locked,place[0] Note that if the two MAPs differ, the last MAP is the one that goes in. On the other hand, the things you add with commands like OBJECT: and DOOR: accumulate. Anonymous contributer: | | You could also blank out (' ') any space that you don't want any | stuff on and let objects be placed randomly, in each map, with | the final one the 'real' map, but that way you might get more | than one item on any place, and you have to make sure that the | last map is the final version. | | You can also randomly place stuff in lava with that (I guess in | water too), first a map with only '.' where the lava will later | be, the rest filled with ' ' and the randomly objects placed in | that map, and then later the actual map covers the items (rocks | seem to get lost in the lava, though). Note that we're limited to 10 MAPs per level. Randomly placing rock: John Harris: > > ...this thing with the doors, is it possible to do > the same thing with walls, that is, specify where single > walls or rock should go, according to the places on the > RANDOM_PLACES list? Me: I don't see how to do it directly. Try the reverse: put walls everywhere, then put broken doors at the places that you don't want walls. Drawbacks: o RANDOM_PLACES only allows 10 locations per list (although trickery gives us up to 10 lists per level). o Having a path of broken doors looks a wee bit odd. Placing MAPs beside each other: Me: > > The Asmodeus level in gehennom.des welds two MAPs > together. Since there are only 15 places to put a MAP, I > suspect that your second MAP must be exactly the right size > to fill the gap to the first MAP. Anonymous contributer: > Whatever doesn't fit is just cut off. No matter how big I made > the second map, it stayed the same size, and alinged itself to > the rules Kelly mentioned a while ago. The left map just > overlapped any excess column on the left side of the right map. Very specific statue traps, including carried items: Anonymous contributer: > Can I combine a container and a trap statue? Like: > > CONTAINER:'`',"statue",(70,09),"gnome",0,"Fuzzy" > TRAP:"statue",(70,09) > OBJECT:')',"dagger",(70,09),contained,uncursed,+1 > > To get a gnome called Fuzzy that has a +1 dagger in its > inventory when triggered? Dylan O'Donnell: > I believe creating a statue trap will always generate its own > statue to go on it; you can't tell it to use a statue that's > already there. However, since objects are created after traps > in the level-loading code, Fuzzy will go on top; and it's the > top statue that animates when a statue trap triggers. So if > you can live with a spurious random statue being created on > this square... Anonymous contributer: > Will the container-gnome carry the dagger when it's triggered? Dylan O'Donnell: > Yes. RANDOM_PLACES for non-objects: Joe McCauley asked if you can place secret doors in one of several different spots using RANDOM_PLACES. That isn't possible, but he's right about using RANDOM_PLACES for things that aren't objects. When you have two doors, you can make a random one broken and have the other one always be locked. Or put stairs in random locations. Extra items in stores: Desired: place a shopkeeper with a certain name and with certain goods. You can build a shop, then add extra items on top of the normally generated goods. The shopkeeper will treat the extras just like his own stock, even if you've given a potion shop a suit of dragon scale mail. I found that building an unfilled shop (= no shopkeeper or goods) and adding everything separately does NOT work; the shopkeeper isn't "bound" to the shop, so he wanders off. There's no obvious way to get a shopkeeper with a partic- ular name to stay in a shop. Alternate sets of loot: Desired: give a level alternate sets of loot without using variant levels. That is, the player gets objects 1-3, or objects 4-6, but never both sets. Using RANDOM_PLACE means that ALL sets of loot are some- where on the level. A spoiled player knows where it is. He can polymorph to a xorn and dig through walls to get to it. Fix: put the alternate loot in a 1x1 room with NON_DIGGABLE and NON_PASSWALL walls. Put a trap on the same square. He can no longer teleport, tunnel, or walk through the walls to the square. Multiple staircases: I tried putting three down staircases on a level. All three were displayed, but for two of them, I got "You can't go down here." 11.0 OPEN QUESTIONS There are quite a few question marks (and outright errors) in this document. The weakest area is the "commands" section. lev_comp.txt says "The maximum size of a map is normally 76 columns by 21 rows." I do not know when "abnormal" kicks in or what the maximum size changes to. Things which do not seem to be possible: start monsters with items in their inventory. Add tombstones. Add randomly located '.' floor squares to levels that are otherwise all ice. APPENDIX 1: SECTION 5 OF "nethack sources how-to" [Copied with permission. Reformatted. One bit of Unix stuff removed.] 5. Creating a new level ----------------------- To create a new level is easy. In fact, it doesn't require any knowledge of C: the dev team prepared it for us. Under the "util" directory the process of creating a nethack exe- cutable should have left a program called 'lev_comp' (lev_comp.exe if in MS-DOS). That binary is capable of create a new special level for nethack: give it a description file (named .des) and it gives you a level file (named .lev) suitable for the nethack binary: mylevel.des ----------- | __ | __ \ V / ___\___/___ | | _ |lev_comp |/ | | -----> mylevel.lev ------------- The lev_comp compiler has a manual page (have a look in the "doc" directory) called ['lev_comp.txt'. I've snipped out some unix info.] This man page shows (quite obtusely) how to create a .des file; but better than starting from scratch is starting trying to understand a predefined file. For example, let's view the begining of "dat\castle.des" file: MAZE:"castle",random FLAGS: noteleport GEOMETRY:center,center MAP }}}}}}}}}.............................................}}}}}}}}} }-------}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}-------} }|.....|-----------------------------------------------|.....|} }|.....+...............................................+.....|} }-------------------------------+-----------------------------} }}}}}}|........|..........+...........|.......S.S.......|}}}}}} .....}|........|..........|...........|.......|.|.......|}..... .....}|........------------...........---------S---------}..... .....}|...{....+..........+.........\.S.................+...... .....}|........------------...........---------S---------}..... .....}|........|..........|...........|.......|.|.......|}..... }}}}}}|........|..........+...........|.......S.S.......|}}}}}} }-------------------------------+-----------------------------} }|.....+...............................................+.....|} }|.....|-----------------------------------------------|.....|} }-------}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}-------} }}}}}}}}}.............................................}}}}}}}}} ENDMAP Sounds familiar? This file is the description from where the castle level is created. The part showed here just sets the level aspect: a drawed castle centered between mazes (note the MAZE line). The rest of the file puts doors, traps, objects and monsters in a random or specific position (with coordinates relative to the previous map). The man page describes the exact syntax, so if you dare you can now start modifying the whole file; but let's make a very easy change and see how it works: suppose you feel the soldiers at the castle are too wimpy and think changing them to more difficult monsters, say mino- taurs for example. So, just change the lines: MONSTER:'@',"soldier",(08,06) and subsequents with MONSTER:'H',"minotaur",(08,06) etc... (Note that with this change we are chosing a specific monster. We could have chosen to create monsters of a certain class, like MONSTER:'D',RANDOM,(08,06) # Create a random type dragon ) Save the new castle.des file and run: (from the dat directory) ..\util\lev_comp castle.des [Try lev_comp castle.des instead] That creates a new 'castle.lev' file in the 'dat' directory. To try it, copy it to the playing directory (something like games\nethack) and start a game in wizard mode. Teleport to the castle, wish for a floating eye corpse and a blindfold and have a look: you should have lots of brown H's! But now it is time to deal with the original subject: we wanted to add a NEW level to nethack, not just modifying one. Let the castle.des alone and create a newlevel.des! For that, we have to introduce a new compiler: dgn_comp, the dungeon compiler. As the lev_comp it has a manual page: dgn_comp.6. Its pur- pose is a step ahead: it takes a file describing the complete dungeon (as a collection of levels) and creates a "dungeon" file suitable for the nethack binary. The description file in question is called "dungeon.def": DUNGEON: "The Dungeons of Doom" "D" (25, 5) ALIGNMENT: unaligned %MULDGN BRANCH: "The Gnomish Mines" @ (2, 3) %REINCARNATION LEVEL: "rogue" "R" @ (15, 4) LEVEL: "oracle" "O" @ (5, 5) LEVALIGN: neutral LEVEL: "bigroom" "B" @ (10, 3) 15 %MULDGN CHAINBRANCH: "The Quest" "oracle" + (6, 2) portal %MULDGN BRANCH: "Fort Ludios" @ (18, 4) portal RNDLEVEL: "medusa" "none" @ (-5, 4) 2 LEVALIGN: chaotic LEVEL: "castle" "none" @ (-1, 0) CHAINBRANCH: "Gehennom" "castle" + (0, 0) no_down BRANCH: "The Elemental Planes" @ (1, 0) no_down up As you probably knew, there are 'levels' and branches of the main dungeon, being composed of levels. The easiest thing is to add a simple level inside the main dungeon: Suppose you created a new mylevel.des file where you define a 'mylevel' level: MAZE:"mylevel",' ' (IMPORTANT note here: usually the file is named the same as the MAZE it defines, as in castle.des, but the name for the .lev file is taken from the MAZE line !!) To add it to the main dungeon we can add a line after the bigroom one: LEVEL: "mylevel" "none" @ (15,2) That is, create the 'mylevel' level randomly at 15 +-2 level deep. The level won't left bones files (the 'none' part). And run ..\util\dgn_comp dungeon.def to get the 'dungeon' file. Copy it to the game directory and try it out (wizard mode command Ctrl-O is quite useful here). If there is any error loading the new level, nethack will create a random maze instead. Finally, if we wanted to add a whole new branch to the dungeon, we will put a line like: %MULDGN BRANCH: "newbranch" @ (18, 1) and later on, the lines defining the levels in this new branch: DUNGEON: "newbranch" "S" (4,0) DESCRIPTION: mazelike LEVEL: "mylevel1" "none" @ (1, 0) LEVEL: "mylevel2" "none" @ (2, 0) LEVEL: "mylevel3" "none" @ (3, 0) LEVEL: "mylevel4" "none" @ (4, 0) Now you should take a while and play around with the existing .des files and become familiar with the syntax. Creating new levels and dungeon wasn't difficult, was it? Maybe this chapter covers all your needs; but if you really want exciting new emotions, read on. [Download German Martin's full writeup if you want more.] APPENDIX 2: A SIMPLE .des FILE [This was taken from the end of lev_comp.txt.] EXAMPLE Here is an example of a description file (a very simple one): MAZE : "fortress", random GEOMETRY : center , center MAP }}}}}}}}} }}}|-|}}} }}|-.-|}} }|-...-|} }|.....|} }|-...-|} }}|-.-|}} }}}|-|}}} }}}}}}}}} ENDMAP MONSTER: '@', "Wizard of Yendor", (4,4) OBJECT: '"', "Amulet of Yendor", (4,4) # a hell hound flanking the Wiz on a random side RANDOM_PLACES: (4,3), (4,5), (3,4), (5,4) MONSTER: 'd', "hell hound", place[0] # a chest on another random side OBJECT: '(', "chest", place[1] # a sack on a random side, with a diamond and maybe a ruby in it CONTAINER: '(', "sack", place[2] OBJECT: '*', "diamond", contained OBJECT[50%]: '*', "ruby", contained # a random dragon somewhere MONSTER: 'D', random, random # 3 out of 4 chance for a random trap in the EAST end TRAP[75%]: random, (6,4) # an electric eel below the SOUTH end MONSTER: ';', "electric eel", (4,8) # make the walls non-diggable NON_DIGGABLE: (0,0,8,8) TELEPORT_REGION: levregion(0,0,79,20), (0,0,8,8) This example will produce a file named "fortress" that can be integrated into one of the numerous mazes of the game. Note especially the final, TELEPORT_REGION specification. This says that level teleports or other non-stairway arrivals on this level can land anywhere on the level except the area of the map. This shows the use of the ``levre- gion'' prefix allowed in certain region specifications. Normally, regions apply only to the most recent MAP specifi- cation, but when prefixed with ``levregion'', one can refer to any area of the level, regardless of the placement of the current MAP in the level. APPENDIX 3: MAZE-TYPE LEVEL TEMPLATE # Author: # Date: MAZE: "name_me", ' ' # You can change ' ' (= rock) to some other letter, or to random # for a gehennom-style maze. FLAGS: noteleport,hardfloor,nommap, arboreal, shortsighted # Remove the ones you don't want. You'll usually remove the entire # line. INIT_MAP: '.' , ' ' , true , true , lit , false # This embeds your MAP inside a random level. It's rarely used. # Walkable terrain letter, barrier terrain, smoothed (normally true), # joined (normally true), lighting, is there a wall around the level # or not. # If you use more than one map, copy everything from here to the end. # If you are making a random level, then everything from here down # to ENDMAP gets replaced by NOMAP. GEOMETRY: center, center # Left, half-left, center, half-right, or right. # Top, center, or bottom. # 10 20 30 40 50 60 70 #012345678901234567890123456789012345678901234567890123456789012345678901234 MAP 0........................................................................... 1........................................................................... 2........................................................................... 3........................................................................... 4........................................................................... 5........................................................................... 6........................................................................... 7........................................................................... 8........................................................................... 9........................................................................... 0........................................................................... 1........................................................................... 2........................................................................... 3........................................................................... 4........................................................................... 5........................................................................... 6........................................................................... 7........................................................................... 8........................................................................... 9........................................................................... 0........................................................................... ENDMAP #012345678901234567890123456789012345678901234567890123456789012345678901234 # 10 20 30 40 50 60 70 RANDOM_OBJECTS: [A list of letters for types of objects: '[' ] RANDOM_PLACES: [A list of locations: (5, 13) ] RANDOM_MONSTERS: [A list of letters for types of monsters: 'D' ] # Delete the lines above, unless you are randomizing things in # your level. (Few levels do, although it's a very good feature.) # Now place everything. The common commands are: ALTAR: [location], [alignment], [altar type] # Noalign (= Moloch), law, neutral, chaos, coaligned, nonco- # aligned, random, or align[number]. # Sanctum (high priest), shrine (priest), or altar (no priest). CONTAINER[chance]: [object type], [object name], [location] plus, if you want: , [special options] # See 7.2.2 if you want to use a special option. DOOR: [door state], [location] # Open, closed, locked, nodoor, broken, or random. ENGRAVING: [location], [engraving type], [what to engrave] # Dust, engrave, burn, or mark. MONSTER[chance]: [monster letter], [monster name], [location] plus, if you want: , [1 or more special options] # Special options: peaceful or hostile, awake or asleep, alignment. NON_DIGGABLE: region NON_PASSWALL: region # Stops monsters & poly-ed players able to walk through walls. OBJECT [chance]: [object type], [object name], [location] plus, if you want: , [special options] # See 7.2.2 if you want to use a special option. REGION: [region], [lighting], [room type] optional: , [populated] # room type: "ordinary", "throne", "swamp", "vault", "beehive", # "morgue", "barracks", "zoo", "delphi", "temple", "shop", "armor # shop", "scroll shop", "potion shop", "weapon shop", "food shop", # "ring shop", "wand shop", "tool shop", "book shop", "candle shop", # and probably "anthole", "cocknest", and "leprehall", too. # populated: filled or unfilled. STAIR: [location], [up or down] TRAP [chance]: [trap name], [location] # "arrow", "dart", "falling rock", "board", "bear", "land mine", # "rolling boulder", "sleep gas", "rust", "fire", "pit", "spiked pit", # "hole", "trap door", "teleport", "level teleport", "magic portal", # "web", "statue", "magic", "anti magic", "polymorph", or "random". WALLIFY # Plain rock adjacent to floor is changed to wall. # End of map. Go back and remove the numbers at the end of each # line of the map. APPENDIX 4: ROOM-TYPE LEVEL TEMPLATE # Author: # Date: LEVEL: "name_me" FLAGS: noteleport,hardfloor,nommap, arboreal, shortsighted # Remove the ones you don't want. You'll usually remove the entire # line. # This map template is just to make designing the level easier. # It is all commented out; the computer ignores it. ## 10 20 30 40 50 60 70 ##012345678901234567890123456789012345678901234567890123456789012345678901234 #0........................................................................... #1........................................................................... #2........................................................................... #3........................................................................... #4........................................................................... #5........................................................................... #6........................................................................... #7........................................................................... #8........................................................................... #9........................................................................... ##012345678901234567890123456789012345678901234567890123456789012345678901234 #0........................................................................... #1........................................................................... #2........................................................................... #3........................................................................... #4........................................................................... #5........................................................................... #6........................................................................... #7........................................................................... #8........................................................................... #9........................................................................... #0........................................................................... ##012345678901234567890123456789012345678901234567890123456789012345678901234 ## 10 20 30 40 50 60 70 RANDOM_OBJECTS: [A list of letters for types of objects: '[' ] RANDOM_MONSTERS: [A list of letters for types of monsters: 'D' ] # Delete the lines above, unless you are randomizing things in # your level. (Few levels do, although it's a very good feature.) # Add some rooms and (sometimes) subrooms: ROOM: [room type], [lit or unlit], (0,0), [location], [size] SUBROOM: [room type], [lit or unlit], [location], [room name],[size] # room type: "ordinary", "throne", "swamp", "vault", "beehive", # "morgue", "barracks", "zoo", "delphi", "temple", "shop", "armor # shop", "scroll shop", "potion shop", "weapon shop", "food shop", # "ring shop", "wand shop", "tool shop", "book shop", "candle shop", # and probably "anthole", "cocknest", and "leprehall", too. # Now place things in each room. The common commands are: ALTAR: [location], [alignment], [altar type] # Noalign (= Moloch), law, neutral, chaos, coaligned, nonco- # aligned, random, or align[number]. # Sanctum (high priest), shrine (priest), or altar (no priest). CHANCE: [50 or whatever] # The percent chance that the room does get the contents you say. CONTAINER[chance]: [object type], [object name], [location] plus, if you want: , [special options] # See 7.2.2 if you want to use a special option. DOOR: [secret], [door state], [which wall], [where on wall] # Open, closed, locked, nodoor, broken, or random. # Wall: north, east, south, or west. Where: # of squares or random ENGRAVING: [location], [engraving type], [what to engrave] # Dust, engrave, burn, or mark. FOUNTAIN: [location] MONSTER[chance]: [monster letter], [monster name], [location] plus, if you want: , [1 or more special options] # Special options: peaceful or hostile, awake or asleep, alignment. NAME: [room name] # Only needed if you're adding subrooms to it. OBJECT [chance]: [object type], [object name], [location] plus, if you want: , [special options] # See 7.2.2 if you want to use a special option. POOL: [location] SINK: [location] STAIR: [location], [up or down] TRAP [chance]: [trap name], [location] # "arrow", "dart", "falling rock", "board", "bear", "land mine", # "rolling boulder", "sleep gas", "rust", "fire", "pit", "spiked pit", # "hole", "trap door", "teleport", "level teleport", "magic portal", # "web", "statue", "magic", "anti magic", "polymorph", or "random". # End of level. APPENDIX 5: TABLES AND LISTS 5.1 Terrain symbols Taken from the documentation. Comments in [] are mine. '-' horizontal wall '|' vertical wall '+' a doorway 'A' open air [See below.] 'B' boundary room location (for bounding unwalled irregular regions) [see the Valley of the Dead.] 'C' cloudy air 'I' ice 'S' a secret door 'H' a secret corridor [Tested a bit; no bugs seen.] '{' a fountain '\' a throne 'K' a sink '}' a part of a moat or other deep water 'P' a pool 'L' lava 'W' water (yes, different from a pool) [See below.] 'T' a tree 'F' iron bars '#' a corridor '.' a normal room location (unlit unless lit in a REGION declaration) ' ' stone An extract from one of Dylan O'Donnell's postings: | |There are three types of water terrain: moat (}), pool (P), and |water (W), all of which show up on screen as '}'. Some of the |more significant differences: | |Moat: | cannot be dried up by fire | can be frozen | 1/30 chance of kelp | |Pool: | can be dried up by fire | can be frozen | less likely to flow into adjacent pits than a moat | 1/10 chance of kelp | |Water: | cannot be dried up by fire | cannot be frozen | no chance of kelp | |There are assumptions in several places that all W terrain will be |on the Plane of Water, so I wouldn't recommend using it elsewhere. | | ...I wouldn't recommend using [A for air] outside the Endgame, |because some assumptions are likely to break. 5.2 Object symbols + Spell book [and door] $ Gold ) Weapon [ Armor % Food ? Scroll / Wand = Ring ! Potion ( Tool " Amulet [and spider web] * Gem rock ` Boulder statue 0 Iron ball _ Altar iron chain. 5.3 Monster symbols I generated this from MONS-331. a giant ant killer bee soldier ant fire ant giant beetle queen bee b acid blob quivering blob gelatinous cube c chickatrice cockatrice pyrolisk d jackal fox coyote werejackal little dog dog large dog dingo wolf werewolf warg winter wolf cub winter wolf hell hound pup hell hound e gas spore floating eye freezing sphere flaming sphere shocking sphere f kitten housecat jaguar lynx panther large cat tiger g gremlin gargoyle winged gargoyle h hobbit dwarf bugbear dwarf lord dwarf king mind flayer master mind flayer i manes homunculus imp lemure quasit tengu j blue jelly spotted jelly ochre jelly k kobold large kobold kobold lord kobold shaman l leprechaun m small mimic large mimic giant mimic n wood nymph water nymph mountain nymph o goblin hobgoblin orc hill orc Mordor orc Uruk-hai orc shaman orc-captain p rock piercer iron piercer glass piercer q rothe mumak leocrotta wumpus titanothere baluchitherium mastodon r sewer rat giant rat rabid rat wererat rock mole woodchuck s cave spider centipede giant spider scorpion Scorpius t lurker above trapper u white unicorn gray unicorn black unicorn pony horse warhorse v fog cloud dust vortex ice vortex energy vortex steam vortex fire vortex w baby long worm baby purple worm long worm purple worm x grid bug xan y yellow light black light z zruty A couatl Aleax Angel ki-rin Archon B bat giant bat raven vampire bat C plains centaur forest centaur mountain centaur D baby gray dragon baby silver dragon baby red dragon baby white dragon baby orange dragon baby black dragon baby blue dragon baby green dragon baby yellow dragon gray dragon silver dragon red dragon white dragon orange dragon black dragon blue dragon green dragon yellow dragon Chromatic Dragon Ixoth E stalker air elemental fire elemental earth elemental water elemental F lichen brown mold yellow mold green mold red mold shrieker violet fungus G gnome gnome lord gnomish wizard gnome king H giant stone giant hill giant fire giant frost giant storm giant ettin titan minotaur Cyclops Lord Surtur J jabberwock K Keystone Kop Kop Sergeant Kop Lieutenant Kop Kaptain L lich demilich master lich arch-lich M kobold mummy gnome mummy orc mummy dwarf mummy elf mummy human mummy ettin mummy giant mummy N red naga hatchling black naga hatchling golden naga hatchling guardian naga hatchling red naga black naga golden naga guardian naga O ogre ogre lord ogre king P gray ooze brown pudding black pudding green slime Q quantum mechanic R rust monster disenchanter S garter snake snake water moccasin pit viper python cobra T troll ice troll rock troll water troll Olog-hai U umber hulk V vampire vampire lord Vlad the Impaler W barrow wight wraith Nazgul X xorn Y monkey ape owlbear yeti carnivorous ape sasquatch Z kobold zombie gnome zombie orc zombie dwarf zombie elf zombie human zombie ettin zombie giant zombie ghoul skeleton ' straw golem paper golem rope golem gold golem leather golem wood golem flesh golem clay golem stone golem glass golem iron golem @ human wererat werejackal werewolf elf Woodland-elf Green-elf Grey-elf elf-lord Elvenking doppelganger nurse shopkeeper guard prisoner Oracle aligned priest high priest soldier sergeant lieutenant captain watchman watch captain Medusa Wizard of Yendor Croesus archeologist barbarian caveman cavewoman healer knight monk priest priestess ranger rogue samurai tourist valkyrie wizard Lord Carnarvon Pelias Shaman Karnov Hippocrates King Arthur Grand Master Arch Priest Orion Master of Thieves Lord Sato Twoflower Norn Wizard of Balance Thoth Amon Master Kaen Master Assassin Ashikaga Takauji Dark One student chieftain neanderthal attendant page abbot acolyte hunter thug ninja roshi guide warrior apprentice [blank] ghost shade & water demon horned devil succubus incubus erinys barbed devil marilith vrock hezrou bone devil ice devil nalfeshnee pit fiend balrog Juiblex Yeenoghu Orcus Geryon Dispater Baalzebub Asmodeus Demogorgon Death Pestilence Famine djinni sandestin Minion of Huhetotl Nalzok ; jellyfish piranha shark giant eel electric eel kraken : newt gecko iguana baby crocodile lizard chameleon crocodile salamander ~ long worm tail 5.4 Types of traps TRAP [chance]: [trap name], [location] TRAP:"pit",(57,10) "anti magic" "arrow" "bear" "board" "dart" "falling rock" "fire" "hole" "land mine" "level teleport" "magic" "magic portal" [I doubt that you can place these with TRAP:] "pit" "polymorph" "random" "rolling boulder" "rust" "sleep gas" "spiked pit" "statue" "teleport" "trap door" "web" 5.5 Types of rooms When you're playing, you sometimes are given a different name. Example: "shop" is a general store. "armor shop" "barracks" "beehive" "book shop" "candle shop" "delphi" "food shop" "morgue" "ordinary" "potion shop" "ring shop" "scroll shop" "shop" "swamp" "temple" "throne" "tool shop" "vault" (have a layer of ' ' then at least one '#'; see 7.2.4.) "wand shop" "weapon shop" "zoo" I think that these are legal, too: "anthole" "cocknest" "leprehall" APPENDIX 6: OPTIONS FOR THE MAP COMMANDS Some options apply to more than one command. I'll list those here, in alphabetical order. [alignment]: noalign, law, neutral, chaos, coaligned, nonco- aligned, random, or align[number]. "noalign" is Moloch. align[number] is a way to get the same random alignment for several different things. I'll explain more later. (N.B.: you use align[0] to [2] without using RANDOM_ALIGN first; RANDOM_ALIGN is not needed and does not exist.) [chance] lets you specify the odds of an object, monster, or trap appearing. (Room-type levels let you do this for rooms, too, so you can have random shops and altars.) An example from the Medusa level: CONTAINER: '`', "statue" ,(36,10), uncursed, "knight", 1, "Perseus" OBJECT[75%]: '[', "shield of reflection", contained, cursed , +0 OBJECT[25%]: '[', "levitation boots" , contained, random , +0 OBJECT[50%]: ')', "scimitar" , contained, blessed, +2 OBJECT[50%]: '(', "sack" , contained [curse status]: blessed, uncursed, cursed, or random. Note that the effect of "random" depends on the item. Levitation boots are usually cursed, so using "random" on the levitation boots in the example usually curses them. [lighting]: lit, unlit, or random. [location]: (x,y), random, place[number], or CONTAINED. o (x, y): x is the horizontal position and y the vertical. o Random: a random spot on the current MAP, not anywhere on the level. o place[number]: you must give RANDOM_PLACES a list of locations for this region. After that, place[#] gives you a random selection from that list. I'll explain more later. o CONTAINED: this is only allowed for objects, and only after a CONTAINER has been placed. Location examples: TRAP: "spiked pit", (37,07) Barbarian quest OBJECT: random, random, random Gnomish mine CONTAINER: '(', "chest" , place[0] Castle OBJECT: '"', "amulet of life saving", contained Vlad [region] lets you specify a rectangle that you want treated specially in some way. There are two ways to specify it: 1) (x1, y1, x2, y2), where (x1, y1) is the upper left corner of the region and (x2, y2) is the lower right corner. Examples: REGION: (00,00,74,19),lit,"ordinary" Medusa NON_DIGGABLE: (00,00,14,10) Vlad 2) levregion(x1, y1, x2, y2) "levregion" says that this region's location is given relative to the upper left hand corner of the entire *level*. This doesn't make a difference if your map is pushed up into the upper left corner of the level. But the castle isn't that way. It has a 10-square wide random maze on either side, and the random maze isn't on the map. So the castle has this command for the stairs in: STAIR: levregion(01,00,10,20), (0,0,62,16), up So, this places the stairs anywhere inside the left-hand maze. The second region of this command is relative to the map's upper left hand corner, like normal. The second region covers the entire map. I don't know what this second region is for. APPENDIX 7: COMMANDS FOR MAZE-TYPE LEVELS Here are the commands for maze-type levels. For each command, I'll give a template and a couple of examples. I'll then explain the options. 7.1 Commands At The Start Of The Level These are included in the template. MAZE: [level name], [filling type] MAZE: "gehen5", random MAZE: "minetn-1", ' ' Level name: up to 8 characters. Don't use a name already used by another level. Try to make the name meaningful enough that people can figure out what .des file it came from: "gehen5", not "rob1". (Each level name eventually becomes a file name.) Filling: suppose your map is only 30 squares by 20. This leaves a lot of squares undefined. I believe that "filling" says just what is in the rest of the squares. Most levels will use rock, which is a blank: ' '. Or, you can say random, and get a gehennom- style maze. You can also, say, make your map an island surrounded by lava. FLAGS: [special options] FLAGS: noteleport,hardfloor,nommap This lets you define special options applying to the entire level. The same flags are used by both types of levels. If you aren't using any flags, leave this line out. The special options are: noteleport: "A mysterious force keeps you from teleporting!" hardfloor: "This floor is too hard to dig through." nommap: No magic mapping of this level. "Your mind is filled with crazy lines!" arboreal: This is only used in the first ranger quest level. Pasi Kallinen explains: > - all secret corridors and stone walls ('H' and ' ') are shown as > trees ('T') > - arboreal levels don't have randomly placed minerals (gems & gold) > - digging makes floor ('.') instead of corridor ('#'). > - random corridors are made of floor-symbol ('.') instead of > corridor-symbol ('#'). shortsighted: This keeps monsters from "seeing" you from clear across the level. On the astral plane, this keeps every critter on the level from piling up around you after the first minute. INIT_MAP:[walkable terrain letter], [barrier terrain letter], [smoothed], [joined], [lighting], [walled] Juiblex level: INIT_MAP: '.' , '}' , true , true , unlit , false Random mine level: INIT_MAP: '.' , ' ' , true , true , random , true This embeds your map inside a larger, random level. You'll rarely use this. Walkable terrain letter: this is normally the usual '.' floor. 'I' ice is also possible. You could try 'L' lava between undiggable walls for the lower levels of Gehennom. Barrier terrain letter: the Juiblex level uses '}' water when you're not on the walkable terrain. The upper Valkyrie quest levels use 'I' ice. Ice is not much of a barrier. Further down it gets more serious and there's 'L' lava. Smoothed: true or false (usually true). Best guess for what this is: the raw output of the cavern & island drawing routine has very jagged edges. If Smoothed is true, extra squares are added to the cavern or island to give a better-looking perimeter. Joined: true or false. This is almost always true. The cavern & island drawing routine can generate disconnected areas unless you specify Joined as true. Lighting: lit, unlit, or random. Walled: true or false. Normally true, which makes all blank stone adjacent to floors change from " " to normal walls. See the gnome king's wine cellar, on the right side, for what "false" looks like. MESSAGE: [lunatic ravings] MESSAGE: "Well done, mortal!" MESSAGE: "But now thou must face the final Test..." MESSAGE: "Prove thyself worthy or perish!" As of 2001, only the endgame levels give out messages when you first enter them. 7.2 Commands For Each Map You can have up to ten maps on a level. Each map is a rectangle. The Asmodeus level has two maps: a square one for the central rooms, then a long rectangular one for the hallway leading in. You'll usually have just one big map covering most or all of the screen. 7.2.1 Commands To Start A Map GEOMETRY: [horizontal position], [vertical position] GEOMETRY: center , center GEOMETRY: half-left, top This says where your map goes in the level. Usually, your map IS the level, and you just use "center, center". horizontal position: left, half-left, center, half-right, or right. "Left" is touching the left side of the screen. "Half-left" is one quarter of the way across the screen. "Center" means center the map within the level. "Right" is touching the right side of the screen. "Half-right" puts the right side of the map three-quarters of the way across the screen. vertical position: top, center, or bottom. MAP [Your map gets placed here.] ENDMAP The template already has this. NOMAP NOMAP is an alternative to (GEOMETRY and MAP). NOMAP means that, although this is a maze-type level, the part that you're setting up now doesn't have a map. (I've only seen NOMAP used for entire levels.) The random mine levels use this. Nothing in those levels is the same every time. It's just a random level with some enemies, some loot, and stairs. The random quest levels are the same. RANDOM_OBJECTS: [A list of letters for types of objects] RANDOM_PLACES: [A list of locations] RANDOM_MONSTERS: [A list of letters for types of monsters] (RANDOM_CORRIDORS is for room-type levels and is not related to these three commands.) This example is from the castle: RANDOM_OBJECTS: '[', ')', '*', '%' RANDOM_PLACES: (04,02), (58,02), (04,14), (58,14) RANDOM_MONSTERS: 'L', 'N', 'E', 'H', 'M', 'O', 'R', 'T', 'X', 'Z' The RANDOM_xxx options aren't used a lot, but they let you do some unique things. They set up random lists of thingies, for use later on in the region. You can list, say, a bunch of letters for monsters. Later, when you place a monster, you can say: MONSTER: monster[0], random, (27,05) instead of: MONSTER: 'E', random, (27,05) The second version always gives you a random elemental. This is very predictable. The first version gives you any of ten different monsters. Every time you refer to, say, monster[5], you get the same monster from your list. But, each game monster[5] will be different. If a list has 5 items, they are numbered 0 to 4, not 1 to 5. Your list can have up to 10 items. (The castle has 2 or 3 monsters of each of the ten types given. This is too consistent; only their positions change, and they move around before the player sees them, anyway. Maybe have none of two types, and more of some of the rest. Sometimes you get no giants, sometimes you get six.) The castle uses this a lot. Here's how the wand of wishing is placed in one of the four towers: CONTAINER: '(', "chest" , place[0] OBJECT: '/', "wishing", contained ENGRAVING: place[0], burn, "Elbereth" The CONTAINER is put in place[0]: any one of the four RANDOM_PLACES. The OBJECT's location is "contained", so it goes in the CONTAINER. The ENGRAVING also says place[0], so it goes to the same place as the container. The four types of RANDOM_OBJECTS go into the four storerooms, but they don't always end up in the same rooms: # Storeroom number 1 OBJECT:object[0],random,(39,05) OBJECT:object[0],random,(40,05) OBJECT:object[0],random,(41,05) OBJECT:object[0],random,(42,05) OBJECT:object[0],random,(43,05) OBJECT:object[0],random,(44,05) ...and so on. align[0] to [2] gives a random (but consistent) alignment in a level. Note that there is no RANDOM_ALIGN command. (Some programmer took a shortcut which made the commands less consistent and harder to learn.) 7.2.2 Commands Defining A Map Alphabetical order. Appendix 6 explains some options used with many different commands. General: some items you can add to the map just by using the appropriate symbol (e.g.: '\' gives a throne). ALTAR: [location], [alignment], [altar type] ALTAR: (36,02), coaligned , shrine Caveman quest ALTAR: (16,11), noncoaligned, altar Wizard quest alignment: as given in 4.2.2. altar type: sanctum, shrine, or altar. A shrine is an altar with a priest in attendance. The priest is generated for you, just like shops automatically get random goods. A sanctum has the high priest for that alignment in attendance. The only sanctums are on the astral plane, Moloch's final level (Moloch counts as an align- ment unto himself), and the Orcus level. That one must be treated specially in the code; there's no high priest. BRANCH: [region], [region] # Branch, not allowed on Medusa's island. BRANCH:levregion(01,00,79,20),(59,01,73,17) I have not studied how to make a new branch of levels, like the Gnomish Mines. I'll only document this if I learn and document all the level-set stuff. CONTAINER: [the same stuff as for an object] Containers can be sacks, bags of holding, oilskin bags, ice- boxes, chests, large boxes, or statues. Examples: CONTAINER:'`',"statue",random CONTAINER:'`',"statue",(64,09) CONTAINER:'`',"statue",(46,17),uncursed,"gnome king", 0 To put an object into a container, you say CONTAINED for the object's location. It goes into the most recent container. (Warning: for ROOM-type levels, it goes into the *next* container. Sheesh.) (The "0" at the end of the gnome king statue means that the statue is not historic, which only matters to archeologists. "1" would mean historic. For an object, this number would be the en- chantment. Statues re-use the number for a different purpose. The Perseus statue is not +1 when wielded as a weapon.) Containers are empty except for what you put in. If you want a chest with the normal random loot, use the OBJECT command to add it. DOOR: [door state], [location] DOOR: closed, (46,07) DOOR: locked, (38,08) Door state: open, closed, locked, nodoor, broken, or random. But, if you used an "S" on the map, the door is already secret, so just specify "closed" or "locked". "random" for normal doors would mean open, closed, or broken. (Don't use "random" for shop doors: the shopkeeper can't block the doorway if the door is broken.) Dylan O'Donnell: "Doors defined as 'random' may be randomly trapped; doors defined as 'closed' or 'locked' will never be, nor will secret doors implicitly defined through 'S' on a map." DRAWBRIDGE: [location], [direction], [door state] DRAWBRIDGE:(05,08),east,closed Direction: north, east, south, or west. The drawbridge location is where the drawbridge is shown when it is open (= down and OK to walk on). From there, go in the direc- tion given to find the square which is blocked when the drawbridge is closed. Thus, the drawbridge direction for the castle is east. (The above is reversed from I expected, so watch it.) ENGRAVING: [location], [engraving type], [what to engrave] ENGRAVING:(12,03),engrave,"You are now entering the Gnome King's wine cellar." ENGRAVING:(12,04),engrave,"Trespassers will be persecuted!" Engraving type: dust, engrave, burn, or mark. "Mark" would be magic marker. The level compiler does not know about engraving in blood: darn. FOUNTAIN: [location] FOUNTAIN: (13, 7) ... or just use the '{' symbol on your map. GOLD: [amount], [location] Amount: a number, or random. LADDER: [location], [up or down] LADDER: (11,05), down MAZEWALK: [location], [direction] MAZEWALK:(00,10),west Castle MAZEWALK:(62,06),east Castle Direction: north, east, south, or west. MAZEWALK has two main uses: 1. Making Gehennom-style mazes. Example: the castle level has Gehennom-style mazes at either side. 2. Making a path from a MAP to a point outside the MAP (usually a staircase). Example: the Juiblex level has a map for the center half of the level, plus a few smaller maps. Both staircases are in random- ly generated areas. Mazewalk gives you random trails through the water, connecting to the ends of trails built on the central map. MAZEWALK works by starting at a particular point and facing in a particular direction. It jumps two squares forward, leaving a trail of stone floor behind it. It then tries jumping two squares in other directions. If it's making Gehennom-style mazes, it keeps going until it fills the entire area. If it's making a path, it stops once it finds land (but I'm unclear on what rules it uses). The location is where the maze's path starts, and you say what direction the first jump should take. If you're connecting a MAP to a staircase or whatever, put a door or open floor at the start location. I don't properly understand MAZEWALK. I put some information from Kelly Bailey into Appendix 10. Read it if you want to use MAZEWALK, but not before then. MONSTER[chance]: [monster letter], [monster name], [location] plus, if you want: , [1 or more special options] MONSTER: '@', "watchman", random, peaceful MONSTER: 'D',"Chromatic Dragon",(23,10),asleep MONSTER: '@',"aligned priest",(61,11),neutral,hostile monster letter: see appendix 1 for the list of which letters go with which monster names. monster name: name the monster, or say random to get a random monster from the monsters that use the monster letter you gave. Special options: o peaceful or hostile. Note that some monsters can be generated as peaceful. If you want, say, elementals or djinns to be hostile for sure, specify hostile. o awake or asleep. o An alignment. o Give the monster a name. I added this line to barb.des: MONSTER:'n',"water nymph",(60,01), peaceful, "Shirley" ...and when I c)hatted with her, I got the message "Shirley comes on to you." o m_feature "object name" This seems to be specifically for what mimics start off mimicing. Examples from the Juiblex and Rogue quest levels: MONSTER: 'm', "giant mimic", place[1], m_feature "fountain" MONSTER: 'm', "giant mimic", place[1], m_feature "staircase down" You can also use m_object and m_monster. m_monster would be for chameleons and other shapeshifting monsters. m_object would be for mimics. m-object is used in one of the 3.4.0 mine-end levels, but I haven't seen it myself yet. m_monster has never been used, so I can't swear that it works. I don't know if the "m_xxx" options have any other special limitations or options. Several monsters can be started in the same spot. After they start moving, they spread out without any problems. Note that a stack of sleeping monsters will act very strangely. "I killed the orc five times, and he's still there!" It's a stack of ten orcs; keep chopping. NON_DIGGABLE: region Walls in that region can't be dug through. The floor is not affected. NON_PASSWALL: region Ghosts and xorns can walk through walls. This stops them. Apply it to the entire level to keep polymorphed players from going everywhere. OBJECT [chance]: [object type], [object name], [location] plus, if you want: , [special options, which MUST include the enchantment] OBJECT: '*' , "diamond", (21,08) OBJECT: '*' , random , (21,08) OBJECT: random, random , random object type: see appendix 1 for what character each type of object uses, or use random to get a random type of object. object name: name the object, or use random to get a random item of whatever the object type is. location: as explained in 4.2.2. Reminder: the location can be CONTAINED, to put the object into the last CONTAINER you defined. Special options: the order matters; if you use any of them, you MUST give the enchantment; if you #name the object, you have to give either the curse status or the monster name as well. o [curse status] o [monster type] such as "knight" for the status of Perseus. o [enchantment] In the code, "enchantment" is obj->spe. It was freely re-used for everything under the sun. Leave it at zero unless you know that it does for your type of object. Here's what I know: (with thanks to Dylan O'Donnell and Pasi Kallinen) - Armor and weapons: enchantment. - Wands, rings, magic markers, and whatnot: charges. - Statues: 1 means historic, 0 means normal. - Tins: 1 means spinach. -1 means home-made. - Containers: 1 means Schroedinger's Cat. - Bags of holding: it is normally 0. I don't know why. - Lamps and candles: it is normally 1. 0 means "out of oil" for lamps. I suppose 1 means "brand new; unused". - Magic lamps: it is normally 1. 0 means it was wished for, and there's no wish. Don't do this; it looks like a bug. - Candelabrum: how many candles are attached to it. - Scrolls of mail: 1 means it was not delivered to the current player. - Eggs: 1 means the hero laid it. - Chests: 2 means it's the royal coffer (in court). o [#name of object] such as "Perseus" for that statue on the Medusa level. I've only seen this used for the quest artifacts and Perseus. (Special case: if your object is a corpse, this specifies what it's a corpse of.) Examples of named objects: OBJECT : ')', "mace" , (23,10), blessed, 0, "The Sceptre of Might" CONTAINER: '`', "statue", (36,10), uncursed, "knight", 1, "Perseus" As of 3.3.1, we're limited to 128 objects per level. PORTAL: [region 1], [region 2], [the level you go to] PORTAL:(30,0,75,19),(00,00,09,16),"fire" level of air I have not studied how to make a new branch of levels, like the Gnomish Mines. I'll only document this properly if I learn and document all the level-set stuff. I believe that the portal is randomly placed in the first region. Define a one-square region if you want a fixed location. I believe that the second region is the invalid region, as ex- plained under TELEPORT_REGION. The name of the destination level is as given on its "MAZE:" or "LEVEL:" line. REGION: [region], [lighting], [room type] optional: , [populated] optional: ,[irregular] REGION:(00,00,75,19), lit,"ordinary" REGION:(25,04,28,07), lit,"temple" REGION:(27,05,37,11), lit,"throne" ,unfilled castle REGION:(16,05,25,06), lit,"barracks" castle REGION:(02,01,08,03), lit,"ordinary",unfilled,true caveman quest REGION:(19,01,24,08),unlit,"morgue" , filled,true Valley o t Dead REGION:(01,01,04,05),unlit,"morgue" Tourist quest REGION:(00,00,50,17),unlit,"swamp" Jubliex REGION:(32,09,37,12), lit,"shop" REGION:(03,10,07,13),lit,"zoo",filled,true lighting: this seems to go one square beyond the official limits of the region. room type: "ordinary", "throne", "swamp", "vault", "beehive", "morgue", "barracks", "zoo", "delphi", "temple", "shop", "armor shop", "scroll shop", "potion shop", "weapon shop", "food shop", "ring shop", "wand shop", "tool shop", "book shop", or "candle shop". And probably "anthole", "cocknest", and "leprehall", too. Note that, when you're playing, you sometimes are given a different name. Example: "shop" is a general store. populated: filled or unfilled. If you don't say anything, the room is filled. "Filled" means that the room is populated for you: shops get a shopkeeper and the right type of goods, barracks get sleeping soldiers and sometimes a chest. (For temples, the ALTAR command is what determines if there's a priest or not.) I suspect that this option does nothing for some types of rooms. A morgue is populated with undead. (The Fort Ludios treasure room is an unfilled morgue, but ignore that: it's a way for the .des file to tell the program which room is the treasure room.) Pasi Kallinen: "on the medusa-level, the first region with 'unfilled' gets random statues named after players." Special case: if you have a portal inside an ordinary room, set that room's REGION to "unfilled". (When monsters arrive via portal, they are placed near the portal. "unfilled" indirectly keeps them inside the room. The Fort Ludios entry room does this, to keep monsters from arriving on the far side of two locked doors.) irregular: true or false. Pasi Kallinen explains: > > I think if the region is defined as irregular, the only thing that > matters is that the first region coordinate is inside the area, and > that the area is closed off from the rest of the map with walls, > doors, boundary symbols ('B'), etc. The boundary symbols will be > converted to floor-symbols ('.') after NetHack loads the level. At compile time, 'B' is officially a wall. Putting an object in the same square gives a warning. STAIR: [location], [up or down] or STAIR: [region 1], [region 2], [up or down] Stairs have to go on '.' squares. This is normally not an issue. The Juiblex level has a couple of small MAPs, just to make that the stairs have some solid land to go on. The second version works like TELEPORT_REGION. TELEPORT_REGION: [destination region], [invalid region] optional: , [up or down] When you teleport into the level from the specified direction, you end up in the destination region. If you do not specify a dir- ection, the destination region applies to teleports in both direc- tions. The invalid region apparently gives areas you can't arrive in, if you're, say, dropped into the level by a trapdoor. TRAP [chance]: [trap name], [location] Trap names: "arrow", "dart", "falling rock", "board", "bear", "land mine", "rolling boulder", "sleep gas", "rust", "fire", "pit", "spiked pit", "hole", "trap door", "teleport", "level teleport", "magic portal" (but I doubt that you can place them this way), "web", "statue", "magic", "anti magic", "polymorph", or "random". 7.2.3 Commands To End A Map WALLIFY Pasi Kallinen explains: > > Wallify does 2 things: > > a) it changes all walls completely surrounded by solidrock or > walls to solidrock, and > > b) all solidrock (' ') in MAP...ENDMAP are changed to walls > ('|' or '-'), if the solidrock is next to a unsolid mapgrid. 7.2.4 Vaults on Maze-type Levels. Put a layer of rock ' ' around the vault, and have some corr- idor '#' somewhere outside of that. (I tend to use '.' instead of '#'.) Otherwise, when it's time for the vault guard to teleport in, you get the message "Not a single corridor on this level??" and you're randomly teleported, just to rescue you from the vault. APPENDIX 8: COMMANDS FOR ROOM-TYPE LEVELS 8.1 Background For Room-type Levels This explanation may be wrong. I'm guessing here. There are two types of rooms: a normal ROOM, and a SUBROOM. Your standard random dungeon level has 4-8 random ROOMs. OK, you know what a ROOM is. But, a ROOM can be more than that. Minetown-1 and -2 have big rectangular areas with a bunch of shops and whatnot inside, plus four random ROOMs on the outside. The big rectangular areas are actually ROOMs. After that, if you want to place a room inside of a bigger room, you call it a SUBROOM. SUBROOM means "this is a slightly unusual room which goes inside a normal ROOM". The big difference between a ROOM and a SUBROOM is that a SUBROOM has to be placed inside a ROOM. The SUBROOM's options for lighting and whatnot override what- ever the ROOM has. So, if you want, you can define a ROOM as big as the entire level, then fill in the details with SUBROOMs. Or, you can just put in a whole bunch of ROOMs and forget about SUBROOMs completely. I expect that putting a normal ROOM inside another ROOM will give error messages. If it goes inside a ROOM, it must be a SUBROOM. When you add an object or whatever, you have to give its location. For maze-type levels, the location is relative to the upper left corner of the map. Here, for room-type levels, they are relative to the upper left corner of the room. It's the same when you place a SUBROOM inside a ROOM. The SUBROOM's co-ordinates are relative to the ROOM's corner. If you're doing up a ROOM like minetown-1 (big, with stuff inside, but smaller than the entire level), then don't put the entire level on your map template. Instead, just put the ROOM itself. All the locations you need will be relative to the upper left corner of the ROOM, so it makes sense to put that at (0,0) on the map template. 8.2 Commands At The Start Of The Level These are included in the template. I'll only document the differences between maze-type and room-type levels. LEVEL: [level name] LEVEL: "minetn-2" This is the equivalent of the MAZE command. FLAGS: [special options] INIT_MAP:[walkable terrain letter], [barrier terrain letter], [true or false #1], [true or false #2], [lighting], [walled] I only see this used with maze-type levels. I suspect that it does not apply to room-type levels, even though lev_comp.txt shows it as allowed. If you want to experiment, it's explained in the maze-type appendix. MESSAGE: [lunatic ravings] You can only have 256 characters of messages per .des file. (I suspect a bug; 256 per .lev file seems more reasonable.) RANDOM_OBJECTS: [A list of letters for types of objects] RANDOM_MONSTERS: [A list of letters for types of monsters] (RANDOM_CORRIDORS is not related to these three commands.) These commands are used only once per room-type level. (Maze- type levels used them once per map.) Note that the RANDOM_PLACES command does not work for room-type levels. 8.3 Commands For Each Room You can have several rooms on a level. Each room is a rect- angle. 8.3.1 Commands To Start A Room SUBROOM: [room type], [lighting], [location], [room name], [size] or: ROOM: [room type], [lighting], [location #1], [location #2], [size] room type: "ordinary", "throne", "swamp", "vault", "beehive", "morgue", "barracks", "zoo", "delphi", "temple", "shop", "armor shop", "scroll shop", "potion shop", "weapon shop", "food shop", "ring shop", "wand shop", "tool shop", "book shop", "candle shop", and probably "anthole", "cocknest", and "leprehall", too. Notes on room types: o When you're playing, you sometimes are given a different name. Example: "shop" is a general store. o Although the above says that a ROOM can be a vault, it fails in real life. (The game crashes when you enter the level, or you don't get what you asked for.) To be safe, use "ordinary" for all ROOMs. SUBROOMs should work with any room type. Both types of locations specify the upper left corner of the room. The wall around the room does not count as part of the room; you specify the location of floor, not rock. The wall is added for you. location: a SUBROOM's location, relative to the ROOM it is in. (Do not use "random"; the level compiler accepts it, but Nethack locks up.) location #1 and #2: these only apply to ROOMs. o location #1: this roughly positions the ROOM on the level. Imagine a 5x5 grid laid out over a level. The upper left corner is (1,1). The lower right corner is (5,5). The center is (3,3) o location #2: this apparently gives the exact location of the room, relative to location #1. It can be random or [horizontal position], [vertical position]. - horizontal position: left, half-left, center, half- right, or right. - vertical position: top, center, or bottom. room name: this only applies to SUBROOMs. It says which ROOM the SUBROOM goes into. You have to NAME the ROOM first. size: how many squares the room extends, horizontally and vertically. It can be random or (x,y) There is a final option called "filling". It can be true, false, or left blank. As of 3.3.1, all of the .des files leave it blank. Presumably it lets you fill a room with lava, water, or whatever. -------------------- Late update: I had serious problems getting a shrine to work. The priest either wasn't generated, or was not linked to the altar (= would wander off, and attack you if you #chatted with him). For many things I tried, the shrine gave the same message as when the priest of a shrine has been killed. I eventually got it to work with a room of type 'ordinary' with a 'temple' subroom and with the altar explicitly placed: ROOM: "ordinary" , lit, (3,1), (center,top), (11,7) NAME: "holy" SUBROOM: "temple", lit, (2,0), (7,5), "holy" DOOR: false, nodoor, south, random DOOR: false, nodoor, east , random DOOR: false, nodoor, west , random ALTAR: (03,02), coaligned, shrine -------------------- 8.3.2 Commands Defining A Room Alphabetical order. I'll only explain the non-trivial ones which aren't already explained for maze-type levels. ALTAR: [location], [alignment], [altar type] CHANCE: [percent odds] CHANCE: 90 You can have an altar show up half the time by specifying CHANCE: 50 for the ROOM or SUBROOM it's in. The room is still there, but just as a normal room. I suspect that everything except the room itself gets taken out: both gnomish wizards and whatnot. CONTAINER: [the same stuff as for an object] PROBLEM: to put objects into containers on room-type levels, put the "contained" objects *first*, and the container *last*. Example: OBJECT:'?',"blank paper",contained OBJECT:'$',random,contained CONTAINER:'(',"chest",(01,02) DOOR: [secret], [door state], [which wall], [door location] DOOR: false, closed, north, random secret: true or false. Door state: open, closed, locked, nodoor, broken, or random. Direction: north, east, south, or west. Door location: random, or give a number. This is where along the wall the door goes. I expect that 0 means at the left for horizontal walls and at the top for vertical walls. ENGRAVING: [location], [engraving type], [what to engrave] Engraving type: dust, engrave, burn, or mark, but not blood. FOUNTAIN: [location] GOLD: [amount], [location] MONSTER[chance]: [monster letter], [monster name], [location] plus, if you want: , [1 or more special options] NAME: [room name] NAME: "town" I believe that this only applies to ROOMs. Once you NAME a room, SUBROOMs specify "roomname" to get added to that particular ROOM, instead of one half-way across the level. OBJECT [chance]: [object type], [object name], [location] plus, if you want: , [one of the special options] POOL: [location] I don't know if you can place moats on ROOM-type levels. SINK: [location] STAIR: [location], [up or down] TRAP [chance]: [trap name], [location] Trap names: "arrow", "dart", "falling rock", "board", "bear", "land mine", "rolling boulder", "sleep gas", "rust", "fire", "pit", "spiked pit", "hole", "trap door", "teleport", "level teleport", "magic portal" (but I doubt that you can place them this way), "web", "statue", "magic", "anti magic", "polymorph", or "random". 8.4 Commands Defining Corridors RANDOM_CORRIDORS Corridors are randomly added to connect all the ROOMs. If you specified random locations for all your ROOMs but one, this is exactly what you want. It's probably what you want even if you put 10 rooms in very specific locations. (SUBROOMs don't need corridors. When you add them to the parent ROOM, you leave some spaces empty. Those spaces are the corridors. They pick up whatever defaults you gave the parent ROOM.) CORRIDOR: ( [room number], [direction], [door position] ), ( [room number], [direction], [door position] ) or CORRIDOR: ( [room number], [direction], [door position] ), [number] Pasi Kallinen explains: > > CORRIDOR: (1, north, random), (2, south, random) > > Creates a corridor from [sub]room #1 (starting from a random > position on its north wall), to [sub]room #2 (ending on a random > position on its south wall). The room # is defined by the order > in which the [sub]rooms are defined. APPENDIX 9: DIFFERENCES BETWEEN MAZE- AND ROOM-TYPE LEVELS There are workarounds to some of the missing commands. For example, the quest home levels are maze-type levels. That lets them put in thrones for the quest leaders, without having to put in the crowds of hostile monsters that throne rooms normally have. To get the same thing in a room-type level, add a throne room with the "unfilled" option. Maze-type only: - MAPs. This doesn't directly affect what you can do on a level. It does make levels easier to build. - RANDOM_PLACES. Example use: the castle's WoW is randomly in one of four locations. - DRAWBRIDGE. - LADDER. - NON_DIGGABLE, which makes walls undiggable. - NON_PASSWALL, which keeps ghosts, xorns, and polymorphed players from walking through walls. - Several commands which all seem to be related to moving between different branches of the dungeon. (BRANCH, TELEPORT_REGION, PORTAL, REGIONS, and the second version of STAIR.) - Gehennom-style mazes. (MAZEWALK is a near equivalent to RANDOM_CORRIDORS. REGION is close enough to ROOM.) APPENDIX 10: KELLY BAILEY ON "MAZEWALK" [This includes several posts. I have edited it somewhat. - Rob.] MAZEWALK's goal in life is to eat through STONE (that is, the blank space character in MAPs) like swiss cheese. It leaves behind a trail of FLOOR ('.'). MW is very particular and a bit odd. 1) Each time mazewalk wants to dig another bit of maze, it looks two characters ahead. If it sees stone, it moves there. It digs right through the character between the current square and the target square, without ever looking at it. So that's why something like this: MAP TTTTTTT T T T T TTTTTTT T T T T TTTTTTT ENDMAP ...can create a maze of trees: mazewalk jumps from stone to stone square, replacing some trees with floor, but leaving the rest intact as walls. But note that mazewalk doesn't really care about the edge of the above map. It would look beyond the edges for stone and burrow into the level beyond. So when you place your MAP, you want to use characters to keep the mazewalk in. [That is, if there were an extra layer of T all around the edge of the MAP, mazewalk would be stopped: its steps are only two characters long. Anything except " " works, I think. - Rob.] Substituting empty floor ('.') for T's at the edge of the MAP will give you entrances and exits. Substituting empty floor ('.') for T's inside the MAP will create loops in the finished maze (not otherwise possible). 2) Mazewalk is particular about starting out on odd or even squares. I forget which, and it's not worth trying to calculate: just try it, and adjust [your starting location] by a square horizontally and/or vertically to get it to work. (If the MAP height is 21, the Y must be locally odd.) 3) Start mazewalk next to a square it will eat, pointed at it. 4) Gehennom levels are MAZEs. Gehennom levels get random monsters, traps, and objects suitable for Gehennom. MAZEWALK uses the same routines as the Gehennom levels. When you use a mazewalk, Nethack will say: "Gee, this is part of a Gehennom level. I should add some random stuff appropriate to Gehennom. Like minotaurs." If your mazewalk is on level 5, you don't want random minotaurs. I believe that if your total area covered by MAPs is 1232 squares or more, this doesn't happen, and you're safe. [This is probably because the Castle uses a mazewalk, but shouldn't get Gehennom-style random stuff.] The amount of automatic sprinkling of traps, boulders, minotaurs, etc. is proportional to how much space isn't used up by your MAP..ENDMAPs. The program tries to place random things in the area outside the MAPs. If it can't find a good spot, it goes ahead and finds a bad one, which could lead to objects stuck in walls. 5) It also doesn't do the top row of squares for some reason. 6) MAZE:"..",random. Here, the 'random' means fill the map first with a "checkerboard grid" of walls and stone specifically for mazewalk to chew on. But that's getting into wallification, which is another can of worms :-/ load_maze() in sp_lev.c is the function to pore over. [Here's another post, which you're probably better off ignoring:] MAZEWALK works only when the STONE blocks it eats are on odd-numbered squares. That is, "globally" odd numbered squares. Normally you don't have to worry about this, since when you put a MAP down, nethack tries to snap the map to globally odd coordinates. This means that usually you can be sure that (0,0) on your map is in fact an odd coodinate, which means that placing the STONE squares on *even* local coordinates is correct. However, if your map is 21 squares tall, then it fills up the whole vertical size of the screen, so the program has no choice but to start the vertical count at 0, which means (0,0) on your map is (odd,even) in terms of global coordinates. Thus, if your map is 21 squares high, the rows of blocks should occur on ODD local coordinates instead of even. The quickest fix would be to delete a row from the bottom of the map so that it's only 20 squares high, so it gets aligned properly (that is, oddly). If the map *MUST* be 21 squares tall, you'll have to make it so that the square that is now (02,02) becomes (02,03) by moving the whole maze down and adjusting coordinates, so that it might look like this: MAP ............... ............... .-S-----------. .- - - - - - -. .-------------. .- - - - - - S. .-------------. ............... [down to 21 lines] ENDMAP MAZEWALK:(02,02),south [I've found that MAZEWALK fails for this type of map if you use WALLIFY. WALLIFY is applied before MAZEWALK is done, and MAZE- WALK has no normal stone squares to tunnel through.] If you've got the squares aligned properly (and they must be), you should probably start the MAZEWALK right on the "entrance square" (either of the S characters above), pointing "in." Don't start it on one of the STONE bits. This is because the very first thing MAZEWALK does is move one square in the direction you tell it, and then turn what's there to ROOM floor (unless it's a door). This makes sense when you consider how it is being used in the castle and gehennom, pointing outside the map. And no, I have no idea why MAZEWALK behaves so oddly ;)