Skip to content

Pokemon navigation: shared story steps and one retry policy for AutoStory - #122

Draft
dayfine wants to merge 20 commits into
nav/sharedfrom
nav/story-steps
Draft

dayfine wants to merge 20 commits into
nav/sharedfrom
nav/story-steps

Conversation

@dayfine

@dayfine dayfine commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Depends on #114 (and through it #43–#45).

FRLG's story was a declarative table and BDSP's a list of wrapped functions, with no shared way to say "walk here, talk, answer YES, fight". This adds one step vocabulary (Pokemon_StorySteps.h), with a builder from table rows to engine events and an executor interface each game implements, and one StoryRunOptions group both programs embed: start and end checkpoint dropdowns (#43's select database, joined at #44's story_index()), attempts per checkpoint, stop at the first failure, a Thorough/Fast checks level and the game's language. SegmentPolicy is the one place retries are set, and record_story_stats() adds a run to #45's AutoStoryStats. Tested with the StorySteps suite against a fake executor (event order, skip conditions, poses, failures, the retry policy, the options and the stats) and the existing StorySegments suite in fork CI; no console runs of its own.

Design note
  • Shared types. StoryStep{kind, name, why, target (Pose), direction, legs, fight_wild, yes, may_lose, battles, items, variant, skip_if, pose_after} and StoryCheckpoint{id, title, start (Pose), steps}. build_story_checkpoint() emits a from_save event for the start pose, then one event per step; saving stays the game's (FRLG saves at the end, BDSP at the start).
  • Executor. StoryStepExecutor has one virtual per kind, each failing as unsupported_step unless overridden, so a table using a kind the game lacks fails by name. Chosen over a table of std::function because a fake overrides only what a test needs, and the kinds stay one list. run() wraps every step (FRLG turns console exceptions into failed Outcomes; BDSP goes through its runner for screenshots and the lab log line). begin_attempt() is called once per attempt. holds() answers skip_if, by default from run flags that earlier steps set.
  • Game extras. Per-checkpoint data rides in the game's row type, derived from StoryCheckpoint (FRLG: supplies and START menu; BDSP: what a failure does). Per-step extras go in variant: BDSP route plan costs (town, robust), D-pad legs that may end a tile short, and segment-registered variants for the Mart lady, the signs' gap and the Jubilife stairs. Trainer sight lives in BDSP's executor (its route kind fights who sees us; trainers reset per attempt). Door line-up is inside BDSP's HEAL (lit doorway by sight).
  • Poses. Game-defined through the existing Pose/TilePose: FRLG one-tile poses with facing; BDSP sets of world tiles. Executors return where a step left the player; pose_after covers scenes.
  • FRLG. Every kind maps 1:1 (NEW_GAME, OPTIONS was SET_OPTIONS, ROUTE, LEGS, STEP, TALK, ANSWER, MASH, BATTLE, HEAL, SHOP with its items now in the table, READY).
  • BDSP 00.04 after the catch. Train → ROUTE to the catch grass + TRAIN 3. Center → ROUTE into Sandgem (robust) + ROUTE to the sign (town) + LEGS west taps (one short ok) + HEAL. Mart lady → SHOP variant (lady, clerk after two misses), ending on Route 202's save spot. Save → the row's start save. Route 202 north → ROUTE to the exit rows with trainer sight. Jubilife scene → STEP variant (the stairs) + MASH.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E

dayfine and others added 3 commits November 1, 2026 09:53
A story checkpoint as a list of StorySteps (route, legs, step onto a
trigger, talk, YES/NO, scene, battle, train, heal, shop, save, ready for
a boss, and a game-only step), plain data, built into engine events by
build_story_checkpoint(). Each event asks the game's StoryStepExecutor
to do its step: one virtual per kind, failing as unsupported unless the
game overrides it. Poses are the game's (TilePose); skip_if names
conditions the executor answers.

Tests run tables against a fake executor: event order, skip_if, pose
propagation, failure naming, unsupported kinds, a segment with a reload,
and lint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
SegmentPolicy is now where retries are set: attempts per checkpoint
(default 3), stop at the first failure (no reload; the game stays where
it failed), and in-place recoveries per event (SegmentHooks::recover,
then the event again) before a checkpoint is reloaded, default 0.
run_segment reports each checkpoint's attempts and recoveries and logs
"[Checkpoint] 00.07: passed on attempt 2 (1 reset)" and "[Segment] 00:
2 of 3 checkpoints one-shot", so the one-shot rate can be tracked.

StoryRunOptions is the program-option group both AutoStory programs
embed: "Attempts per checkpoint" and "Stop at the first failure". A
story step's skip_if condition is a run flag unless the game overrides
holds(). Tests: the policy against the fake executor (attempts then
fail, stop at first failure, recover in place, one-shot report).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
build_story_checkpoint() calls StoryStepExecutor::begin_attempt() before
building, once per attempt, so a game can start the attempt afresh (BDSP:
the trainers who can see us again; the row's failure mode).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits November 1, 2026 10:32
…r Fast)

StoryChecks: THOROUGH steps read the screen to confirm what they did
(purchases, the Bag, status after battles, position); FAST trusts counts
and timings. Each game decides what its steps check at each level. The
executor carries it (checks(), set_checks(); THOROUGH by default), and
StoryRunOptions gains a "Checks" dropdown, Thorough by default, read with
checks(). Tests: the level reaches a step; the option group's defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
…eed it

StoryRunOptions gains "Game language" (any language the games have,
English by default, never refused for lacking a reader), and the executor
carries it (language(), set_language()) for the few reads that need text:
item names in a shop or the Bag. The header states the rule: steps never
match dialogue or menu text, and a game with no reader for the language
falls back to language-free checks. Tests: the option's choices and the
executor's language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
dayfine added a commit that referenced this pull request Nov 1, 2026
…s PR

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits November 1, 2026 12:34
…d AutoStory stats, for story runs

StoryRunOptions (now "Story Run") takes the game's checkpoint database
and shows Start and End checkpoint dropdowns, labeled as SV labels its
segments ("00.09 Pewter Gym: Camper Liam, then Brock") and built with
#43's make_story_select_database(); a story in sections passes them joined,
so a section's entry is at #44's story_index(). A start after the end is
refused. record_story_stats() adds a segment's run to #45's
AutoStoryStats: the segment, each passed checkpoint, each reload.

Tests: the dropdowns' labels, slugs and defaults, the start/end check,
and the stats.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
The program's integer START/END options give way to the shared story run
options' checkpoint dropdowns (#122), labelled from the table ("00.09
Pewter Gym: Camper Liam, then Brock"), and it counts the shared
AutoStoryStats (#45): a segment per run, the checkpoints passed and the
reloads. The reload and log hooks move into a helper, keeping program()
under the function size limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
The story maps, devtools/maps/bdsp_maps.py and the CMake embed are
maps-v4's (add/add conflicts resolved to its versions); this brings in
nav/story-steps (#122) underneath. The per-map grids still load the maps
here until the next commits move them onto the shared MapData.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
… stats) into bdsp/autostory-v4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 4 commits November 1, 2026 14:15
…y) into nav/story-steps

# Conflicts:
#	SerialPrograms/Source/Pokemon/Navigation/Pokemon_Navigation_Tests.h
#	SerialPrograms/cmake/SourceFiles.cmake
StorySteps and its tests move unchanged to Pokemon/AutoStory, next to the
events and segments they build on (#114), and register from
Pokemon_AutoStory_Tests.h. The story run options include them from there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Code health limits a class's public methods: the methods a game overrides
for each step kind are now protected, reached through
dispatch_story_step(), so an executor's public face is the attempt, the
checks and language, run() and holds(). The test fake follows, and the
segment-of-tables test moves its setup into a helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
The executor's and the simulation fake's step-kind overrides are
protected, as the shared executor declares them (#122); the table's walks
say WildBattles::FIGHT instead of a defaulted bool; the battle loop's body
is braced on its own lines; and the panel list keeps its length.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
dayfine added a commit that referenced this pull request Nov 1, 2026
#122 made Grid's at() read-only and added cell_at() for writes; the
story world and the Ravaged Path's smashed rocks follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
…/story-steps

# Conflicts:
#	SerialPrograms/Source/Pokemon/AutoStory/Pokemon_StorySegments.cpp
#	SerialPrograms/Source/Pokemon/AutoStory/Pokemon_StorySegments.h
@dayfine dayfine added autostory AutoStory programs game:shared Shared or game-neutral code navigation Maps, planner, walker labels Nov 1, 2026
dayfine added a commit that referenced this pull request Nov 1, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
…into nav/story-steps

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 5 commits November 2, 2026 07:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Verify mode, a toggle group in the story run options, runs the start
checkpoint, which must also be the end, a set number of times from its
save without saving at its end, and needs a set number of them to pass
(3 and 2 by default). VERIFY.policy() gives the policy for
verify_checkpoint(), unset when the mode is off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autostory AutoStory programs game:shared Shared or game-neutral code navigation Maps, planner, walker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant