Skip to content

[Demo] FRLG: replay shared checkpoint scenarios with native engine and semantic actions - #258

Draft
dayfine wants to merge 41 commits into
frlg/stage7-celadonfrom
frlg/checkpoint-replay
Draft

dayfine wants to merge 41 commits into
frlg/stage7-celadonfrom
frlg/checkpoint-replay

Conversation

@dayfine

@dayfine dayfine commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Base: frlg/stage7-celadon (#224). #260 has merged there; its authored loader and shared codec are inherited, outside this diff. This follow-up contains only the broader cross-repository replay diagnostic and an unchanged route-formatting extraction; the loader/data/equivalence checks are in merged #260. No console or production executor behavior changes.

Load the evaluated Parcel checkpoint and run PokemonSimulation #73's seven scenarios through the existing checkpoint engine and native route runner. Semantic action assertions check complete straight walks, facing changes, map transitions and scenes. Ten native negative controls reject invalid pins/bindings/policies/routes and catch missing, extra, reordered or incorrect actions.

The supplied route is independently generated from the Python planner's actual output, never from test expectations. Native movement rules validate it; the native story-cost planner's own alternative is exported separately. A no-interruption OverworldSimWalker control additionally checks holds, fades and connection stalls. Raw engine initialization and walker diagnostics remain visible in the trace.

This is diagnostic-profile conformance, not live-executor parity: scenes/encounters are scripted, the test policy is stop/no-save, production runtime/save/retry options remain unbound, and native STEP/scene fallback behavior is unchanged. The fixtures pin an explicitly labeled preview of #73; this does not adopt unreviewed production plans or alter the approved map resource pin.

How to review: start with devtools/story-replay/README.md and the linked readable shared cases, then PokemonFRLG_StoryReplay_IO.*, PokemonFRLG_StoryReplay_Executor.* and adjacent tests. The route-formatting move is a separate preparation commit; its two functions are unchanged. Inspect moves with:

git diff --color-moved=dimmed-zebra --color-moved-ws=allow-indentation-change origin/frlg/stage7-celadon...frlg/checkpoint-replay

Local validation: eight C++ translation units pass syntax checks, code health against the intended parent has zero failures, fixture bytes and independent Python candidate regeneration match, and CRLF-aware whitespace checks pass. Initial CI found follow-up issues: Windows rejects two missing designated field initializers; Linux builds and completes the successful Parcel scenario/timed control, but failure scenarios expose an entry-failure label mismatch and empty receipt objects serialized as null. These remain unresolved in this draft; this is not ready to merge. Ubuntu uploads the compiled trace. No console/profile/save was used.

Parent sync at 518b44972: retains the merged authored loader, parser/writer split, shared codec, and std::string expectation. Replay registration follows the moved Data/Json_Tests.cpp, and replay IO includes Data/JsonParser.h. Code health against the new base passes. The existing diagnostic failures above remain unresolved; this sync does not make the draft merge-ready. All 10 affected translation units pass local syntax checks. Fresh Linux native CI is running.

Story action table (core stage 3, from #213/#222): ReplayExecutor now runs steps through the same FRLG rows, binding ROUTE, STEP and MASH to its scripted actions and everything else to unsupported, as before; its guard rethrows, so a replay still never reloads. Gate: the FRLG full-run sim (00.01 to 00.27) step trace and all 12 replay reports are byte-identical to the pre-change baseline, StoryReplay 17/17, and the failing FRLG/Pokemon test names (missing CommandLineTests images only) are unchanged.

Merged #222's core stage 8 through #224: the FRLG sim now runs through the same action table as the console and ReplayExecutor; replay reports and the full-run trace are unchanged.

Interrupts between steps in the replay: ReplayExecutor binds the FRLG table to an optional scenario field between_steps (dialog, wild encounter, trainer sight, warp), each cleared one recorded as an "interrupt" action. cases.json stays PokemonSimulation's copy, so the new test is a mutation of parcel-all-events (StoryReplay 18/18); the 12 existing reports are byte-identical.

dayfine and others added 7 commits November 8, 2026 01:27
read_story_checkpoint_export() is the inverse of story_checkpoint_export():
it reads a pokesim-native-checkpoint-export/1 record (the shared checkpoint
through Pokemon::read_story_checkpoint, plus FRLG's menu and supplies) into
the same StoryCheckpoint type that story_checkpoints() holds, so
build_checkpoint() and make_story_segment() take loaded rows unchanged.
The envelope constants are checked, every native field is required and
unknown fields fail, so a record is read as written or refused.

PokemonSimulation's data/story/native/frlg-parcel-00.05.json (its commit
051785fa251f37b71eb661d4b583435d70f69439, the export tool's output for
row 00.05) is built into the program from StoryData/ as
autostory_checkpoint_json(), and load_story_checkpoint() reads it.

Tests: CheckpointExport reads the capture and checks it exports back to
the same file and to the same JSON as table row 00.05, and refuses eight
altered copies; the existing export cases also round-trip every native
field. AutoStory - Simulation runs the loaded 00.05 and the table's 00.05
through FakeGame and compares describe(), the trace, the log lines and
the save pose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
…heckpoint-replay

# Conflicts:
#	SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/AutoStory/PokemonFRLG_AutoStorySimulation_Tests.cpp
@dayfine
dayfine changed the base branch from frlg/stage7-celadon to frlg/checkpoint-json November 8, 2026 21:04
@dayfine
dayfine changed the base branch from frlg/checkpoint-json to frlg/stage7-celadon November 9, 2026 00:12
@dayfine dayfine changed the title FRLG: replay shared checkpoint scenarios with native engine and semantic actions [Demo] FRLG: replay shared checkpoint scenarios with native engine and semantic actions Nov 9, 2026
dayfine and others added 7 commits November 9, 2026 00:19
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
JsonValue::dump() writes an empty JsonObject as "null", so a document
re-dumped after parsing loses every "{}" and the reader sees null. This
test is red until to_nlohmann() builds objects as objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
to_nlohmann() started each object as a default nlohmann::json, which is
null until a key is added, so an empty object came out as null. Build it
as object_t, as arrays already use array_t.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
The replay puts its entry check in the checkpoint's start conditions,
which the engine reports as "start_failed", not "require_failed", so the
entry-not-overworld case got the raw engine code. The JSON dump bug hid
this until now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
One case per container shape, registered from a named table, so a
failure names the shape that lost its type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
dayfine and others added 5 commits November 9, 2026 01:38
ReplayExecutor binds FRLG's rows (story_action_rows()) to its scripted
route, step and scene, and every other action to unsupported, in place of
the per-kind virtuals. Its guard lets a failed step's exception through,
as before: a replay never reloads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Its table's actions point at it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
dayfine and others added 8 commits November 9, 2026 03:38
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Binds the FRLG between-step interrupts (step_interrupts()) to the native
checkpoint replay. A scenario may script what shows before a step
(between_steps: a dialog, a wild encounter, a trainer's sight or a
warp); the look shows it once, and its handler records it as an
"interrupt" action, a warp also losing the pose. Without between_steps
the replay and its reports are as before; cases.json stays
PokemonSimulation's copy, so the new case is a mutation of
parcel-all-events in the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss
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