NetHack Full Logic Port to JS/TS — Checklist
NetHack Full Logic Port to JS/TS — Checklist (English)
0. Core Choices
- Target Version: NetHack 3.7 (trunk) — fewer legacy
#ifdef
s and the latest fixes. - Language: TypeScript (strict) — maps C structs to interfaces with strong typing and IDE support.
- License: Keep the NetHack General Public License (NGPL); include LICENSE and source when publishing.
1. Repository Skeleton
/core ← TypeScript game engine
/dungeon ← generation & topology
/actors ← monsters, player
/items ← objects & inventory rules
/rules ← combat, magic, conducts
/tests ← Jest golden-file tests
/ui-c ← original C "window port" or BrowserHack WASM
/scripts ← build helpers & code-gen scripts
Keep the original C sources under /ui-c/
; remove a C file only after its TS equivalent passes tests.
2. Automated Safety Net
- Deterministic RNG: Make C/WASM read
RNG_SEED
so both engines reproduce the same sequence. - Per-turn state dump: Serialize dungeon map, hero stats, monster list, etc., to JSON.
- Golden-file tests (Jest): Feed identical key sequences to both engines and assert deep equality of the JSON dumps.
3. Translation Guidelines
- C structs → TS: Use
interface
(orclass
if methods are needed). - Bit-field flags: Keep numeric mask values; expose them via a TS
enum
for readability. - Global arrays: Export
const
arrays; generate contents from.h
tables with a small script. - Function-like macros: Rewrite as plain TS functions to remove hidden indirection.
goto
error paths: Replace withtry…finally
or earlyreturn
for clarity.
4. Recommended Port Order (Easy → Hard)
- Utility libraries (e.g.,
hacklib.c
): RNG and string helpers. - Data types:
coord
,obj
,monst
,level
, and all enums. - Save/Load: JSON first; binary compatibility later if desired.
- Dungeon generation:
dungeon.c
,mklev.c
,sp_lev.c
. - Turn loop & timing:
moveloop.c
, energy accounting, hunger clock. - Combat mechanics:
uhitm.c
,mhitu.c
, throwing and hit logic. - Inventory & items: stacking, weight, erosion, polymorph.
- Magic & prayers:
spell.c
,pray.c
,zap.c
. - Edge cases: extinction, genocide, vault guard, demon gating, and other rarities.
- Conducts & scoring: ascend checks, death handling, conduct penalties.
5. Helpful Tooling
- tree-sitter-c → TS stub generator: Parse the C AST and auto-generate TS function signatures.
- clang-format: Normalize indentation in the original C to clarify block structure.
// @ts-expect-error
: Temporarily mute errors for not-yet-ported modules.
6. Incremental Hand-Off Pattern
export function mhitm(mon: Monster, target: Monster | Player): AttackResult {
if (!ported) {
// Fallback to the original C/WASM implementation
return cBindings.mhitm(mon.id, target.id);
}
// Translated TypeScript logic goes here…
}
7. Performance Notes
- Modern JS engines comfortably handle NetHack-scale logic (millions of ops per turn).
- Offload hotspots (e.g., line-of-sight, pathfinding) to small WASM modules if needed.
8. Reference Code
- BrowserHack / NetHackJS: concrete examples of JS shims for the NetHack window interface.
- Hacker News rewrite discussions: practical pitfalls and lessons from earlier attempts.
9. Estimated Effort
- Minimal playable demo: 3–4 months (one developer × 20 h/week).
- Full 3.7 parity: 1–2 years, including edge cases and wizard-mode tools.
10. Next Steps
- Fork NetHack 3.7; add deterministic RNG and per-turn JSON state dumps to the C build.
- Generate TypeScript interfaces from all C structs using a small script.
- Port
hacklib.c
; write the first golden-file test and make it pass.
Comments
Post a Comment