ZWalker is an automated walkthrough generator for Z-machine interactive fiction games. It combines a CZECH-compliant Z-machine interpreter, AI-assisted solvers, and a deterministic replay harness to produce and verify game walkthroughs, primarily as regression tests for the z2js compiler.
โ View Full Documentation & Game Index
The headline result is a corpus of 50 verified complete solves spanning Z-machine versions V1 through V8. It covers a large slice of the Infocom catalogue โ both Zork-era trilogies and Mini-Zork, the Planetfall series, Trinity, A Mind Forever Voyaging, The Hitchhiker's Guide to the Galaxy, Starcross, the three mysteries (Deadline, Suspect, Witness), Suspended, Ballyhoo, Hollywood Hijinx, Cutthroats, Infidel, Plundered Hearts, Moonmist, Leather Goddesses of Phobos, The Lurking Horror โ alongside modern classics (Photopia, Shade, Lost Pig, The Dreamhold) and IF-Comp games. Every game is played start to finish and reproducibly won, verified by deterministic replay against a fixed RNG seed:
| Game | Z-ver | Score | Won | Turns | Commands | Seed | Solution | Walkthrough |
|---|---|---|---|---|---|---|---|---|
| 9:05 | V5 | Win (unscored) | โ | 0 | 20 | 1 | JSON | Text |
| A Mind Forever Voyaging | V4 | Win (unscored) | โ | 0 | 623 | 1 | JSON | Text |
| Adventure (Colossal Cave) | V3 | 350/350 | โ | 290 | 289 | 3 | JSON | Text |
| Adventureland | V5 | 100/100 | โ | 146 | 146 | 3 | JSON | Text |
| All Quiet on the Library Front | V5 | Win (unscored) | โ | 1 | 37 | 1 | JSON | Text |
| All Roads | V5 | Win (unscored) | โ | 0 | 185 | 1 | JSON | Text |
| Balances | V5 | 51/51 | โ | 123 | 124 | 1 | JSON | Text |
| Ballyhoo | V3 | 200/200 | โ | 413 | 415 | 1 | JSON | Text |
| Castle Adventure! | V8 | Win (unscored) | โ | 67 | 277 | 1 | JSON | Text |
| Cloak of Darkness | V3 | Win (unscored) | โ | 4 | 5 | 1 | JSON | Text |
| Cold Iron | V8 | Win (unscored) | โ | 89 | 30 | 1 | JSON | Text |
| Cutthroats | V3 | 250/250 | โ | 416 (clock) | 264 | 1 | JSON | Text |
| Deadline | V3 | Win (unscored) | โ | 10 (clock) | 129 | 1 | JSON | Text |
| Deephome | V5 | Win (unscored) | โ | 11 | 315 | 1 | JSON | Text |
| Detective | V5 | 360/360 | โ | 45 | 45 | 1 | JSON | Text |
| Enchanter | V3 | 400/400 | โ | 300 | 206 | 1 | JSON | Text |
| Hollywood Hijinx | V3 | 150/150 | โ | 395 | 394 | 1 | JSON | Text |
| Infidel | V3 | 400/400 | โ | 305 | 306 | 1 | JSON | Text |
| Leather Goddesses of Phobos | V3 | Win (unscored) | โ | 395 | 373 | 1 | JSON | Text |
| Lost Pig | V8 | 7/7 | โ | 173 | 173 | 1 | JSON | Text |
| Mini-Zork I | V3 | 350/350 | โ | 440 | 405 | 1 | JSON | Text |
| Moonmist | V3 | Win (unscored) | โ | 26 | 86 | 1 | JSON | Text |
| Pentari | V5 | 70/70 | โ | 35 | 35 | 3 | JSON | Text |
| Photopia | V5 | Win (unscored) | โ | 80 | 110 | 1 | JSON | Text |
| Planetfall | V3 | 80/80 | โ | 5165 (GST) | 444 | 1 | JSON | Text |
| Plundered Hearts | V3 | 25/25 | โ | 192 | 186 | 1 | JSON | Text |
| Reverberations | V5 | Win (unscored) | โ | 4 | 72 | 1 | JSON | Text |
| Shade | V5 | Win (unscored) | โ | 124 | 126 | 1 | JSON | Text |
| Sorcerer | V3 | 400/400 | โ | 390 | 234 | 2 | JSON | Text |
| Spellbreaker | V3 | 600/600 | โ | 531 | 422 | 1 | JSON | Text |
| Starcross | V3 | 400/400 | โ | 265 | 240 | 1 | JSON | Text |
| Stationfall | V3 | 80/80 | โ | 5700 (GST) | 375 | 1 | JSON | Text |
| Suspect | V3 | Win (unscored) | โ | 29 (clock) | 110 | 1 | JSON | Text |
| Suspended | V3 | Win (unscored) | โ | 71 | 72 | 1 | JSON | Text |
| Suveh Nux | V5 | Win (unscored) | โ | 0 | 102 | 1 | JSON | Text |
| The Acorn Court | V5 | 30/30 | โ | 18 | 18 | 1 | JSON | Text |
| The Dreamhold | V8 | Win (unscored) | โ | 0 | 438 | 1 | JSON | Text |
| The Edifice | V5 | Win (unscored) | โ | 136 | 142 | 1 | JSON | Text |
| The Hitchhiker's Guide to the Galaxy | V3 | 400/400 | โ | 521 | 466 | 1 | JSON | Text |
| The Jewel of Knowledge | V5 | 90/90 | โ | 246 | 248 | 1 | JSON | Text |
| The Lurking Horror | V3 | 100/100 | โ | 310 | 306 | 1 | JSON | Text |
| The Witness | V3 | Win (unscored) | โ | 42 | 56 | 1 | JSON | Text |
| Theatre | V5 | 50/50 | โ | 295 | 357 | 1 | JSON | Text |
| Trinity | V4 | 100/100 | โ | 485 | 473 | 1 | JSON | Text |
| Wearing the Claw | V5 | Win (unscored) | โ | 159 | 160 | 1 | JSON | Text |
| Wishbringer | V3 | 100/100 | โ | 162 | 179 | 1 | JSON | Text |
| Zork I | V3 | 350/350 | โ | 499 | 431 | 3 | JSON | Text |
| Zork I (Release 5) | V1 | 350/350 | โ | 416 | 418 | 4 | JSON | Text |
| Zork II | V3 | 400/400 | โ | 416 | 386 | 2 | JSON | Text |
| Zork III | V3 | 7/7 | โ | 241 | 216 | 1 | JSON | Text |
Notes on the odd columns: Zork III scores "potential" out of 7; the win is entering the Treasury of Zork and becoming the Dungeon Master. Planetfall's and Stationfall's move counters are their in-game Galactic Standard Time clocks, and the Cutthroats/Deadline/Suspect "clock" turns are their real-time game clocks (the arrest in Deadline/Suspect happens at that hour). Wishbringer and Cutthroats are V3 "time" games โ the status line shows a clock, so the interpreter reads their true score from the games' own globals (GSCORE, RATING). Trinity is V4+, which has no status-line score convention at all, so its SCORE/MOVES globals are mapped per build.
The #% WIN_TEXT: verification path (assert the game's true ending text
instead of a score) covers two kinds of "Win (unscored)" rows. Some games are
genuinely scoreless (9:05, Photopia, Shade, A Mind Forever Voyaging, The
Witness, Moonmist, Suspended, Wearing the Claw, ...). Others are internally
scored and their walkthroughs reach the documented maximum โ Deephome 300/300,
Reverberations 50/50, All Quiet on the Library Front 30/30, Leather Goddesses
of Phobos (which deliberately randomizes its own score and prints "N out of
N") โ but those particular builds keep the score in a global the interpreter
doesn't sample, so the run is verified by the ending text rather than the
number (the winning ending prints the real score, and the walkthrough header
documents it). A few games (Suveh Nux, The Dreamhold, 9:05) also show 0 turns
for the same reason: no move counter in the sampled global. Stationfall's and
Suspect's recordings open with a restart, which re-rolls the game's boot-time
clock on the pinned seed to make the run reproducible. Reproduce any of them
locally:
python3 scripts/replay_solve.py games/zcode/905.z5 walkthroughs/905_verified_win.txt --seeds 2
# -> 905_verified_win.txt: VERIFIED 0/None at seed 1 | 20 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/amfv.z4 walkthroughs/amfv_verified_win.txt --seeds 2
# -> amfv_verified_win.txt: VERIFIED -4134/None at seed 1 | 623 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/advent.z3 walkthroughs/advent_verified_350.txt --seeds 4
# -> advent_verified_350.txt: VERIFIED 350/350 at seed 3 | 289 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/adventureland.z5 walkthroughs/adventureland_verified_100.txt --seeds 4
# -> adventureland_verified_100.txt: VERIFIED 100/100 at seed 3 | 146 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/library.z5 walkthroughs/library_verified_win.txt --seeds 2
# -> library_verified_win.txt: VERIFIED 1/None at seed 1 | 37 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/allroads.z5 walkthroughs/allroads_verified_win.txt --seeds 2
# -> allroads_verified_win.txt: VERIFIED 36/None at seed 1 | 185 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/balances.z5 walkthroughs/balances_verified_51.txt --seeds 2
# -> balances_verified_51.txt: VERIFIED 51/51 at seed 1 | 124 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/ballyhoo.z3 walkthroughs/ballyhoo_verified_200.txt --seeds 2
# -> ballyhoo_verified_200.txt: VERIFIED 200/200 at seed 1 | 415 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/castle_adventure.z8 walkthroughs/castle_adventure_verified_win.txt --seeds 2
# -> castle_adventure_verified_win.txt: VERIFIED 0/None at seed 1 | 277 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/cloak.z3 walkthroughs/cloak_verified_win.txt --seeds 2
# -> cloak_verified_win.txt: VERIFIED 0/None at seed 1 | 5 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/coldiron.z8 walkthroughs/coldiron_verified_win.txt --seeds 2
# -> coldiron_verified_win.txt: VERIFIED 0/None at seed 1 | 30 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/cutthroats.z3 walkthroughs/cutthroats_verified_250.txt --seeds 2
# -> cutthroats_verified_250.txt: VERIFIED 250/250 at seed 1 | 264 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/deadline.z3 walkthroughs/deadline_verified_win.txt --seeds 2
# -> deadline_verified_win.txt: VERIFIED 13/None at seed 1 | 129 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/deephome.z5 walkthroughs/deephome_verified_300.txt --seeds 2
# -> deephome_verified_300.txt: VERIFIED 10/None at seed 1 | 315 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/detective.z5 walkthroughs/detective_verified_360.txt --seeds 2
# -> detective_verified_360.txt: VERIFIED 360/360 at seed 1 | 45 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/enchanter.z3 walkthroughs/enchanter_verified_400.txt --seeds 2
# -> enchanter_verified_400.txt: VERIFIED 400/400 at seed 1 | 206 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/hollywood.z3 walkthroughs/hollywood_verified_150.txt --seeds 2
# -> hollywood_verified_150.txt: VERIFIED 150/150 at seed 1 | 394 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/infidel.z3 walkthroughs/infidel_verified_400.txt --seeds 2
# -> infidel_verified_400.txt: VERIFIED 400/400 at seed 1 | 306 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/lgop.z3 walkthroughs/lgop_verified_win.txt --seeds 2
# -> lgop_verified_win.txt: VERIFIED 321/None at seed 1 | 373 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/lostpig.z8 walkthroughs/lostpig_verified_7.txt --seeds 2
# -> lostpig_verified_7.txt: VERIFIED 7/7 at seed 1 | 173 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/minizork.z3 walkthroughs/minizork_verified_350.txt --seeds 2
# -> minizork_verified_350.txt: VERIFIED 350/350 at seed 1 | 405 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/moonmist.z3 walkthroughs/moonmist_verified_win.txt --seeds 2
# -> moonmist_verified_win.txt: VERIFIED 21/None at seed 1 | 86 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/pentari.z5 walkthroughs/pentari_verified_70.txt --seeds 4
# -> pentari_verified_70.txt: VERIFIED 70/70 at seed 3 | 35 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/photopia.z5 walkthroughs/photopia_verified_win.txt --seeds 2
# -> photopia_verified_win.txt: VERIFIED 2/None at seed 1 | 110 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/planetfall.z3 walkthroughs/planetfall_verified_80.txt --seeds 2
# -> planetfall_verified_80.txt: VERIFIED 80/80 at seed 1 | 444 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/plundered.z3 walkthroughs/plundered_verified_25.txt --seeds 2
# -> plundered_verified_25.txt: VERIFIED 25/25 at seed 1 | 186 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/reverb.z5 walkthroughs/reverb_verified_50.txt --seeds 2
# -> reverb_verified_50.txt: VERIFIED 3/None at seed 1 | 72 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/shade.z5 walkthroughs/shade_verified_win.txt --seeds 2
# -> shade_verified_win.txt: VERIFIED 0/None at seed 1 | 126 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/sorcerer.z3 walkthroughs/sorcerer_verified_400.txt --seeds 3
# -> sorcerer_verified_400.txt: VERIFIED 400/400 at seed 2 | 234 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/spellbreaker.z3 walkthroughs/spellbreaker_verified_600.txt --seeds 2
# -> spellbreaker_verified_600.txt: VERIFIED 600/600 at seed 1 | 422 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/starcross.z3 walkthroughs/starcross_verified_400.txt --seeds 2
# -> starcross_verified_400.txt: VERIFIED 400/400 at seed 1 | 240 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/stationfall.z3 walkthroughs/stationfall_verified_80.txt --seeds 2
# -> stationfall_verified_80.txt: VERIFIED 80/80 at seed 1 | 375 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/suspect.z3 walkthroughs/suspect_verified_win.txt --seeds 2
# -> suspect_verified_win.txt: VERIFIED 23/None at seed 1 | 110 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/suspended.z3 walkthroughs/suspended_verified_win.txt --seeds 2
# -> suspended_verified_win.txt: VERIFIED 0/None at seed 1 | 72 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/suveh_nux.z5 walkthroughs/suveh_nux_verified_win.txt --seeds 2
# -> suveh_nux_verified_win.txt: VERIFIED 0/None at seed 1 | 102 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/acorncourt.z5 walkthroughs/acorncourt_verified_30.txt --seeds 2
# -> acorncourt_verified_30.txt: VERIFIED 30/30 at seed 1 | 18 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/dreamhold.z8 walkthroughs/dreamhold_verified_win.txt --seeds 2
# -> dreamhold_verified_win.txt: VERIFIED 0/None at seed 1 | 438 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/edifice.z5 walkthroughs/edifice_verified_win.txt --seeds 2
# -> edifice_verified_win.txt: VERIFIED 0/None at seed 1 | 142 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/hhgg.z3 walkthroughs/hhgg_verified_400.txt --seeds 2
# -> hhgg_verified_400.txt: VERIFIED 400/400 at seed 1 | 466 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/jewel.z5 walkthroughs/jewel_verified_90.txt --seeds 2
# -> jewel_verified_90.txt: VERIFIED 90/90 at seed 1 | 248 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/lurking.z3 walkthroughs/lurking_verified_100.txt --seeds 2
# -> lurking_verified_100.txt: VERIFIED 100/100 at seed 1 | 306 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/witness.z3 walkthroughs/witness_verified_win.txt --seeds 2
# -> witness_verified_win.txt: VERIFIED 0/None at seed 1 | 56 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/theatre.z5 walkthroughs/theatre_verified_50.txt --seeds 2
# -> theatre_verified_50.txt: VERIFIED 50/50 at seed 1 | 357 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/trinity.z4 walkthroughs/trinity_verified_100.txt --seeds 2
# -> trinity_verified_100.txt: VERIFIED 100/100 at seed 1 | 473 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/wearing_the_claw.z5 walkthroughs/wearing_the_claw_verified_win.txt --seeds 2
# -> wearing_the_claw_verified_win.txt: VERIFIED 0/None at seed 1 | 160 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/wishbringer.z3 walkthroughs/wishbringer_verified_100.txt --seeds 2
# -> wishbringer_verified_100.txt: VERIFIED 100/100 at seed 1 | 179 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/zork1.z3 walkthroughs/zork1_verified_350.txt --seeds 4
# -> zork1_verified_350.txt: VERIFIED 350/350 at seed 3 | 431 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/zork1-r5.z1 walkthroughs/zork1-r5_verified_350.txt --seeds 5
# -> zork1-r5_verified_350.txt: VERIFIED 350/350 at seed 4 | 418 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/zork2.z3 walkthroughs/zork2_verified_400.txt --seeds 3
# -> zork2_verified_400.txt: VERIFIED 400/400 at seed 2 | 386 cmds | died=False | won=True
python3 scripts/replay_solve.py games/zcode/zork_iii.z3 walkthroughs/zork3_verified_7.txt --seeds 2
# -> zork3_verified_7.txt: VERIFIED 7/7 at seed 1 | 216 cmds | died=False | won=TrueBeyond the verified solves, the repo carries exploration-grade coverage data: 43 room-mapping
walkthrough dumps in games/results/ and 73 batch solver runs in solutions/. These map
rooms and exercise the parser for compiler regression testing โ they are not complete
solutions and are labeled accordingly.
-
๐ฎ Z-Machine Interpreter: 100% CZECH compliance โ 1,604/1,604 tests passing across versions 3, 4, 5, and 8 (v3: 368, v4: 386, v5: 425, v8: 425)
- Plays Z-machine versions 1โ5 and 8 (v6/v7 screen model not supported); CZECH-verified on 3, 4, 5, 8
- Accurate opcode implementation, full state save/restore
-
โ Deterministic Replay Verification:
scripts/replay_solve.pyreplays a walkthrough with a pinned RNG seed and searches seeds until random events (combat, thief, wizard) line up โ making "did we really win?" a reproducible yes/no -
๐ค AI-Assisted Solving: multiple solver generations
- Agentic solver (
zwalker/agentic_solver.py): perceiveโdecideโactโverify loop with BFS navigation, world model, and checkpoint backtracking; runs free with a local decider or with Claude via API - Strategic LLM solver (
zwalker/advanced_solver.py) and assist layer (zwalker/ai_assist.py) - Persistent cross-run knowledge base (
zwalker/knowledge.py)
- Agentic solver (
-
๐งช Compiler Testing: validate z2js and other compilers
- Convert solutions into Node.js replay test scripts (155 tracked, including 73 "smart" tests that tolerate random events)
- Compare outputs between interpreters, detect regressions automatically
-
๐ Game Exploration: automated mapping and analysis
- Room discovery and mapping, object detection and tracking
- Command success/failure analysis
Not yet published to PyPI โ install from source:
git clone https://github.com/avwohl/zwalker.git
cd zwalker
pip install -e .
# with AI backends (anthropic, openai)
pip install -e ".[ai]"# Explore a game and generate a map
zwalker explore game.z5 --max-rooms 50 --json walkthrough.json
# Use AI assistance (requires ANTHROPIC_API_KEY)
zwalker explore game.z5 --ai --ai-backend anthropic --max-rooms 100
# Interactive play mode
zwalker play game.z5python3 scripts/replay_solve.py games/zcode/zork1.z3 walkthroughs/zork1_verified_350.txt --seeds 4from zwalker.zmachine import ZMachine
from zwalker.walker import GameWalker
from zwalker.ai_assist import AIAssistant
# Load and explore a game
game_data = open('game.z5', 'rb').read()
walker = GameWalker(game_data)
# Start game
output = walker.start()
print(output)
# Explore with AI
ai = AIAssistant(backend='anthropic')
results = walker.explore_with_ai(ai, max_commands=20)
# Save walkthrough
walkthrough = walker.get_walkthrough_json()# Solve a game (iterations fixed at 50; add --real-ai for LLM assistance)
python scripts/solve_game.py game.z5 --real-ai
# Compare interpreter output against a recorded solution
python scripts/compare_outputs.py solutions/lostpig_solution.jsonZWalker was built to provide regression testing for the z2js compiler (ZIL/ZILF to JavaScript).
The Problem: z2js was released with bugs that upset users due to lack of testing.
The Solution: ZWalker generates comprehensive test walkthroughs that can be:
- Generated from a known-good .z compile
- Replayed on new compiles to detect regressions
- Used to compare output between interpreters
# Generate JS test scripts from recorded solutions (smart tests handle random events)
python scripts/generate_all_smart_tests.py
# Run the z2js regression suite
./scripts/run_smart_tests.shSee docs/TEST_GENERATION.md for the full pipeline.
Automatically map and analyze IF games:
zwalker explore game.z5 --thorough --commandsGenerate test coverage for your IF game:
python scripts/solve_game.py your_game.z5 --real-aiVersion: 0.1.0 (Alpha)
What Works:
- โ Z-machine interpreter (1,604/1,604 CZECH tests across v3/v4/v5/v8)
- โ Verified complete solves: Zork I 350/350, Zork II 400/400, Zork III 7/7, Enchanter 400/400, Sorcerer 400/400, Spellbreaker 600/600, Planetfall 80/80, Wishbringer 100/100, Stationfall 80/80 (deterministic replay)
- โ
Replay/verification harness (
scripts/replay_solve.py) - โ Agentic solver with navigation, world model, and backtracking
- โ Walkthrough generation and z2js test-script generation
- โ Output comparison tools
Current Limitations:
- Most games beyond the 50 verified solves have exploration coverage only, not verified wins
- Menu-based IF and Y/N prompts need special handling
- Complex opening puzzles can stall the AI solvers
See TODO.md for current status and docs/CHANGELOG.md for interpreter fixes. Historical reports live in docs/archive/.
- CHANGELOG.md - Z-machine bug fixes
- ZORKIE_TESTING.md - using the verified solves to test the zorkie ZIL compiler, and why released
.zโ compiled historicalsource ZIL - TEST_GENERATION.md - z2js test pipeline
- ADVANCED_SOLVER.md - strategic solver design (Dec 2025)
- PROJECT_NOTES.md - project overview and approach
- docs/archive/ - historical status and progress reports
zwalker/
โโโ zmachine.py # Z-machine interpreter (1,604/1,604 CZECH tests)
โโโ walker.py # Game exploration engine
โโโ agentic_solver.py # Agentic solver: perceiveโactโverify + navigation + backtracking
โโโ advanced_solver.py # Strategic LLM solver (multi-turn planning)
โโโ ai_assist.py # AI integration (Claude, GPT, local)
โโโ knowledge.py # Persistent cross-run knowledge base
โโโ cli.py # Command-line interface
scripts/ # (selection)
โโโ replay_solve.py # Deterministic seed-search walkthrough verifier
โโโ solve_zork3_adaptive.py # Adaptive recorder that produced the Zork III solve
โโโ solve_enchanter_adaptive.py # Adaptive recorder for the Enchanter solve
โโโ solve_sorcerer_adaptive.py # Adaptive recorder for the Sorcerer solve
โโโ solve_spellbreaker_adaptive.py # Adaptive recorder for the Spellbreaker solve
โโโ solve_planetfall_adaptive.py # Adaptive recorder for the Planetfall solve
โโโ solve_wishbringer_adaptive.py # Adaptive recorder for the Wishbringer solve
โโโ solve_stationfall_adaptive.py # Adaptive recorder for the Stationfall solve
โโโ debug_replay.py # Transcript-printing replayer for walkthrough debugging
โโโ solve_game.py # Single game AI solver
โโโ generate_all_smart_tests.py # z2js test generation (random-event tolerant)
โโโ compare_outputs.py # Output comparison tool
โโโ generate_docs_pages.py # Regenerates docs/WALKTHROUGHS.html from repo data
docs/ # Documentation + GitHub Pages site
solutions/ # Solution JSONs (50 verified solves + exploration runs)
walkthroughs/ # Human + verified walkthroughs (text + JSON command lists)
games/zcode/ # Game corpus (155 story files)
games/results/ # Exploration walkthrough dumps (43 games)
tests/ # Interpreter regression tests
Contributions welcome! Areas needing improvement:
- More Verified Solves: extend the adaptive-recorder treatment to other games
- Menu Detection: better handling of menu-based IF and Y/N prompts
- Puzzle Solving: improved AI strategies for complex puzzles
- More Games: test coverage for additional IF games
GPL v3 License - see LICENSE file.
- Z-Machine Spec: Based on the Z-Machine Standards Document
- CZECH Test Suite: Compliance testing by Amir Karger
- AI Assistance: Powered by Anthropic Claude and OpenAI
- Source: https://github.com/avwohl/zwalker
- Issues: https://github.com/avwohl/zwalker/issues
- z2js Compiler: https://github.com/avwohl/z2js
- IF Archive: https://www.ifarchive.org/
- IFDB: https://ifdb.org/
Built to prevent "pissing off users" by providing comprehensive testing for the z2js compiler. Thanks to the Interactive Fiction community for their feedback and patience.
Note: This is alpha software under active development. Use for testing and exploration. Bug reports and contributions welcome!