Add plan for zvm compatability
This commit is contained in:
parent
bc1a2e5489
commit
243a44e3fb
1 changed files with 239 additions and 0 deletions
239
docs/plans/zmachine-game-compatibility.rst
Normal file
239
docs/plans/zmachine-game-compatibility.rst
Normal 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
|
||||||
Loading…
Reference in a new issue