Roguelike column thumbnail ['@ Play' is a bi-weekly column by John Harris which discusses the history, present and future of the Roguelike dungeon exploring genre.]

There are the roguelike games that have closed source, which for the longest time included Rogue, and still includes ADOM and just about every commercial game out there. And then there are the roguelikes that are open source.

And of them all, there is one game that is particularly identified with open source. Of course, it's Nethack, which was effectively open long before it became fashionable. The game is old enough that its license, the "Nethack Public License," takes GNU Bison's as its model, not the GPL. In point of fact, Eric S. Raymond himself has contributed documentation to the game, and he mentioned it in his famous essay . It and the other open source roguelikes (Angband and Dungeon Crawl among them) offer the best hope that open source game development can work.

Development is one thing. Design is something else entirely. The model of many random people contributing patches often turns into a classic case of too many cooks. It takes a strong vision to avoid the game turning into an unplayable muddle, because it's so easy to wreck it by adding misfeatures. Computer games not only require strong software design but something else besides, and roguelikes rely on ideas that most other games abandoned long ago, that some surprising people will swear have no place in gaming. Last month David Sirlin, who possesses an excellent understanding of fighting game mechanics, made a series of blanket statements about game saving, using Dead Rising as his example, that would absolutely destroy roguelikes if applied to them. For some reason few commercial developers outside of Japan seem to get how roguelikes are supposed to work; even Blizzard's popular quasi-roguelike Diablo games didn't add permadeath until the second game, and went out of their way to say it was intended for "hardcore" players. Anyway, it succeed largely for reasons unrelated to being like rogue(6).

Because of the special vision required to avoid ruining 'em, roguelike projects tend to languish without a strong person, or group in agreement, maintaining them. For Nethack, we have the mighty Devteam, who are just about as mysterious a group as is possible in legal open source software development. What they'll add to the next version is known to few outside their group, or even what its release date is. At the moment it's been longer since a new version of Nethack than any previous release of the game, but we still know they're working, and we know a new version will come... some day. Of course it's still open source, and that means anyone can make their own version of Nethack. The Devteam is even known to sometimes add a selection of outside patches in the official game. But neither do they add tremendous numbers of outside ideas, and what they do add at times seems odd to us mortals.

But yes, the source is still open, so anyone can make their own version of the game with just a computer, a compiler, the code, and a whole lot of cursing. Unlike Angband's source, which prior maintainer Ben Harrison cleaned up and made so inviting for people to mod the game that there may be more players of variants than of Angband, Nethack's source looks exactly like you'd expect something with "hack" in the name to be.

gcc hits! Your brain is eaten!

Trying to modify the Nethack source code with only basic programming knowledge is a good way to get frustrated. Changing Nethack is definitely not a task for the faint-hearted... or for the C-ignorant, for that matter. It is not recommended that one try to learn C by hacking away at the Nethack sources, due to its many weirdnesses. Some of its code is automatically generated by an included utility called makedefs, and changes made in the wrong place (like trying to add monsters in pm.h instead of monst.c) could cause unexpected problems, or at best be destroyed by the act of compilation. Macros are used in many places. Even C experts may be confused by the identifiers sprinkled around, things like STATIC_DCL and STATIC_OVL. These are dusty vestiges of the 286 days, when the game had to work under real-mode DOS. They had cooked up this impressive overlay scheme to allow everything to work, swapping code in off disk when needed, but while no one has successfully made real-mode Nethack since 3.3.0, the artifacts of the system are still sprinkled around the source code.

nhbenign.pngFirst off, to compile Nethack for your system, you'll need a supported compiler. This is actually one of the less troublesome aspects of building the game, for Nethack's source is promiscuous to say the least. Nethack is mostly a straight, pre-ANSI C program, with none of that C++ stuff mixed in. It gets some help from make, which gets a fair workout, and yacc/bison and lex/flex for building levels. On Microsoft platforms, there's support for multiple versions of Microsoft's Virtual C tools (including the free 2005 Express version combined with Microsoft's Platform SDK, which I've personally used to build the game), Borland C++ and GCC (using either cygwin, mingw, or DJGPP for protected-mode DOS, still one of the most playable versions of the game). Mac OS/X and Classic are supported, as are many different Unixes, some rather elderly. In addition, the game has official support in the tree for BeOS, Windows CE, OS/2, Amiga and Atari ST. (And of course porting the game to other systems, like the Nintendo DS, is a standard hack for hobbyists.)

Instructions for building the game are straightforward but lengthy, with the docs beginning in README in the source directory followed by system- and compiler-specific instructions in each platform's Install.* file. Further help on this step can be found on the Nethack Wiki. In a last-ditch situation, the Devteam is known to sometimes reply to questions concerning compilation trouble, and if a problem seems intractable it may be worth shooting them an email. (I won't repeat their address here to try to save them from a bit of extra spam, but there's a contact from on their site that's not too hard to find.)

"Nethack contains everything including the kitchen sink," eh? Not anymore, fool!

Once the game is compiled, though, then what? The Devteam provides official binaries for many target systems, so there's not usually a reason to build from scratch unless one is going to modify the source in some way. And there are several different levels of involvement that one can take with this.

The simplest level, which doesn't take much skill with C to mess with, is to add or remove certain well-compartmentalized features from the game. Config.h in include/ is the place to do this, which is where different graphic styles are added to the game as well as wizard mode, a notable debugging aid that can also be used to cheat. Most of the interesting features come in that file's Section 4, suitably named "THE FUN STUFF!!!"

minocube.pngWhen the Devteam adds major features to the game, there's often a period when the code is put in conditionally, so players able to compile the game can remove them because they don't like them, or they need to make the game smaller. After a while, as these features become increasingly identified with Nethack, the conditionals are usually removed from the code. But some features take up residence here permanently. Usually these are the crazier features: kitchen sinks, the Rogue level, Keystone Kops, seduction by succubi and incubi, and Discworld-inspired Tourist players can all be neatly excised by commenting out a single line.

In practice this is done but rarely, because the weirdness has become identified with Nethack's style (people who are attracted to Nethack are often so because of the clever jokes, and are loathe to see them go), and because a number of nice sub-features are tied in with these. Commenting out #define TOURIST also removes Touristy items like credit cards, expensive cameras and shirts. Elbereth, a popular feature that some (okay, I) think make the game too easy, can also be compiled out from config.h, but this also removes crowning, a cool game event that happens to players who achieve high standing with their god.

At Last We Can Add Gamera as a Monster

Many people who change the game don't want to add huge new features, but just want to customize some of the monsters and items, or add to the dungeon. This is not so easy, but it could be much worse. The Beginners Guide to the Nethack Sources is the bible for making these kinds of modifications, and for detailed instructions one should check there first. Although it was last modified in 1995 most of its information is still good, especially concerning the overall structure of the source, and most of the information in the rest of this column ultimately comes from there.

Making a new monster involves editing the file monst.c, and with a bit of intuition it's not hard to add a new entry there, if one doesn't care about it having any abilities not shared by other monsters. Other than that the process is largely automated, for Nethack determines stuff like monster difficulty, experience awards and generation odds automatically. Adding new levels is trickier, but there is support in the game for changing levels without changing the binary. Nethack gets its information on the dungeon and its levels from data files, not the game binary itself, so it's theoretically possible to change the dungeon on a pre-compiled version of the game.

nhpotions.pngIt's possible, but that doesn't mean that anyone does it in practice. The dungeon and level files usually get made as part of make install, and there are some hard-coded references to various levels in the source, so making any really interesting changes usually means recompiling the game. Changing the level definition files is a notoriously finicky process, prone to break if language terms are specified out of order, or with the wrong spacing character. (Tabs != spaces!)

A few other things can be added relatively easily. Adding a new item isn't so hard, although it'll have only basic object behavior until code is added to cover the neat stuff it should do. Still, that can get you further than you might think. Basic equipment stats like damage, AC and weight can be manipulated just by changing the appropriate numbers, and some things are automatically applied by the code, like silver damage to demons and lycanthropes if the object's material is set to SILVER.

One thing it's easy to overlook are the special characteristics for different item classes. All rings produce special messages when dropped down sinks and many wands produce distinctive messages when the player engraves on the floor with one. Often potions mix with others when dipped, or have special effects on items, and scrolls and spellbooks should have code added to handle when magic markers are used to write them. This is all in addition to the code needed to make the object perform its function, and don't forget that potions, wands and tools have different effects if cursed or blessed, and scrolls have additional effects when read while confused.

New room types are a mixed bag. It's easy to take the code for a monster lair room type in mkroom.c, like the leprechaun hall, copy it, modify it to make a new type of lair, then adjust the room generation probability elsewhere in the source file to make it show up. But this will only produce lair-type rooms. The most interesting Nethack rooms are the ones with special rules, shops and temples, and those are very difficult to write. Nethack shops and shopkeepers do things the hard way because it makes theft into a puzzle to be overcome, and are designed with care. Duplicating that is a task even experienced hack-hackers balk at.

That's how... but why?

The best advice I can offer towards learning how to get around the code, besides playing the game a lot to know how things operate, and using a code cross-referencing tool like doxygen, is to think hard about using the source code itself as a guide for how to do things. Many things you might want to add to the game are already there, under a different context. I had an idea a week ago about adjusting a unicorn horn's cursed/blessed status one level down when successfully applied for healing, in order to prevent a single horn from making a player practically immune to negative status effects. I happened to remember that scrolls of scare monster, when picked up, lower in blessing status in exactly the same way. A search for SCARE_MONSTER turned up hits in five files, one of them named pickup.c. The addition ended up being only slightly more involved than a copy-and-paste job. When trying to find code to adapt, it's useful to search for the code-name for the item (like "SCARE_MONSTER"), or for a message printed by the game when using it.

Knowing what not to change

The greatest danger, when it comes to modifying the source... well, the greatest danger is causing a hard-to-find bug. But assuming it all works, then the greatest danger is messing up the game's design while doing so. Nethack's various game systems interact with each other in unexpected ways, and one must have encyclopedic knowledge of nearly the whole game to avoid unforeseen balance effects. Some people wonder why drinking a potion doesn't leave an empty bottles that could be later filled with water. The only real answer is because it would make the game too easy: water is one of the most useful potions available to a player who knows how to use it. It doesn't make sense, but it's pretty much mandated by the play.

Maybe there's a way to make empty potion bottles work in the context of the game. It's not impossible. But it's the kind of thing that, if there was an easy way to do it, the Devteam probably would have implemented it years ago. Most of the weird things about Nethack are like that. Perhaps that budding patch author may have the solution to the problem. It's just likely that he doesn't.