Skip to content

webapp: load a replay script from the file system - #6

Open
macabeus wants to merge 1 commit into
mainfrom
webapp-load-script
Open

webapp: load a replay script from the file system#6
macabeus wants to merge 1 commit into
mainfrom
webapp-load-script

Conversation

@macabeus

@macabeus macabeus commented Aug 1, 2026

Copy link
Copy Markdown
Owner

The recorder panel could record and replay a script but never open one, so a script saved to disk was write-only. This PR closes the loop.

What's in it

  • script-parser.ts — the exact inverse of the serializer. It shares the serializer's button vocabulary (BUTTON_NAMES / buttonsFromString derive from the same BIT_TO_BUTTON_NAME table), so a button name cannot exist in only one direction.
  • Strict parsing, per-line errors. An unsupported statement is an error with a line number, not a silent skip — a replay that silently dropped a line would "work" and desync. Comments are blanked in place (offsets preserved) so the reported line numbers match the file the user is looking at.
  • Recorder panel: a Load button + error panel; Save and the "From recording start" origin are disabled while no snapshot exists, since both are meaningless before recording begins.
  • 27 new tests (57 total), including a round-trip property pinning parse(serialize(segments)) = segments.
  • docs/examples/klonoa-hidden-minigame.mjs — a real script to load: it boots Klonoa: Empire of Dreams holding A+B+RIGHT+L+R(+UP) and plays a few dodges of the hidden boot-menu minigame.

Verification

  • pnpm test (57), check-types, lint, check-deps all clean.
  • Exercised end-to-end in a browser: loading the example script replays the minigame, and loading a file with bad statements shows the per-line errors instead of replaying a truncated script.

🤖 Generated with Claude Code

The recorder panel could record and replay a script but never open one, so
a script saved to disk was write-only. This adds a Load button backed by a
new script-parser: the exact inverse of the serializer, sharing its button
vocabulary (BUTTON_NAMES / buttonsFromString derive from the same
BIT_TO_BUTTON_NAME table, so a name can't exist in only one direction).

Parsing is strict on purpose: an unsupported statement is a per-line error
shown in the panel, not a silent skip — a replay that dropped a line would
"work" and desync. Comments are blanked in place so error line numbers
survive, and a round-trip property test pins serialize∘parse = identity.

Save and the "From recording start" origin are disabled while no snapshot
exists, since both are meaningless before recording begins.

docs/examples/klonoa-hidden-minigame.mjs is a real script to load: it
boots Klonoa: Empire of Dreams holding A+B+RIGHT+L+R(+UP) and plays a few
dodges of the hidden boot-menu minigame.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant