diff --git a/docs/plans/zmachine-game-compatibility.rst b/docs/plans/zmachine-game-compatibility.rst new file mode 100644 index 0000000..4a2e414 --- /dev/null +++ b/docs/plans/zmachine-game-compatibility.rst @@ -0,0 +1,239 @@ +zmachine game compatibility plan +================================= + +goal: round out the hybrid z-machine interpreter by testing against a variety +of freely available IF games. find what breaks, fix it, build confidence that +the interpreter handles the spec correctly rather than just the two games we +built it against. + +background +---------- + +the interpreter was shaped by tracing two specific games: + +- Zork 1 (V3, 69 opcodes) — the Infocom classic +- Lost Pig (V8/V5, 61 opcodes) — modern Inform, 101K instructions + +this means the implementation is biased toward what those two games exercise. +other games will hit different opcode combinations, edge cases in string +encoding, parser behaviors, object tree structures, and screen model usage. + +version coverage +~~~~~~~~~~~~~~~~ + +V3, V5, and V8 cover essentially everything worth playing: + +- V3: the Infocom catalog (Zork, Hitchhiker's, Planetfall, etc) +- V5: most modern Inform-compiled games (Photopia, Curses, Spider and Web) +- V8: V5 with x8 packed addresses (Lost Pig, some larger Inform games) + +versions we are NOT targeting: + +- V1/V2: original mainframe Zork only. almost nothing uses these. +- V4: tiny transitional version. Trinity is the notable game. maybe 5 games + total ever published. if a V4 game trips a bug we'll fix it (the version + gates already include V4 in the 4-5 range) but we're not seeking them out. +- V6: graphical z-machine. mouse, pictures, complex screen model. only a + handful of late Infocom titles (Zork Zero, Shogun, Arthur, Journey). out + of scope — the MUD is text. +- V7: almost nonexistent. maybe 1-2 games ever. not worth thinking about. + +known stub opcodes +~~~~~~~~~~~~~~~~~~ + +the dispatch table is complete for V3/V5/V8, but ~12 opcodes have "TODO" +docstrings — they're registered but may not work correctly:: + + op_set_colour — color setting (can likely remain a no-op for MUD) + op_throw — throw to catch frame (needs real implementation) + op_print_ret — print embedded string + newline + return true + op_save_v4 — V4 save (store result, not branch) + op_restore_v4 — V4 restore (store result, not branch) + op_piracy — always branch true (standard behavior, stub is fine) + op_sread_v4 — V4 input (like V3 sread but with timing) + op_erase_line — erase current line (display op, can be no-op) + op_get_cursor — get cursor position (display op, needs stub) + op_not_v5 — bitwise NOT, VAR form (should be trivial) + op_encode_text — encode ZSCII to dictionary format + op_print_table — formatted table output + +some of these are fine as no-ops (color, erase_line). others need real +implementations if games use them (throw, print_ret, encode_text). + +phase 1 — acquire games +------------------------ + +download freely available z-machine games from the IF Archive +(https://ifarchive.org). all games below are free to distribute. + +priority targets (well-known, diverse, good coverage): + +V3 games:: + + Hitchhiker's Guide to the Galaxy — Infocom, nasty parser edge cases + NOTE: check if freely available. + Infocom titles are abandonware + but not legally free. skip if + we can't get a legit copy. + +V5 games:: + + Curses — Graham Nelson, 1993. first Inform game. large, + exercises many opcodes. freely available. + Photopia — Adam Cadre, 1998. minimal puzzles, narrative + heavy, lots of text output. free. + Spider and Web — Andrew Plotkin, 1998. notoriously clever parser + tricks, unreliable narrator mechanic. free. + Shade — Andrew Plotkin, 2000. small, atmospheric, + good smoke test. free. + Anchorhead — Michael Gentry, 1998. horror, larger game, + heavy object manipulation. original z-machine + version is free (later Inform 7 version is + commercial — use the original). + Bronze — Emily Short, 2006. tutorial-style, good for + testing standard patterns. free. + Counterfeit Monkey — Emily Short, 2012. complex, large, exercises + advanced Inform features. free. + +V8 games:: + + (Lost Pig already working — look for other V8 titles on IF Archive + to broaden coverage if any exist) + +also worth checking: games compiled with different Inform versions (Inform 5, +6, 7-to-Z) to catch compiler-specific patterns. + +the agent doing this work should: + +1. find each game on ifarchive.org or the author's site +2. download the story file (.z3, .z5, .z8) +3. verify the z-machine version byte (byte 0 of story file) +4. place in content/stories/ with a note about source/license + +phase 2 — smoke test each game +------------------------------- + +for each acquired game, run it through the interpreter and record results. + +use the existing trace infrastructure:: + + scripts/trace_zmachine.py — V3 opcode tracing + scripts/trace_lostpig.py — V5/V8 opcode tracing + +for each game: + +1. run the trace script (or adapt it for the game) +2. record: how many instructions execute, which opcodes are used, + where it crashes (if it crashes) +3. try interactive play for at least 10-15 commands +4. categorize the result: + + - WORKS: plays correctly, no crashes + - CRASHES: hits an unimplemented or buggy opcode (record which one) + - MISBEHAVES: runs but output is wrong (garbled text, wrong responses, + display issues) + - BLOCKS ON INPUT: hangs or mishandles input in some way + +build a results table like:: + + game | version | result | notes + ------------------|---------|------------|--------------------------- + Curses | V5 | CRASHES | op_encode_text at 0x1234 + Photopia | V5 | WORKS | 45K instructions to prompt + Spider and Web | V5 | MISBEHAVES | status line garbled + ... + +phase 3 — fix failures +----------------------- + +group failures by type and fix them: + +missing/stub opcodes +~~~~~~~~~~~~~~~~~~~~ + +for each "TODO" opcode that a real game exercises: + +1. read the z-machine spec (``zmach06e.pdf`` or inform-fiction.org/zmachine) +2. implement per spec +3. add a unit test +4. verify the game that triggered it now works + +spec compliance bugs +~~~~~~~~~~~~~~~~~~~~ + +for opcodes that are implemented but behave wrong: + +1. compare our implementation against the spec +2. check edge cases (signed vs unsigned, overflow, zero-length strings) +3. fix and add regression test + +display/screen model issues +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +V5+ games use the screen model more aggressively than Zork or Lost Pig: + +- window splitting, cursor positioning, text styles +- status line formatting +- output stream selection (stream 3 = memory table) + +these may need MudScreen improvements. the MUD doesn't need pixel-perfect +screen emulation but it needs to not crash and should produce readable output. + +string encoding edge cases +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +different games exercise different parts of ZSCII: + +- alphabet table switching (A0/A1/A2) +- abbreviations (V3 has 32, V5+ has 96) +- unicode extensions +- custom alphabet tables (some games define their own) + +phase 4 — regression harness +----------------------------- + +once games are working, build automated smoke tests: + +- for each game, a script that feeds N commands and checks for crashes +- run as part of ``just check`` or a separate ``just smoke`` target +- catches regressions when we change the interpreter + +the test doesn't need to verify game output is correct — just that the +interpreter doesn't crash, produces output, and reaches the input prompt. + +something like:: + + @pytest.mark.parametrize("game,commands", [ + ("zork1.z3", ["look", "open mailbox", "read leaflet"]), + ("curses.z5", ["look", "inventory", "north"]), + ("photopia.z5", ["look", "yes"]), + ]) + def test_game_smoke(game, commands): + """Run game through interpreter, feed commands, verify no crash.""" + ... + +success criteria +---------------- + +- 5+ freely available games beyond Zork 1 and Lost Pig run without crashes +- all "TODO" stub opcodes that real games exercise have real implementations +- automated smoke tests prevent regressions +- the interpreter handles V3 and V5/V8 games from different compilers + +non-goals +--------- + +- pixel-perfect screen emulation (we're a text MUD) +- V6 graphical games +- V1/V2 support +- multiplayer z-machine (separate effort, see mojozork-audit.rst) +- perfect Infocom compatibility (we care about freely available games first) + +related documents +----------------- + +- ``docs/how/if-journey.rst`` — integration vision and roadmap +- ``docs/how/mojozork-audit.rst`` — multiplayer z-machine audit +- ``docs/how/zmachine-performance.rst`` — performance profiling and optimization +- ``scripts/trace_zmachine.py`` — V3 opcode tracing +- ``scripts/trace_lostpig.py`` — V5/V8 opcode tracing