Skip to main content

NHEMO — NetHack Expert Machine Operator

An automated NetHack 3.6.x player that reads the terminal screen, parses the game state, and makes decisions — just like a human player would, but faster and without getting distracted.

MVP goal: a bot that consistently reaches Minetown as a dwarven Valkyrie.


What NHEMO can do right now

NHEMO v0.1.0 covers dungeon exploration through level 4 of the workflow:

Capability Status
Connect to a live NetHack session via PTY done
Read and parse the terminal screen done
Navigate without walking into walls done
Open and kick locked doors done
Explore rooms systematically (A* pathfinding) done
Descend stairs across multiple dungeon levels done
Detect hunger and eat food from inventory done
Monitor HP and wait in place to heal done

What it cannot do yet: fight monsters (it will flee or die), pick up items, remember previously visited levels, use knowledge about monsters or items, or consult an LLM. See CHANGELOG.md for a full capability breakdown by version.

Player dying miserably...

Player descending one level


Requirements

  • Python 3.12+
  • NetHack 3.6.x — the real ELF binary, not a shell wrapper. Typical paths: /usr/lib/nethack/nethack (Arch), /usr/games/nethack (Debian/Ubuntu)

Important: NHEMO must point at the actual setgid binary. Shell wrappers like /usr/bin/nethack override NETHACKOPTIONS and break the custom configuration.


Installation

pip install nhemo
# or, with uv:
uv add nhemo

Configuration

Create a config.yaml in your working directory before running:

nethack:
  binary_path: "/usr/lib/nethack/nethack"   # adjust for your distro
  playground_dir: "/var/games/nethack"

player:
  role: "Valkyrie"
  race: "Dwarf"
  alignment: "Neutral"
  gender: "Female"

llm:
  mode: "offline"

A fully annotated example with every available option is at config.yaml.example.


Quick Start

# 30-turn smoke test
python -m nhemo

# Watch the bot play live
python -m nhemo --turns 500 --watch

# Slower watch mode, easier to follow
python -m nhemo --turns 500 --watch --delay 0.5

Watch mode display

Running with --watch renders the NetHack screen live, followed by NHEMO's status line and a persistent message log:

This door is locked.                                    <- row 0: game message
                                                        <- rows 1-21: dungeon map
             --------
             |....#.|
             |......|
             |......|
             |......|
             ----.---          +
                ##             @
                #             ##
             ...
    -------.--------    #----.-
    |..............|    #|....|
    |......$........#####|"....###          ----------
    |..............|    #.....|#############..$$.....|
    |..............|`####------   #####     |........|
    ----------------                  ######|.<......|
                                            ----------
NHEMO the Stripling  St:16 Dx:14 Co:17 In:8 Wi:12 Ch:8 Lawful
Dlvl:1 $:0 HP:18(18) Pw:1(1) AC:6 Xp:1/0 T:118
 NHEMO turn 321  action: ---
-- message log --------------------------------------------------
  t 314: This door is locked.
  t 315: This door is locked.
  t 316: This door is locked.
> t 321: This door is locked.                          <- most recent (bold >)

Observability

Logging

# Verbose per-turn decisions
python -m nhemo --turns 200 --watch --log-level DEBUG

# Capture to file (logging goes to stderr, safe to combine with --watch)
python -m nhemo --turns 500 --log-level DEBUG 2>nhemo_debug.log
Level What you see
WARNING (default) Parse failures, bot stuck and giving up
INFO Level transitions, doors opened, stairs descended, food eaten
DEBUG Every turn: position, visited tile count, chosen action and phase

Decision event log

python -m nhemo --turns 200 --log-events /tmp/events.jsonl

Each turn emits one JSON line:

{"turn":42,"screen_mode":"NORMAL","action":"MOVE_E","phase":"pathfind","pos":[12,40],"hp":15,"max_hp":19,"dlvl":"Dlvl:3"}

Flags combine freely:

python -m nhemo --turns 500 --watch --log-events /tmp/events.jsonl --log-level DEBUG 2>nhemo_debug.log

How it works

NHEMO never reads NetHack's internals — it sees only what a human player sees on a terminal. Under the hood it has four layers: a PTY screen reader, a parser that turns raw screen output into structured game state, a behavior-tree decision engine, and a future LLM consultation layer.

Curious about the architecture? See CONTRIBUTING.md for the component overview, module breakdown, and design documents.


Roadmap

Phase Target
V5–V7 Combat, item management, SQLite persistence, knowledge base
V8–V9 LLM integration, full data-driven behavior tree
V10 MVP: consistent Minetown arrival as dwarven Valkyrie
V11+ Mines End, Sokoban, shop interaction, quest completion, ascension

Contributing

See CONTRIBUTING.md.


License

Copyright (C) 2025 Javier Novoa C.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

See LICENSE for the full text.

Metadata

Release files for nhemo 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nhemo 0.1.2
File Size Uploaded
nhemo-0.1.2.tar.gz 63.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nhemo 0.1.2
File Interpreter ABI Platform
nhemo-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 131.6 kB

Release files / nhemo-0.1.2.tar.gz

Download URL nhemo-0.1.2.tar.gz
Size 63.1 kB
Tags Source
SHA-256 checksum
How to use checksums
01929c23ad58b3ec966559c77d4cff44a7ff2b33e9fb323da4e8e9ccd04222d3
BLAKE2b-256 checksum
How to use checksums
55f38acb586f7a519d16d3d10542e0cc8c5502860dd56c30716b14784cdd168b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nhemo-0.1.2-py3-none-any.whl

Download URL nhemo-0.1.2-py3-none-any.whl
Size 68.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
762f6a64d42bda755b1c2a168f6fe3f99a6e0249b5a746ff2915f2da67e26c04
BLAKE2b-256 checksum
How to use checksums
d7dcd941280516f0d34863f79327d80105170093816197c8f4568725736eddcb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page