You feel a wrenching sensation.

Play now at nethack.games

Teleport

NetHack is a 46-year-old roguelike: 442,901 lines of C and Lua that have accumulated layers of intricate and ingenious gameplay rules. It is famous for permadeath: one little mistake can be fatal, and there is no taking it back. This does make it fun, but it can also be a hard game to walk into cold, a game you can only learn by dying, and dying, and dying…

The Teleport edition is designed as a sandbox for learning and exploring the game without permadeath. It is a port of NetHack to JavaScript that runs directly in the browser and plays bit-exactly like the original. But what we’ve added here are some new tools for learning:

Since it has no permadeath, nethack.games will never be a replacement for nethack.alt.org. Here high scores are not authoritative, and savescumming is totally allowed. You can use it to make your own speedrun, to learn how to play, or test a strategy.

Playing

Go to nethack.games to play in any browser; there is nothing to install and no account to make. Start a game, share a link to play with someone, and open the companion when you want to look something up.

The hamburger menu (☰) also runs a few other programs from the same era:


Background: porting NetHack with AI agents

I have been porting NetHack to JavaScript with a swarm of AI coding agents, as best I know how. The reason is that I do not know whether AI agents can reproduce a 442,901-line C and Lua codebase faithfully, bugs and all, and I wanted to find out.

The work is checked by deterministic replay: record a C NetHack session under a fixed PRNG seed, capturing every random number call, game event, and screen; replay the same keystrokes in JavaScript under the same seed; and compare the three, step for step. Where they diverge, I find the first divergence, read the C, and fix the JavaScript. The engine now matches most of the recorded sessions exactly. The commit timeline tracks parity across every commit.

This is my second attempt. An earlier one, Menace, taught me a lot about the codebase and about working with agents; AGENTS.md is where I wrote down what I learned — commit discipline, debugging techniques, and the ways agents tend to go wrong.

The contest

Teleport also runs as a public contest on the same question. Fork teleport-contest and write your own JavaScript port of NetHack, by any method. Every push is scored against public sessions in your own GitHub Actions, and an official judge re-scores all forks against the full public and held-out suite every two hours, updating the leaderboard.

Architecture

See docs/DECISIONS.md for the full design rationale.

Getting started (development)

# Serve locally (no build step needed)
python3 -m http.server 8080
open http://localhost:8080

# Check JS-vs-C parity (three-channel report)
node scripts/pes-report.mjs

# Record a C reference session
cd test/comparison/c-harness && bash setup.sh
python3 run_session.py --seed 42

Documentation

Document Contents
docs/DECISIONS.md Design decisions with rationale
multiplayer/README.md Running the multiplayer relay + client
docs/SESSION_FORMAT.md Session file format reference
docs/LORE.md Porting lessons and debugging techniques
docs/CODEMATCH.md Function-by-function C-to-JS porting tracker
docs/EVENTS.md Game event logging system
docs/CONVENTIONS.md C-to-JS translation conventions
docs/GAMESTATE.md Global game state structure
docs/MONSTERS.md Monster system architecture
docs/COMBAT.md Combat system porting notes
docs/VISION.md Vision and line-of-sight system
yendorbound/README.md The Yendorbound Agent: autonomous NetHack play, architecture, and evaluation
AGENTS.md Agent instructions and methodology

The cardinal rules

  1. Single-threaded contract enforced. modal_guard.js throws if game code fires during a modal wait.
  2. RNG is the source of truth. If RNG sequences diverge, everything else is noise. Fix RNG first.
  3. Read the C, not the comments. Port implementation, including its bugs.
  4. Follow the first divergence. Every subsequent mismatch is a cascade. Fix #1, re-run, repeat.
  5. Don’t revert C-faithful fixes that cause regressions. Regressions from correct code reveal coupled bugs. Fix those bugs — don’t re-break the correct code.

License

NetHack is distributed under the NetHack General Public License. This JavaScript port is a derivative work under the same license.