Update if-journey docs with save/restore completion

Save/restore is now fully implemented in the hybrid interpreter. Updated
open question 7 to reflect completion, marked the what-to-do-next item as
done, and updated the milestone section to include save/restore in the
"what works" list.

Also noted the QuetzalParser off-by-one bug fix (return_pc parsing).
This commit is contained in:
Jared Miller 2026-02-10 10:07:38 -05:00
parent 1ffc4e14c2
commit 5b7cb252b5
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -234,12 +234,14 @@ How hard is it to add words to a z-machine dictionary at runtime? The dictionary
7. Save/restore in the hybrid interpreter 7. Save/restore in the hybrid interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``op_save`` is a stub that always branches false (game prints "Failed."). The infrastructure is mostly there — ``TrivialFilesystem.save_game()`` prompts for a filename and writes to disk, ``QuetzalParser`` can read save files — but two pieces are missing: RESOLVED: save/restore is now fully implemented and working. Key pieces:
- ``QuetzalWriter`` chunk generators (``ifhd``, ``cmem``, ``stks``) are all stubs returning ``"0"`` - ``QuetzalWriter`` chunk generators implemented (``IFhd`` for header, ``CMem`` for XOR-compressed dynamic memory, ``Stks`` for stack frame serialization)
- ``op_save`` doesn't collect game state or call the filesystem - ``op_save`` and ``op_restore`` wired to filesystem layer via ``TrivialFilesystem``
- round-trip tested: save game state, restore it, continue playing
- fixed ``QuetzalParser`` off-by-one bug in return_pc parsing (was reading ptr+3, should be ptr+2)
To make save work: implement ``QuetzalWriter`` (XOR-compress dynamic memory against original story, serialize stack frames into Quetzal format), then wire ``op_save`` to generate the bytes and call ``self._ui.filesystem.save_game(data)``. Restore should be simpler since ``QuetzalParser`` already works — just need to wire ``op_restore`` to call ``filesystem.restore_game()`` and apply the parsed state. Quetzal format is now fully supported for both reading and writing saves.
what to do next what to do next
--------------- ---------------
@ -254,7 +256,7 @@ Concrete next steps, roughly ordered. Update as items get done.
- [x] build level 1 prototype: regardless of interpreter choice, implement the terminal object, IF mode, and subprocess dfrotz path. this proves the MUD-side architecture (mode stack, spectators, save/restore) independently of the interpreter question. (done — see ``docs/how/if-terminal.txt``) - [x] build level 1 prototype: regardless of interpreter choice, implement the terminal object, IF mode, and subprocess dfrotz path. this proves the MUD-side architecture (mode stack, spectators, save/restore) independently of the interpreter question. (done — see ``docs/how/if-terminal.txt``)
- [ ] implement save/restore: finish ``QuetzalWriter`` chunk generators and wire ``op_save``/``op_restore`` to the filesystem layer. restore should be easier since ``QuetzalParser`` already works. - [x] implement save/restore: finished ``QuetzalWriter`` chunk generators (IFhd, CMem, Stks) and wired ``op_save``/``op_restore`` to filesystem. quetzal round-trip now works — can save during gameplay, restore, and continue. also fixed parser off-by-one bug in return_pc.
- [ ] study MojoZork's multiplayer model: read the MultiZork source for how it handles multiple players in one z-machine. document the pattern for our eventual level 4. - [ ] study MojoZork's multiplayer model: read the MultiZork source for how it handles multiple players in one z-machine. document the pattern for our eventual level 4.
@ -273,7 +275,8 @@ What works:
- instruction trace deque (last 20 instructions) for debugging state errors - instruction trace deque (last 20 instructions) for debugging state errors
- smoke test: ``scripts/run_zork1.py`` runs the game headless, exercises core opcode paths - smoke test: ``scripts/run_zork1.py`` runs the game headless, exercises core opcode paths
- parser and lexer: all Zork 1 commands work (look, open mailbox, read leaflet, inventory, take, drop, navigation) - parser and lexer: all Zork 1 commands work (look, open mailbox, read leaflet, inventory, take, drop, navigation)
- the interpreter is fully playable for Zork 1 (save/restore not yet wired — see open question 7) - save/restore: full quetzal format support for persisting and restoring game state
- the interpreter is fully playable for Zork 1
What this enables: What this enables: