There is an archive of the sorce code for NitroHack 4.0.4 on the downloads page.
The source code for NitroHack is hosted on GitHub.
The build process uses cmake to generate Makefiles and Visual Studio Projects.
In order to build NitroHack (the text UI) you need ncursesw, ie ncurses with wide character support.
To build the network server and client library you also need jansson, a JSON handling library.
Finally, the network server uses PostgreSQL to store stuff and needs to link to the PostgreSQL client library, libpq.
Report bugs online here or send a bug report to daniel@dthaler.de .
This release fixes all 5 bugs discovered since 4.0.3.
4.0.3 fixes several issues, but saves remain compatible with 4.0.2. In particular, bones files now work.
Once again several bugs were fixed in the save format, making old games incompatible. Additionally, many crashes were fixed.
4.0.1 fixes several game-breaking bugs. Since the save format also had bugs, saves from 4.0.0 will most likely not work with 4.0.1. This depends on whether any of the buggy code was hit in the saved game.
Alex Smith (3):
Daniel Thaler (57):
NitroHack supports network play without telnet or ssh over its own protocol. The protocol is based on JSON and should make it very easy to implement a browser-based NitroHack client (TODO!).
The old format was mostly just a dump of the data structures from memory onto disk.
The new format has 2 sections:
The log file is written continuously, so the "INSURANCE" option and the recover utility are gone - a crashed game can always be restored by replaying the log. After the game ends, the log marked as closed and kept.
The reason for keeping logs of finished games. Once there was a way to reconstruct the state of the game at any point it would have been silly not to use it for game viewing.
Since the replay mode is based on abstract game commands rather than directly recorded screen output, it is completely feasible to replay a that was played on a unix tty in a windows tile port or vice versa. A viewer for games is built into the new nethack UI. You can perform commands that don't affect the game state (like view inventory) while viewing a game replay.
Options changed ingame are written back to the options file, which you are not supposed to edit by hand any more. The options have moved from ~/.nethackrc to ~/.config/NitroHack/NitroHack.conf (for game options) and ~/.config/NitroHack/curses.conf for the options of the curses UI. Logs of active and completed games are also under ~/.config/NitroHack/
Want to play without Elbereth? It is now possible to do so without recompiling. ELBERETH, REINCARNATION, SEDUCE and bones files have become a new kind of option: birth options, which can only be set before the character is created.
The core game code has moved into a library (libnitrohack.so or nitrohack.dll). The game library exposes an API of exactly 23 functions and is largely OS independent. The display code is part of the OS/platform dependent executable and must provide a list of callbacks (windowprocs) to the game. There is no shared global state between the two.
This was a prerequisite for the network protocol, which encodes the api calls and callbacks almost literally.
With this change, the days of multiple window port binaries are over. It now makes much more sense to have separate programs, for example nitrohack-qt and xnitrohack.
The NitroHack network server is technically a UI port and uses the same mechanisms.
The came core never, ever requests a key from the UI. All interactions happen on an abstract level: The ui sends commands to the core as a string ("wait", "move", etc.), the game my request a direction or a position (etc).
This allows the UI to perform key mapping safely, because it is never necessary to guess what context some request for input occurs in.
All the old window ports became obsolete due to the extensive API changes. A new UI based on curses (ncurses on unix, pdcurses on windows) has been written. It is a significant upgrade compared to the old tty port in terms of usability and features:
The game core provides a set of display items for each location to the UI, rather than a single display char. For example a monster on an item on a trap can be represented logically.
The curses UI displays the alternatives by blinking between them (unless you disable blinking in the options).
An OS independent RNG with known state was required in order to make game logs replayable. The mersenne twister is the best choice.
Several of the main data structures have been made const, all others are carefully re-initialized when a game is started or loaded. This makes it possible to have a main menu for starting games, viewing the top ten or changing options.
Previously this was not possible, as the altered global state from one game would have affected a second, so quitting was the only option. NitroHack now uses an exception mechanism based on setjmp/longjmp to escape from deep callchains when the game ends or panics.
All levels are now kept in memory at all times. This makes a lot of locking unnecessary. It also allows viewing of levels you are not currently on.
The only remaining locking is of active game logs via OS mechanisms which are not based on files: fcntl on UNIX and LockFile on Windows. (For a game where all levels have been visited, this change could result in up to 5 Mb of extra memory use! The horror!!)
Support for everything that belongs in a computer history museum has been removed: BE, DOS, Classic Mac, Atari, VMS, Ultrix, etc...
The list of supported compilers has likewise been reduced to gcc, clang and msvc (and probably Intel's compiler, too).
This allowed the removal of lots and lots of crufty code and compat macros. All current compilers support "void" and "static", so wrapping them in #defines is not necessary any more.
The number of "#ifdef FOO" has been cut down from 1938 to just 51. That makes the code much more readable, because the indentation isn't being interrupted every couple of lines. To this end almost all compile options that didn't becom birth options were enabled unconditionally or removed due to being obsolete. All functions have been converted to use standard prototypes rather than K&R declarations. Ugly things like prototype widening and the follow-on <FOO>_P #defines went away. Tools like git diff can now correctly show what function a line is in.
All instances of the keyword "register" have been removed - optimizing compilers handle this for us. Likewise NEARDATA; that only made sense on 16-bit computers.
This replaces some of the ugliest Makefiles known to man (I kid). On Linux you get safe parallel builds with pretty colorized output, on Windows the generated Visual Studio 2010 project builds without problems.
Real rule sets that control what gets picked up replace the pickup list + exceptions system. Rules can match based on the name, object type and BUC status.
The following rule set picks up all food as well as lizard corpses, but no other corpses:
IF name matches "*lizard*" AND type is "food": < GRAB
IF name matches "*corpse*" AND type is "food": LEAVE >
IF type is "food": < GRAB
Rules are evaluated in order until a matching rule is found. If no rule matches, the item is left behind by default.
NitroHack will automatically track the following items (with a turn timestamp) for use in your ascension posts:
You can view your heroic deeds with #history
This change was inspired by the "Dungeon Map Overview 3" patch (by Hojita Discordia) as found in UnNetHack.
You can now #annotate a level to name/describe it.
You can select a level from the overview menu to view your memory of it.
Inspired by Jukka Lahtinen's dumplog patch.
When you die, a dump log containing the following information will be created:
Based on code by Jukka Lahtinen and Patric Müller in UnNetHack.
Item types are sorted depending on:
My sources for these fixes were UnNetHack, AceHack, the Patchdb.
© 2012 Daniel Thaler