Add plan for zvm compatability

This commit is contained in:
Jared Miller 2026-02-10 16:50:23 -05:00
parent bc1a2e5489
commit 243a44e3fb
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -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