Skip to content

Pokemon navigation core: tile positions and the leg planner - #66

Closed
dayfine wants to merge 15 commits into
mainfrom
nav/core
Closed

dayfine wants to merge 15 commits into
mainfrom
nav/core

Conversation

@dayfine

@dayfine dayfine commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

FRLG and BDSP each built a grid planner for AutoStory, and the two copies share the same ideas but can't serve each other, because each planner is tied to its own map type. This adds the part both games plan on: the grid types (tile positions and directions) and a leg planner that asks the game's step model what one press does and prefers legs that end at a wall, tested on a small made-up game. Everything else that was here moved to where its user lives: ScreenMachine/StepTrace to #108 (BDSP's new-game intro, no navigation dependency), the leg walker to FRLG's #67 (its LegMover is now a small abstract class, so this PR no longer depends on #72 and carries no copy of MoveOnlyFunction), and TileGrid/MapSet to #109 for BDSP's walker and maps, to come back into the core when FRLG adopts them. The plan is docs/design/AutoStory-Navigation-Stack.md on #42.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E

dayfine and others added 3 commits October 29, 2026 17:45
…odel

The planner searches for the cheapest legs (hold one direction, then the
next) and prefers legs that end against a wall. Each game supplies what
one press of a direction does; the planner doesn't know any tile legend.
Tested on a small made-up game.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Holds one leg while watching for what can stop it part-way. On an
interrupt, a leg to a wall is held again and an open leg walks what is
left, estimated from when the interrupt was seen. The bookkeeping is a
plain function, tested with scripted holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Routines that mash a button or hold a direction for a fixed time break when an
input drops or a stray press opens a menu, and nothing notices until much
later. run_screen_machine() is the closed-loop alternative: it reads the
screen (two frames must agree), takes the one step that state calls for, and
fails on a screen the previous state cannot lead to, a state seen too often or
too many times in a row, eight steps that change nothing, or the timeout. A
capture that drops out for up to 10s is waited out.

StepTrace logs each change of recognized screen with a numbered screenshot and
each input, and a failure lists the screens that led to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
std::function is copyable: copying it forks a stateful lambda's state,
and it cannot hold move-only captures. MoveOnlyFunction is an alias of
std::move_only_function where the standard library has it, and a
minimal R(Args...) fallback for Apple's libc++, which lacks it.

Tests: move-only capture, moving keeps one state, empty and nullptr
comparison, reassignment; copy is rejected at compile time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 6 commits October 29, 2026 22:03
The leg walker takes its mover as a MoveOnlyFunction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
LegMover had one method, so it is now a MoveOnlyFunction that holds a
direction for a duration. walk_leg() takes it by reference, since calling
a MoveOnlyFunction is non-const.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The search's maps and queue become a Search struct, and relaxing a node,
expanding a node, the goal search, tracing the moves back and the final
turn each get a function. The search visits nodes in the same order, so
the plans are unchanged.

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

The standard does not make std::move_only_function's move assignment
noexcept, and MSVC's STL does not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Picks up the test fix for MSVC's std::move_only_function, whose move
assignment is not noexcept.

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
dayfine and others added 3 commits October 30, 2026 07:38
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
Move-only: Pokemon_TileGrid.{h,cpp} and Pokemon_MapSet.{h,cpp} are copied
unchanged from bdsp/floaroma-mvp, where the BDSP AutoStory MVP added them,
so the grid and map set sit with the planner and walker they build on.
Their tests stay with the BDSP map data they check.

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 Oct 31, 2026
…fset) and the MVP plan

Section 14 of the lessons: measured movement (D-pad taps are whole tiles,
stick holds drift), the clip-to-wall then D-pad offset route model, what
the screen tells, and the process mistakes. AutoStory-MVP-Plan.md: run 1
stays on fork #68; the compact series stacked on #66 follows it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits October 31, 2026 20:49
…a search cap

Three planner changes the BDSP run made on its branch, ported to the core:
RobustPlanCosts::exact_open_tiles (open legs up to that length land exactly:
D-pad taps move whole tiles), per_open_tile (a long open leg costs more
than a short step after a wall), and max_searched (the set search gives up
after 20000 sets: all of Jubilife from six start tiles ran for minutes,
r224a; town costs or a cropped map are the answer, not a higher cap).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Both games plan on Grid and LegPlanner, so those stay here. The rest
served one game each and moves to its user: ScreenMachine/StepTrace to
common/screen-machine, LegWalker to frlg/brock-mvp (where LegMover is a
small abstract class, so MoveOnlyFunction is no longer needed here),
TileGrid and MapSet to bdsp/tilegrid-mapset. The MoveOnlyFunction copy
of #72 goes with them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
@dayfine dayfine changed the title Pokemon navigation core: leg planner, leg walker, screen machine Pokemon navigation core: tile positions and the leg planner Nov 1, 2026
@dayfine

dayfine commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #114 (commit S2 3209523 of the shared-core collector). Branch kept.

@dayfine dayfine closed this Nov 1, 2026
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