On this page
  1. Related
  2. Mechanics
  3. References
  4. Sources

NetHack’s README calls it “a distant descendent of Rogue and Hack”1. The atlas reads NetHack 3.6.7, whose README is dated February 2023, so every claim here names that version.

The hunger-clock starts at 900 nutrition, lower than Rogue’s 1,300, and drops by 1 a turn, with more taken by rings, amulets, a heavy load, and some properties2,3. A hero turns Hungry at 150 and Weak at 50, and starves at a depth set by Constitution4. Where Rogue caps a meal at 2,000, NetHack can choke a hero who keeps eating while Satiated5,6.

The melee roll keeps Rogue’s rate of 5% per point of level and armor class, and adds Luck7. An ordinary level fills free rectangles with rooms and joins them from left to right8. One level copies Rogue’s 3 × 3 grid instead9.

A death ends the program unless an amulet of life saving or a debug mode intervenes10. Restoring deletes the save, except in wizard and explore modes11, and those modes ask “Die?” at a death12. Unidentified items’ descriptions are shuffled each game13.

Mechanics

MechanicKindHow
Hunger clockOvereating chokes900 nutrition at the start, less 1 a turn plus rings, amulets, and loads; Hungry at 150, Weak at 50, starved below −(100 + 10 × Constitution); a Satiated meal past 2,000 can choke
Hit chanced20 against armor classa 1–20 roll below 1 + Luck + level + armor class + bonuses: 5% a point, as in Rogue
Procedural dungeonFree rectanglesup to 40 rooms in free rectangles, joined from left to right, plus extra corridors that can dead-end
Procedural dungeonRoom gridone level in Rogue's 3 × 3 style, each cell an intersection 1 time in 5
PermadeathWhole runrestoring deletes the save, except in wizard and explore modes, which also offer to refuse a death
Item identificationShuffled appearancesdescriptions shuffled within seven classes and four armor groups
Every claim about this game, by concept (12)
generalNetHack's README calls the game “a distant descendent of Rogue and Hack”.Developer
Hit chanceIn NetHack 3.6.7 the hero's melee attack hits when a roll of 1 to 20 is below a total of 1 + Luck + the strength and dexterity bonus + the target's armor class + the hero's level (a polymorphed hero's monster level) + the hero's to-hit increment from rings of increase accuracy. The total gains 2 against a stunned, a fleeing, or a sleeping target (which the attack wakes), and 4 against one that can't move; it loses 3 while the hero is trapped and more for a heavier load; it adds the wielded weapon's to-hit and the hero's skill bonus, and adjusts for a monk and for an elf against an orc. An engulfed hero always hits. Computed, the chance is (total − 1) / 20, held within 0 to 100%. Damage is computed only after a hit.Code
Computed from both games' code, NetHack 3.6.7's melee roll keeps the rate of Rogue 5.4's swing: each point of the attacker's level or the target's armor class adds 5% to the chance to hit, which is (level + armor class + bonuses) / 20 in Rogue and (level + armor class + Luck + bonuses) / 20 in NetHack.Code
Hunger clockNetHack 3.6.7 starts the hero at 900 nutrition. Once per game turn, and again for each melee attack the hero makes, it takes 1, unless the hero has slow digestion, is polymorphed into a form that doesn't eat, or is praying under divine protection, and only at a chance of 1 in 10 while the hero is asleep or fainted. On odd turns, regeneration (not from an artifact) and a Stressed or heavier load each take 1 more; on even turns, the Hunger property and Conflict (not from an artifact) do, and once every 20 turns each worn ring that has a charge other than 0 or takes none, the worn amulet, and carrying the Amulet of Yendor take 1 each.Code
NetHack 3.6.7 counts the hero Satiated above 1,000 nutrition, Not Hungry above 150, Hungry above 50, Weak above 0, and Fainting at 0 or below. While Fainting, a hero not already fainted or helpless faints on entering the state, and later at a chance that grows as nutrition falls (1 in 20 at 0), for 10 turns plus a tenth of the deficit; on an update where neither happens, the hero starves once nutrition is below −(100 + 10 × Constitution).Code
In NetHack 3.6.7, food that brings nutrition to 2,000 or more chokes a hero who was Satiated (for a meal, at its start). A hero who doesn't breathe always vomits and loses 1,000 nutrition instead; a hero being strangled always dies; any other hero vomits 1 time in 20 and otherwise dies.Code
Item identificationWhen a NetHack 3.6.7 game starts, it shuffles the descriptions of amulets, potions, rings, scrolls, spellbooks, wands, and venoms within each class, and of helmets, gloves, cloaks, and boots within each of those groups. Water keeps a fixed description, and scrolls, spellbooks, and amulets keep the unique or non-magic ones fixed; a type whose name is already known keeps its description.Code
PermadeathRestoring a NetHack 3.6.7 game deletes the save file once it is read, unless the game is in wizard (debug) or explore mode; in those modes the Unix build asks “Do you want to keep the save file?”. While a restore runs, the Unix build makes the file unreadable, to disallow parallel restores.Code
When a NetHack 3.6.7 hero dies in wizard (debug) or explore mode, from any cause of death from an ordinary death to genocide (not a panic, quitting, escaping, or ascending), and a worn amulet of life saving hasn't already saved the hero, the game asks “Die?”; answering no saves the hero's life and play goes on.Code
When a NetHack 3.6.7 hero dies, unless a worn amulet of life saving or the wizard and explore modes' “Die?” prompt saves the hero, the game records the score and ends the program.Code
Procedural dungeonAn ordinary NetHack 3.6.7 level places rooms, one of which may be a vault, in free rectangles until none is left, a room fails to fit, or it has 40. It sorts them by left edge, and joins each to the next, stopping early at a chance of 1 in 50 per join. It then joins each room to the one two along when they aren't yet connected, then any pair still unconnected. With 3 or more rooms it makes 4 to (room count + 3) attempts at another corridor; an attempt gives up before digging when the square outside its door is already open, and stops short, leaving a dead end, at a chance of 1 in 35 per step.Code
NetHack 3.6.7's main dungeon, the Dungeons of Doom, holds one level built in Rogue's style. Its code's comment says “Rogue levels are structured 3 by 3, with each section containing a room or an intersection”, and each of the nine cells is an intersection at a chance of 1 in 5, so long as at least one room is made.Code

References

  1. ^NetHack's README calls the game “a distant descendent of Rogue and Hack”.DeveloperNetHack 3.6.7 source
    How we know
    4which is a distant descendent of Rogue and Hack, and a direct descendent of
    
    README lines 3–5 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  2. ^NetHack 3.6.7 starts the hero at 900 nutrition. Once per game turn, and again for each melee attack the hero makes, it takes 1, unless the hero has slow digestion, is polymorphed into a form that doesn't eat, or is praying under divine protection, and only at a chance of 1 in 10 while the hero is asleep or fainted. On odd turns, regeneration (not from an artifact) and a Stressed or heavier load each take 1 more; on even turns, the Hunger property and Conflict (not from an artifact) do, and once every 20 turns each worn ring that has a charge other than 0 or takes none, the worn amulet, and carrying the Amulet of Yendor take 1 each.CodeNetHack 3.6.7 sourcerevised
    How we know
    119    u.uhunger = 900;
    
    src/eat.c lines 116–120 at ed600d9 · upstream ↗
    176                    /* once-per-turn things go here */
    
    src/allmain.c lines 172–176 at ed600d9 · upstream ↗
    281                    gethungry();
    
    src/allmain.c line 281 at ed600d9 · upstream ↗
    2799    if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
    
    src/eat.c lines 2790–2804 at ed600d9 · upstream ↗
    2821        switch ((int) (moves % 20)) { /* note: use even cases only */
    
    src/eat.c lines 2806–2841 at ed600d9 · upstream ↗
    373#define Unaware (multi < 0 && (unconscious() || is_fainted()))
    
    include/youprop.h line 373 at ed600d9 · upstream ↗
    25    SLT_ENCUMBER = 1, /* Burdened */
    
    include/hack.h line 25 at ed600d9 · upstream ↗
    1873    if (p_type == 3 && !Inhell) {
    ⋮
    1877        u.uinvulnerable = TRUE;
    
    src/pray.c lines 1873–1877 at ed600d9 · upstream ↗
    1978overexertion()
    ⋮
    1983    gethungry();
    
    src/hack.c lines 1975–1983 at ed600d9 · upstream ↗
    408        || overexertion())
    409        goto atk_done;
    
    src/uhitm.c lines 406–409 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Revised after a check by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  3. ^Rogue 5.4 starts the hero with 1,300 food. The stomach daemon runs once per pass of the command loop, after the hero's move, or after both moves when the hero is hasted. While food is above 0 it takes 1, plus each worn ring's cost, and 1 less while the hero carries the Amulet of Yendor, so with the Amulet and no rings the count stops.CodeRogue 5.4.4 source
    How we know
    29    food_left = HUNGERTIME;
    
    init.c line 29 at cf9bd26 · upstream ↗
    117#define HUNGERTIME	1300
    
    rogue.h line 117 at cf9bd26 · upstream ↗
    150    start_daemon(stomach, 0, AFTER);
    
    main.c line 150 at cf9bd26 · upstream ↗
    32    if (on(player, ISHASTE))
    
    command.c lines 32–39 at cf9bd26 · upstream ↗
    444    do_daemons(AFTER);
    
    command.c line 444 at cf9bd26 · upstream ↗
    163	food_left -= ring_eat(LEFT) + ring_eat(RIGHT) + 1 - amulet;
    
    daemons.c lines 160–163 at cf9bd26 · upstream ↗
    148	amulet = TRUE;
    
    pack.c lines 147–148 at cf9bd26 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  4. ^NetHack 3.6.7 counts the hero Satiated above 1,000 nutrition, Not Hungry above 150, Hungry above 50, Weak above 0, and Fainting at 0 or below. While Fainting, a hero not already fainted or helpless faints on entering the state, and later at a chance that grows as nutrition falls (1 in 20 at 0), for 10 turns plus a tenth of the deficit; on an update where neither happens, the hero starves once nutrition is below −(100 + 10 × Constitution).CodeNetHack 3.6.7 source
    How we know
    2939                            : (h > 50) ? HUNGRY : (h > 0) ? WEAK : FAINTING;
    
    src/eat.c lines 2936–2939 at ed600d9 · upstream ↗
    2983        if (u.uhs <= WEAK || rn2(20 - uhunger_div_by_10) >= 19) {
    
    src/eat.c lines 2977–2999 at ed600d9 · upstream ↗
    3004        } else if (u.uhunger < -(100 + 10 * (int) ACURR(A_CON))) {
    
    src/eat.c lines 3001–3008 at ed600d9 · upstream ↗
    2842    newuhs(TRUE);
    
    src/eat.c line 2842 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  5. ^Eating any food in Rogue 5.4 first raises a negative count to 0, then adds 1,100 to 1,499 (HUNGERTIME - 200 + rnd(400)), capped at 2,000.CodeRogue 5.4.4 source
    How we know
    298    if ((food_left += HUNGERTIME - 200 + rnd(400)) > STOMACHSIZE)
    
    misc.c lines 296–300 at cf9bd26 · upstream ↗
    119#define STOMACHSIZE	2000
    
    rogue.h line 119 at cf9bd26 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  6. ^In NetHack 3.6.7, food that brings nutrition to 2,000 or more chokes a hero who was Satiated (for a meal, at its start). A hero who doesn't breathe always vomits and loses 1,000 nutrition instead; a hero being strangled always dies; any other hero vomits 1 time in 20 and otherwise dies.CodeNetHack 3.6.7 sourcerevised
    How we know
    2864    if (u.uhunger >= 2000) {
    
    src/eat.c lines 2863–2865 at ed600d9 · upstream ↗
    2543        context.victual.canchoke = (u.uhs == SATIATED);
    
    src/eat.c line 2543 at ed600d9 · upstream ↗
    252    if (Breathless || (!Strangled && !rn2(20))) {
    
    src/eat.c lines 238–260 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  7. ^Computed from both games' code, NetHack 3.6.7's melee roll keeps the rate of Rogue 5.4's swing: each point of the attacker's level or the target's armor class adds 5% to the chance to hit, which is (level + armor class + bonuses) / 20 in Rogue and (level + armor class + Luck + bonuses) / 20 in NetHack.CodeNetHack 3.6.7 source · Rogue 5.4.4 sourcerevised
    How we know
    266    tmp = 1 + Luck + abon() + find_mac(mtmp) + u.uhitinc
    
    src/uhitm.c lines 266–267 at ed600d9 · upstream ↗
    613    int mhit = (tmp > dieroll || u.uswallow);
    
    src/uhitm.c lines 612–613 at ed600d9 · upstream ↗
    172    x = RND(x) + 1;
    
    src/rnd.c line 172 at ed600d9 · upstream ↗
    381    int need = (20 - at_lvl) - op_arm;
    
    fight.c lines 378–384 at cf9bd26 · upstream ↗
    188    return range == 0 ? 0 : abs((int) RN) % range;
    
    main.c lines 186–189 at cf9bd26 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  8. ^An ordinary NetHack 3.6.7 level places rooms, one of which may be a vault, in free rectangles until none is left, a room fails to fit, or it has 40. It sorts them by left edge, and joins each to the next, stopping early at a chance of 1 in 50 per join. It then joins each room to the one two along when they aren't yet connected, then any pair still unconnected. With 3 or more rooms it makes 4 to (room count + 3) attempts at another corridor; an attempt gives up before digging when the square outside its door is already open, and stops short, leaving a dead end, at a chance of 1 in 35 per step.CodeNetHack 3.6.7 sourcerevised
    How we know
    229    while (nroom < MAXNROFROOMS && rnd_rect()) {
    
    src/mklev.c lines 227–239 at ed600d9 · upstream ↗
    330#define MAXNROFROOMS 40 /* max number of rooms per level */
    
    include/global.h line 330 at ed600d9 · upstream ↗
    62    if (x->lx < y->lx)
    
    src/mklev.c lines 62–64 at ed600d9 · upstream ↗
    704    sort_rooms();
    
    src/mklev.c lines 700–704 at ed600d9 · upstream ↗
    341        for (i = rn2(nroom) + 4; i; i--) {
    
    src/mklev.c lines 319–348 at ed600d9 · upstream ↗
    294    if (nxcor && levl[xx + dx][yy + dy].typ)
    
    src/mklev.c lines 294–295 at ed600d9 · upstream ↗
    2248        if (cct++ > 500 || (nxcor && !rn2(35)))
    
    src/sp_lev.c line 2248 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  9. ^NetHack 3.6.7's main dungeon, the Dungeons of Doom, holds one level built in Rogue's style. Its code's comment says “Rogue levels are structured 3 by 3, with each section containing a room or an intersection”, and each of the nine cells is an intersection at a chance of 1 in 5, so long as at least one room is made.CodeNetHack 3.6.7 source
    How we know
    20LEVEL:		"rogue" "R" @ (15, 4)
    
    dat/dungeon.def lines 17–21 at ed600d9 · upstream ↗
    Rogue levels are structured 3 by 3, with each section containing
    src/extralev.c#L209-L213 · upstream ↗
    233            if (!rn2(5) && (nroom || (x < 2 && y < 2))) {
    
    src/extralev.c lines 228–243 at ed600d9 · upstream ↗
    700        makeroguerooms();
    
    src/mklev.c lines 698–701 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  10. ^When a NetHack 3.6.7 hero dies, unless a worn amulet of life saving or the wizard and explore modes' “Die?” prompt saves the hero, the game records the score and ends the program.CodeNetHack 3.6.7 sourcerevised
    How we know
    1201    really_done(how);
    
    src/end.c lines 1168–1201 at ed600d9 · upstream ↗
    1626    nh_terminate(EXIT_SUCCESS);
    
    src/end.c lines 1618–1626 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  11. ^Restoring a NetHack 3.6.7 game deletes the save file once it is read, unless the game is in wizard (debug) or explore mode; in those modes the Unix build asks “Do you want to keep the save file?”. While a restore runs, the Unix build makes the file unreadable, to disallow parallel restores.CodeNetHack 3.6.7 source
    How we know
    901    if (!wizard && !discover)
    
    src/restore.c lines 901–902 at ed600d9 · upstream ↗
    295        (void) chmod(fq_save, 0); /* disallow parallel restores */
    
    sys/unix/unixmain.c line 295 at ed600d9 · upstream ↗
    312                if (yn("Do you want to keep the save file?") == 'n') {
    
    sys/unix/unixmain.c lines 307–319 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  12. ^When a NetHack 3.6.7 hero dies in wizard (debug) or explore mode, from any cause of death from an ordinary death to genocide (not a panic, quitting, escaping, or ascending), and a worn amulet of life saving hasn't already saved the hero, the game asks “Die?”; answering no saves the hero's life and play goes on.CodeNetHack 3.6.7 sourcerevised
    How we know
    1188    if (!survive && (wizard || discover) && how <= GENOCIDED
    1189        && !paranoid_query(ParanoidDie, "Die?")) {
    ⋮
    1192        savelife(how);
    1193        survive = TRUE;
    
    src/end.c lines 1187–1194 at ed600d9 · upstream ↗
    1168    if (Lifesaved && (how <= GENOCIDED)) {
    
    src/end.c lines 1168–1186 at ed600d9 · upstream ↗
    148    GENOCIDED    = 10,
    
    include/hack.h lines 137–153 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Revised after a check by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  13. ^When a NetHack 3.6.7 game starts, it shuffles the descriptions of amulets, potions, rings, scrolls, spellbooks, wands, and venoms within each class, and of helmets, gloves, cloaks, and boots within each of those groups. Water keeps a fixed description, and scrolls, spellbooks, and amulets keep the unique or non-magic ones fixed; a type whose name is already known keeps its description.CodeNetHack 3.6.7 source
    How we know
    179    shuffle_all();
    
    src/o_init.c lines 178–179 at ed600d9 · upstream ↗
    247        AMULET_CLASS, POTION_CLASS, RING_CLASS,  SCROLL_CLASS,
    
    src/o_init.c lines 243–266 at ed600d9 · upstream ↗
    88        if (objects[j].oc_name_known)
    
    src/o_init.c lines 81–95 at ed600d9 · upstream ↗
    208    case POTION_CLASS:
    ⋮
    211        *hi_p = POT_WATER - 1;
    212        break;
    ⋮
    219            if (objects[i].oc_unique || !objects[i].oc_magic)
    220                break;
    221        *hi_p = i - 1;
    
    src/o_init.c lines 208–221 at ed600d9 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

Sources

Code