diff --git a/docs/design/AutoStory-Map-Reuse-Review.md b/docs/design/AutoStory-Map-Reuse-Review.md new file mode 100644 index 0000000000..ab349d574b --- /dev/null +++ b/docs/design/AutoStory-Map-Reuse-Review.md @@ -0,0 +1,206 @@ +# AutoStory review: prove map reuse in a FireRed demo + +Status: proposed plan revision, 2026-10-28. This updates implementation order; +it does not record new user approval of a fixed interface or hardware budget. +Read alongside [AutoStory.md](AutoStory.md). The concrete implementation slices, +JSON map format and RNG handoffs are in the +[FRLG demo work plan](FRLG-Demo-Work-Plan.md). + +## Evidence and scope + +- Existing design: `0443b0332264c79a7b6a8ffa6ade30a92c0587fc`. +- SV extraction draft stack #43–47: `autostory/r5-dev-tests` at `bad944993`. +- SwSh upstream #1207: `32d506c273879244e0ffc10c59ee01da2d30865e`. +- BDSP upstream #1717 baseline: `65094d4cd`; our segment work starts from + `bdsp/1717-seg00`, with the reviewed map/walk implementation present at + `bdsp/new-game-intro-v2:6dbcc8e10`. The active branch advanced during the + review to `a5f91acde`; that is not a frozen validation build. +- Source and recorded lab lessons were inspected. No console execution or + new build/test run was performed for this documentation review. + +## Recommendation + +Use the existing shared map/planner and screen modules as candidate +implementations. Build a small FRLG adapter and an observed story slice +before settling a common route executor. A small prerequisite extraction +is justified when the demo calls it immediately. Migrating the Elite Four +farmer, SV registries, or all of BDSP is not a prerequisite. + +There are two demos with different purposes: + +1. **Startup demo:** fresh FireRed, supported player-name entry and explicit starter, + bedroom → Oak → starter → lab rival resolved → verified post-rival save. + Optional handoffs prepare SID Helper and Starter RNG; those paths save + the new identity before any reset and preserve the pre-starter checkpoint. + This tests screen handling, short walks, battle outcomes and the first + save. Before a verified save exists, recovery must explicitly restart + the fresh-game flow or stop; it cannot load an assumed checkpoint. +2. **Map demo:** from a prepared, verified post-rival save, leave the lab, + cross Pallet/Route 1 into Viridian, collect Oak's Parcel, return and + deliver it, then verify the Pokédex and save. This demonstrates an + outdoor map connection, building entry/exit, NPC interaction, a grass + interruption, re-localization and checkpoint recovery. First run it + independently from that prepared save, then chain it to startup. + +The map demo is the more useful architectural experiment. It may be built +first while new-game detectors are still being collected. A single starter +and English are enough for the experiment; broader starter choice remains +an implementation decision. The lab-rival routine must report the observed +outcome: story progress, health and level assumptions depend on it. + +## What to reuse from SV + +Drafts #43–46 already implement selection/range helpers, shared stats and a +retry loop. The common files total about 195 physical lines, with another +160 lines of SV hooks. Reuse their implementation through an explicit +prerequisite/reviewed extraction, not a second copy. #47 moves an SV-only +developer harness and contributes nothing required by FRLG. + +The retry draft preserves SV's legacy behavior: the default limit executes +102 attempts, and a failed initial save can be followed by running the +action after a reset without establishing a new checkpoint save. That is +not the FRLG recovery contract. Keep SV compatibility explicit; FRLG needs +an exact attempt budget and a verified rollback location. A reset failure +must stop, not be counted as a successful recovery. + +Keep SV navigation, battle/dialog interpretation, options and registries +in SV. Claim Mystery Gift calls the exported SV segment list; a generic +registry rewrite would affect another existing program. + +The current fake tests cover five retry cases and three index cases. They +do not prove the SV adapter, reset-failure propagation, a second game, or +hardware operation. Existing draft implementation is distinct from rollout +approval and cross-game validation. + +## What BDSP has already made reusable + +Paths below are under `SerialPrograms/Source/`. + +| Module | Present implementation | Reuse decision | +|---|---|---| +| `CommonTools/ScreenMachine/` | Screen matching, stable observations, bounded visits, transitions, stall checks and StepTrace | Reuse for FRLG screens; supply FRLG detectors/actions and test actual timeout/terminal behavior | +| `Pokemon/Navigation/Pokemon_TileGrid.*` | Tile parsing, stepping, wall hits, path search, trainer sight and possible-position planning | Already in shared code; reuse the supported subset with FRLG fixtures | +| `Pokemon/Navigation/Pokemon_MapSet.*` | Places adjoining maps on a single grid and translates local/world coordinates | Reuse only for physically adjoining outdoor maps | +| BDSP `AutoStory_RouteWalk.*` | Execution, timing estimates, banners, trainer dialogs, obstacle handling, replanning | Keep the BDSP implementation; derive a smaller shared execution policy after a working FRLG adapter | +| BDSP `AutoStory_Walk.*` and matchers | Screen motion, interruptions, battle-vs-transition checks and landmarks | Keep perception, timings and battle decisions per game | +| BDSP maps, trainer locations and story checkpoints | Hand-authored and console-corrected story data | Keep in BDSP; FRLG supplies its own reviewed map data | + +At the reviewed BDSP revision, ScreenMachine/StepTrace total 329 lines; +TileGrid/MapSet total 932. They are already in shared folders: extracting +these again would duplicate work. Generic navigation tests currently live +inside BDSP's AutoStory test registration; separate pure map/planner tests +from BDSP map fixtures when FRLG becomes a consumer. + +Recorded evidence is limited: the lessons document reports 00.04 completed +unattended in r79; 00.05 was stepped through to the PC and subsequently +coded. Those are different evidence levels, neither a repeated FRLG run +nor proof that the executor is generic. + +## Map structure to test + +Use these responsibilities as a working division, not a frozen C++ interface: + +- **Map data per game:** terrain, directional traversal, connections, + warp destinations, scripted triggers and NPC/trainer metadata. Maintain + provenance and a pinned source revision. For FRLG, inspect decomp map, + layout, collision/behavior and script data together; a picture or event + coordinate alone is not proof a tile is traversable. +- **Shared spatial model and planning:** positions, supported traversal, + route search, candidate-position propagation, anchor goals. Keep console, + OCR, controller and battle dependencies out of this module. +- **Per-game observation and movement adapter:** translate a leg to inputs, + interpret a stopped camera/battle/dialog, and provide position evidence. + FRLG frame timing and BDSP analog movement remain separate. +- **Story execution per game:** resolve the interaction or battle, verify + its postcondition, update story facts, then continue or reset to a known + save. Share common orchestration only where both adapters exercise it. + +A map coordinate needs a map identity. `MapSet` is a joined outdoor canvas; +a Mart interior or upstairs room is not another adjacent rectangle. Treat +warp/door actions as explicit transitions, verify the destination and its +arrival tile, then plan on that map. The current planner deliberately +rejects doors and unknown edges; preserve that protection during the demo. + +Keep static terrain separate in meaning from current occupancy and story +facts. A wandering NPC blocking a step is temporary; a beaten trainer may +still block a tile; a door may lead into a cutscene. The first demo needs +only its actual states and transitions, not a universal world simulator. + +Limits to resolve before calling the existing map implementation general: + +- `TileType::LEDGE` currently supports southward jumps only. Add other + traversal rules only where the selected FRLG route requires them. +- `at_wall()` treats NPC tiles as anchors. A movable NPC is not a durable + position reference. Use fixed terrain for demo anchors. +- `TrainerSight` is a straight ray with a fixed facing/range. Do not infer + an encountered trainer's identity solely from list order when multiple + sight lines fit. Dynamic facing and defeated flags need game evidence. +- The robust planner proves a result only within its supplied map and + movement-error model. `planned.after` is a prediction, not a screen read. + Unknown position must remain unknown until an anchor/landmark resolves it. +- BDSP's current executor estimates distance from elapsed movement, can + mark a singleton inferred blocker, and picks `watching[0]` for a trainer. + Those are BDSP policies needing evidence, not contracts to export. +- A bounded failure to find a robust route means no route under this + search/model, not that the game destination is unreachable. + +For the demo, use a small hand-reviewed map set. A complete decomp importer, +all Kanto maps and automatic runtime route optimization are unnecessary. +A planned path may be computed offline or at startup; live position +verification is required in either case. + +## Revised work order and gates + +1. **Record the map-demo contract.** Pin FireRed/version and source maps; + step through the route with short commands, capture entry/exit anchors, + and record the exact post-rival starting save and parcel/Pokédex states. +2. **Build one runnable map slice.** Reuse the needed shared map subset; + add the FRLG movement/observation adapter, fixed terrain anchors, + one outdoor connection and a verified building transition. Reuse FRLG + wild-battle exit. Keep a bounded, FRLG-specific orchestration loop. +3. **Complete the parcel round trip and recovery.** Exercise a wild battle + mid-leg; re-anchor rather than replay a full open timed leg. Inject a + recoverable failure after a verified save, reload, verify the anchor, + and complete the checkpoint. Stop on failed localization/reset. +4. **Complete startup and chain both demos.** Reuse ScreenMachine and + StepTrace with FRLG observations. StarterRng's rival code supplies + examples, but its method is coupled to RNG filters, EV accounting and + level-up reads; it is not a drop-in story battle function. +5. **Compare two real adapters.** Extract only common position bookkeeping, + recovery decisions or transition handling that BDSP and FRLG now share. + Keep timings, OCR, battle outcomes and game scripts local. Add native + tests at that interface and rerun both game slices after extraction. +6. **Expand to Brock.** Add trainer approach/battle cases, progression, + health/PP and move-learning handling as the route requires. Consider E4 + walker migration as a separate regression-tested change, not a gate + before the demo. SV adoption remains a separate rollout. + +Validation must cover the model and its use: forbidden door/unknown-edge +planning, one-way ledges, possible starts converging at fixed terrain, +map identity across a door, temporary obstruction, battle interruption, +unknown-position abort, failed save, failed reload and exact retry count. +Screen fixtures test game observations; scripted action tests test orchestration; +console runs test their integration. Existing BDSP route tests mostly check +planned endpoints/geometry, not this execution/recovery matrix. + +Require three consecutive autonomous completions from the declared start +for each ordinary demo, plus the deliberate failure/recovery run. RNG mode uses +manual handoffs; validate its automated legs separately as specified in the +work plan. Record +outcomes, resets, false arrivals, and Switch time. Step-through success and +one unattended run are milestones, not repeated-validation claims. The +existing Brock gate remains the expansion decision; its proposed three-hour +average budget has not become a new public commitment in this review. + +## SwSh comparison + +SwSh #1207 contains about 560 lines of new implementation/header and calls +seven segments directly. It has timed routes plus limited visual feedback +for transitions, battle menus and catching. It has no verified checkpoint +runner. Some helpers return normally on timeout or discard catcher failure +outcomes; navigation repeats a whole timed action after interruption. + +This reinforces the need to retain action outcomes and verify destination +states. It provides no second adapter validating the proposed shared runner. +No source tests or gameplay-validation report were found; passing build CI +is a different claim. Do not extract these helper contracts into shared code. diff --git a/docs/design/AutoStory-Proposal.md b/docs/design/AutoStory-Proposal.md index d823ad849e..727949129c 100644 --- a/docs/design/AutoStory-Proposal.md +++ b/docs/design/AutoStory-Proposal.md @@ -1,6 +1,6 @@ # FireRed AutoStory: proposal -Status: draft, 2026-10-25. The full internal plan, with the evidence and line +Status: draft under revision, 2026-10-28. The full internal plan, with the evidence and line references, is [AutoStory.md](AutoStory.md). ## Problem @@ -16,34 +16,35 @@ Hall of Fame with the starter alone, so the route is known to be automatable. ## What I'm building first: a pilot to Brock A FireRed AutoStory from a new game to the Boulder Badge (about 12 -checkpoints), solo with no trades. It changes no existing program: the +checkpoints), solo with no trades. The game-neutral parts (the run flow with checkpoints, retries from the last save, start/end selection and stats; the tile-path walker; a closed-loop -screen driver) go into new shared folders from the start, with FRLG as -their only user, so nothing has to be moved later. - -About 10 PRs, each 150–500 lines, each doing one thing: - -1. Tile-path executor with unit tests, in a new `Pokemon/Navigation/`. -2. Elite Four farmer moved onto it, with no behaviour change. -3. A closed-loop screen driver (each input follows a screen read), then the new-game screens and naming keyboard on it. -4. Program shell: options, run flow, checkpoint list. -5. **New game → starter → rival battle. This is the first version users can run.** -6. Overworld detector. -7. Trainer-spotted and item-pickup watchers. -8. Resuming a walk after a battle or dialog interrupts it. -9. Trainer battle handler with unit tests. -10. **Parcel → Pokédex → Viridian Forest → Brock. This completes the pilot.** - -Detectors come one per PR, with screenshot tests in CommandLineTests. Paths -are planned offline from the pret/pokefirered decompilation (trainer -positions and sight lines) and checked in as reviewed data. +screen driver) reuse existing shared modules where applicable; FRLG supplies its own +movement and observation implementation. + +The first implementation milestone is a map-based demo from a verified +post-rival save: Pallet → Route 1 → Viridian Mart → Oak’s Parcel delivered +→ Pokédex verified and saved. Build it alongside a startup demo from a new +game through the lab rival and first verified save, then chain them. + +Reuse the existing BDSP shared map/planner and screen modules with an FRLG +adapter. The demo must demonstrate a wild-battle interruption, verified +map/door transitions, and a deliberate failure followed by verified reload +and replay. These two game implementations determine what executor logic +is worth sharing. Elite Four migration and SV refactoring are independent. + +The [FRLG demo work plan](FRLG-Demo-Work-Plan.md) defines JSON map resources, +startup prerequisites and optional SID Helper/Starter RNG handoffs. The +[map-reuse review](AutoStory-Map-Reuse-Review.md) specifies the work order, +source evidence and validation gates. Exact PR splits follow the runnable +slice; the previous ten-PR count is no longer a delivery commitment. ## What I'd like reviewed first -PRs 1–2: the tile executor's result and resume types, and moving `walk_path` -out of `PokemonFRLG_EliteFourFarmer.cpp`. They touch existing FRLG code, and -the rest of the pilot builds on them. +The small map subset and FRLG adapter, especially how observed position, +map transitions and save/reload postconditions constrain the next action. +New detector changes include screenshot fixtures. No general executor +interface is frozen before these behaviors work in the demo. ## The cost, honestly diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index d14601e42e..ab60c8f976 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -1,6 +1,6 @@ # AutoStory: FRLG pilot first, shared run flow and 2D movement later -Status: internal plan, revised 2026-10-25 after review. The upstream-facing +Status: internal plan, revised 2026-10-28 after the map-reuse review. The upstream-facing one-page summary is [AutoStory-Proposal.md](AutoStory-Proposal.md). The review comment drafts for the BDSP PR are in [AutoStory-1717-review-drafts.md](AutoStory-1717-review-drafts.md). Neither @@ -14,6 +14,24 @@ Paths: `SV/` = `SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/`, `BDSP/` = `SerialPrograms/Source/PokemonBDSP/Programs/AutoStory/` (PR ref), `FRLG/` = `SerialPrograms/Source/VideoGames/PokemonFRLG/`. +## Current implementation order (2026-10-28 review) + +The [map-reuse review](AutoStory-Map-Reuse-Review.md) updates the work order +below. The [FRLG demo work plan](FRLG-Demo-Work-Plan.md) specifies map resources, +startup prerequisites, SID Helper/Starter RNG handoffs and acceptance gates. First prove the existing BDSP spatial model with a small FRLG map +demo (post-rival save → Oak’s Parcel → Pokédex), and a startup demo through +the first verified save. Then settle the common executor using both games. +The old ten-PR sequence in §7.7 is retained as a candidate inventory, not a +prerequisite chain. In particular, migrating the Elite Four farmer and SV +is no longer on the critical path to the first runnable FRLG demo. + +Shared map and screen modules already exist in our BDSP work. Reuse them +through explicit prerequisites; do not rewrite them. Keep game-specific +observations and movement execution local until both implementations prove +what needs sharing. The source findings, validation limits, map structure, +and revised gates are in the review. Earlier interface sketches in §3/§5 +are candidates to test, not settled interfaces. + ## 0. Summary **Problem.** AutoStory programs (play a game's story from a new save, @@ -108,8 +126,8 @@ sequence (§7), and who wrote the FRLG code we build on (§8). Four AutoStory efforts (SV on `main`, BDSP #1717, SwSh #1207, our FRLG plan) and our BBQ and BDSP lab work keep rebuilding the same pieces. SwSh -#1207 is timed input throughout (mash A for 30 s, hold the stick for 20 s, -fixed menu walks), as BDSP's segment 00 was; running BDSP's intro on a +#1207 combines timed routes with limited transition, battle-menu and catch +feedback, but lacks verified checkpoint recovery; running BDSP's intro on a console showed why that breaks (dropped inputs, menus opened by a stray A, loops that never end). The pieces below are game-neutral and get their final home in the PR that first adds them, even while one game uses them. @@ -733,7 +751,7 @@ Consequences: fails is a `UserSetupError` at start, not a failure hours in. - The planner and the table are pure logic, so they get unit tests. -### 7.7 PR plan for reviewers +### 7.7 Earlier PR inventory (ordering superseded by the map-reuse review) **2026-10-29:** T1 and T2 below become N1–N3 on `nav/core` and the FRLG child `frlg/brock-mvp` ([AutoStory-Navigation-Stack.md](AutoStory-Navigation-Stack.md) §4). The diff --git a/docs/design/FRLG-Demo-Work-Plan.md b/docs/design/FRLG-Demo-Work-Plan.md new file mode 100644 index 0000000000..731346932a --- /dev/null +++ b/docs/design/FRLG-Demo-Work-Plan.md @@ -0,0 +1,313 @@ +# FRLG demo work plan + +Draft, 2026-10-28. Planning and source inspection only; no new gameplay code, +console run, or build validation. Start with English FireRed and one declared +starter; do not imply LeafGreen or other language coverage from shared code. + +This plan refines [AutoStory.md](AutoStory.md) and the +[map-reuse review](AutoStory-Map-Reuse-Review.md). The demo slices below replace +the older fixed PR sequence; the broader pilot to Brock remains the goal. +Interfaces are proposals to validate with the two demos. + +## Deliverables and order + +Build two independently runnable slices, then chain them: + +- **Startup:** new game → player name → bedroom → Oak's lab → starter → + first rival resolved → verified post-rival save. Provide optional SID Helper + and Starter RNG handoffs along this path. +- **Map demo:** verified post-rival save → Pallet → Route 1 → Viridian Mart → + Oak's Parcel → return to Oak → verified Pokédex and save. + +Begin map implementation from a prepared save while collecting startup screen +fixtures. The parcel trip exercises connected outdoor maps, interiors, grass, +NPC interaction, interruptions, and return travel. It is the experiment that +should determine a shared route executor. No Elite Four migration, generic +registry, full Kanto conversion, or broad SV extraction is a prerequisite. + +## Startup compatible with SID Helper + +Compatibility means explicit handoffs to the existing programs first. It does +not require embedding their UI programs or rewriting their RNG calculations. + +| Stage | Entry and action | Verified exit / recovery boundary | +|---|---|---| +| Settings bootstrap | Check whether a settings-bearing save already exists; establish Fast text, Help button mode, frame 1, and the selected sound setting | Settings survive reload; a blank game needs a temporary save before the SID attempt | +| Prepare SID Helper | Start New Game, select the supported character, enter the requested player name | Naming screen with complete text, **before confirming OK**; drain controller requests and stop | +| External SID Helper | User runs existing program with matching language and valid target advances | Candidate SIDs and TID recorded; actual output may be trainer card or HOME | +| Resume after SID Helper | Resume the running game if on HOME, recognize trainer card, record/check TID, close it and recognize bedroom | Complete and verify the new identity's first save before permitting resets | +| Prepare Starter RNG | Complete Oak's introduction; move to the selected ball from the south side of the table | Save facing that ball, verify completion, and stop before interacting with it | +| External SID confirmation / starter hunt | User chooses a target using candidate SID, runs Starter RNG, and records confirmation | Candidate status remains distinct from confirmed SID; preserve the pre-starter save while testing candidates | +| Resume story | Explicitly choose to keep the result; identify actual screen, starter, rival state and health | Preserve the chosen starter in a verified save before reset-based recovery; finish the rival only if still pending | + +The first demo may require manual settings bootstrap, SID target selection, +and confirmation recording. These are documented handoffs, not an unattended +end-to-end RNG feature. Ordinary startup bypasses both RNG pauses. Full blank-save +bootstrap can be implemented after the shorter naming/return path works. + +The official [SID Helper instructions](https://pokemonautomation.github.io/Programs/PokemonFRLG/SidHelper.html) +require stopping before name confirmation and specify a default rival name. +They also require a temporary settings save when starting without a save. +Use Help button mode for compatibility with the broader RNG workflow, and keep +the selected Mono/Stereo setting consistent. Validate the documented capture, +console and profile setup at handoff. Never silently change these settings +between preparing and running an RNG program. + +The [RNG guide](https://pokemonautomation.github.io/Programs/PokemonFRLG/RngManipulationGuide.html#finding-your-secret-id) +distinguishes candidate SIDs from confirmation using a shiny target. Store +TID, candidate SID/advance pairs, selected candidate, confirmation status, +game/language, sound setting and evidence reference together. TID is a useful +mismatch check, not a globally unique save identifier. A new-game restart +invalidates the association; never carry an old candidate list forward. +For the first manual handoff, a user-maintained record is sufficient; automatic +transfer is a later integration, not a promise that one program can read +another program's display. + +The [Starter RNG instructions](https://pokemonautomation.github.io/Programs/PokemonFRLG/StarterRng.html) +require saving on the south side of the table facing the desired starter. +This becomes a named startup milestone, not just a pause near Oak's lab. + +### Source constraints for integration + +Inspected FRLG code at `c69b5d095`, under +`SerialPrograms/Source/VideoGames/PokemonFRLG/`: + +- `Programs/RngManipulation/PokemonFRLG_SidHelper.cpp` has private helpers + for timed name confirmation, intro completion, trainer-card navigation and + TID reading. The timing sequence chooses the default rival name. Keep its + input schedule unchanged; do not insert AutoStory observation waits into + that interval. Observe before and after it. +- SID Helper does not save. It reads the trainer card and may go HOME. An + AutoStory retry must not reset this unsaved new identity back to the + temporary bootstrap save. A failed first save stops for recovery in place. +- Starter RNG can stop early on a shiny, or use rival battles and further + leveling during calibration. Its exit is not universally "post-rival". + Inspect screen/state before resuming and do not treat program completion + as proof of a saved chosen starter. Resume from arbitrary calibration + interruption is outside the first demo; report an unsupported state. +- Preserve the pre-starter save until the user commits to keeping the result. + SID confirmation may use a disposable starter before a second target hunt. +- If direct integration is later worthwhile, extract a small callable routine + with an explicit result from SID Helper. Keep the existing standalone + program behavior and test its timing contract. Do not instantiate one + top-level program from another or duplicate the timed script. + +Handoff success must not trigger an automatic A press, game close, or reset. +The pre-OK boundary is a deliberate terminal result. Failure before a verified +save is different from failure at a replayable checkpoint. + +## Map storage and typed model + +**Use versioned JSON resources, loaded into typed C++ objects.** Keep large +map contents out of C++ string literals. Small synthetic grids remain useful +in native unit tests. Candidate resource path: +`RESOURCE_PATH()/PokemonFRLG/AutoStory/Maps/pallet-town.json`. +Integrate delivery with the project's Resources/Packages convention; do not +assume generated files placed in a local Packages directory are distributed. + +Three separate kinds of state: + +1. Immutable map definition: terrain, edges, exits, source objects and anchors. +2. Live navigation estimate: current map, possible tiles, facing, occupancy, + most recent observation and uncertainty. A planned endpoint is not evidence. +3. Story state/checkpoints: observed milestones, available transitions, current + starter/health policy and the last verified recoverable save. + +A JSON schema is worth defining now, but only for the small demo subset. First +normalize two connected maps and one interior, then stabilize schema version 1 +with the C++ loader. Proposed fields/types: + +| Field | Representation / meaning | +|---|---| +| `schema_version`, `id`, `game` | Integer version; stable lowercase hyphenated map slug; explicit supported game | +| `source` | Repository, pinned revision, source map/layout IDs and input hashes | +| `width`, `height`, `terrain_rows`, `terrain_palette` | Rectangular grid of compact symbols with typed meanings; JSON strings per row are readable and diffable | +| `traversal_edges` | Sparse directed rules for ledges or other special movement; unknown rules reject traversal | +| `connections` | Outdoor edge, offset, destination map and corresponding boundary; local-to-world conversion is derived | +| `warps` | Local tile, source warp ID, destination map/warp ID and activation condition; explicit transition action | +| `objects` | Stable object ID, initial tile, fixed/wandering classification, movement/script/visibility references | +| `triggers` | Source script/flag references and supported story gates; not an executable game-script interpreter | +| `anchors` | Named location/region plus reference to FRLG observation evidence; a moving NPC is not a fixed anchor | + +Coordinates are zero-based local layout tiles, x east and y south. Do not leak +engine border offsets into route definitions. Resolve destination warp IDs +explicitly; prove the arrival tile and facing on console, since the exit +animation can move the player away from the destination event tile. + +Keep collision/elevation/metatile provenance available during conversion. +The runtime schema can collapse these to supported traversal only after the +conversion proves equivalence on the selected maps. A collision-free tile is +not sufficient to infer grass, ledges, warps or story availability. +Unsupported tiles/transitions are unavailable, not implicitly walkable. + +Out-of-slice exits (e.g. Pallet to Route 21 or the rival's house) must be +explicitly excluded from routing. The importer can preserve their provenance; +the runtime loader must distinguish an intentionally unavailable edge from a +broken reference. Only enabled transitions require loaded destinations. + +Keep static terrain separate from transient blockers. Object positions and +story flags from the decompilation describe possible behavior, not current +screen observations. Replanning changes live occupancy, not the packaged map. +Do not serialize BDSP's ASCII tile codes as the permanent cross-game schema. +Convert supported FRLG terrain to the existing shared TileGrid model; handle +warp actions above its path planner, which currently rejects door tiles. + +## Route-planning memory and time budgets + +The eight demo layouts contain 4,029 tiles; raw map storage is small. Search +state growth is the larger risk. The reviewed ordinary planner stores five +states per tile. The robust planner searches sets of possible positions and +stores those sets in its node table, parent records, planned legs and priority +queue. Its default `max_spread = 5` bounds each resulting position set, not the +number of sets explored. The current implementation has no total state, +queue-size or planning-time limit. A limit on replans does not bound one search. +These are source findings, not measurements of peak memory or a reproduced +out-of-memory failure. + +Before the first observed walk, require: + +- Explicit per-search limits on stored states, queued entries and elapsed time, + plus cancellation checks within expansion work. Check capacity before growing + containers, including stale queue entries and temporary successor sets. + Bound input position sets and validate search parameters so one expansion + cannot evade the resource limits. Never discard possible positions merely + to fit a budget; obtain better observations or return a bounded failure. +- Distinct results for a route found, search exhausted without a route, + budget exceeded (with the limiting resource), and cancellation. Budget + exhaustion is not proof that no route exists. Re-localize, select a nearer + verified landmark, or stop within the existing recovery budget; do not + automatically retry the same search with larger limits. +- Per-search diagnostics: map/region dimensions, starting uncertainty, + expanded states, peak stored states, peak queue entries, elapsed time and + termination reason. During validation, measure peak memory and identify + whether it is planner allocation or whole-process memory; video buffers and + allocator retention must not be attributed to the planner without evidence. +- Short routes between observable anchors or exits. Use map connections/warps + for travel between regions and tile search within a bounded region. MapSet + builds a dense bounding rectangle, including gaps: validate dimensions and + checked size arithmetic before allocation, and do not assemble all Kanto + into one tile canvas. The JSON loader also limits resource size and cell count. + +Choose and document initial finite limits before execution, then tune them from +measured demo searches. A byte estimate based only on node count is not a hard +memory cap unless vector sizes, queue growth and allocation overhead are also +bounded. Keep search-local data scoped to one search so replans release it. + +Native acceptance tests must exercise tight state/queue budgets, deadline and +cancellation paths, oversized map/input rejection, and distinct no-route versus +budget-exceeded results. Use an injectable clock for deterministic deadline +checks. Include unreachable goals, open areas with ambiguous starts and repeated +replanning; verify cleanup and that budget failure issues no movement command. +Profile normal and adverse searches on the demo maps, record peak memory/time, +and confirm repeated replans do not accumulate retained search data. If the +parcel route exceeds the documented limits, narrow the search or improve +localization before expanding scope. This gate precedes sharing the executor. + +## Map sources and first importer + +The initial source subset consists of eight maps and their dependencies from +[pret/pokefirered](https://github.com/pret/pokefirered/tree/ce6406d8c2eaf46d543c8a2606de0c3cb1951982), +pinned to `ce6406d8c2eaf46d543c8a2606de0c3cb1951982`: + +| Map | Width × height | Purpose | +|---|---|---| +| PalletTown | 24 × 20 | Outdoor hub and Oak trigger | +| PalletTown_PlayersHouse_1F | 13 × 10 | Startup interior | +| PalletTown_PlayersHouse_2F | 12 × 9 | Initial bedroom / SID resume | +| PalletTown_ProfessorOaksLab | 13 × 14 | Starter, rival and parcel delivery | +| Route1 | 24 × 40 | Outdoor connection, grass and ledges | +| ViridianCity | 48 × 40 | Town connection and Mart approach | +| ViridianCity_Mart | 11 × 9 | Parcel interaction and door transition | +| ViridianCity_PokemonCenter_1F | 15 × 10 | Optional healing fallback | + +The source subset includes map JSON/scripts, layout binaries, relevant +metatile attributes, layout and tileset indexes, fieldmap definitions, naming +code and constants. The map table describes decompilation inputs, not a +production map pack or console-validated navigation dataset. The converter +must record source revision and input hashes with its output. + +`map.json` alone is insufficient: it contains events/connections and a layout +reference, while tile data is in `map.bin`. The pinned fieldmap definitions +encode metatile index in bits 0–9, collision in 10–11, elevation in 12–15. +Resolve primary/secondary tileset attributes to identify relevant behavior. +Do not download rendered screenshots and treat them as authoritative collision. + +First importer deliverable: deterministic offline conversion of Pallet, +Route 1 and Oak's lab, plus a readable grid/edge report. Add the remaining demo +maps once the encoding and warp semantics are checked. Preserve source revision +and hashes, validate dimensions and references, and compare the converted +route against console observations. No runtime network dependency or moving +"latest" upstream input. An offline conversion script may be Python; production +loader/planner tests remain registered native C++ tests. + +## Startup and traversal inventory + +| Capability | Existing pieces | Demo work still required | +|---|---|---| +| New Game / intro | Dialog, selection and fade detectors | Fresh-save/title path, character/name transitions, cutscene locks; existing LoadMenuDetector assumes a save and says new-game behavior is untested | +| Name entry | No FRLG name-entry driver found | FRLG in-game keyboard, not Switch system keyboard; observe page/cursor, type/backspace, validate text, separate entry from confirmation | +| Naming scope | Decomp defines 7-character player/rival limit and upper/lower/symbol pages | Initially support declared ASCII letters, reject unsupported input before pressing anything; include both keyboard pages in fixtures; custom rival only outside SID mode | +| Menu context | Start-menu helpers and NO_DEX support | Distinguish no Pokémon, Pokémon/no Dex, and post-Dex layouts; do not hard-code one row index throughout startup | +| Saving / reload | `save_game_to_overworld`, reset/load helpers | Verify first-save and overwrite prompts, actual save completion and observed reload location; current save helper can assume first-save completion after a missing second prompt | +| Battle decisions | `spam_first_move`, BattleResult, battle/PP/faint detectors | Bounded early-rival policy, explicit win/loss results, health and PP handling, return to observed overworld; story progress must not assume victory | +| Rival reference | Starter RNG `auto_battle_rival` | Coupled to stat inference, filters and EV updates; use as source evidence, not a drop-in story battle driver | +| Wild battles | `flee_battle`, tested `WildBattleExitActions` | Validate failed escape/opponent turn/faint at starter levels; existing flee contract assumes escape (Smoke Ball), though implementation retries; battle-exit logic only handles an already-won battle | +| Movement | Shared BDSP TileGrid/MapSet; FRLG timed walkers | FRLG observations, uncertainty, small movement batches, facing, dynamic NPCs, interrupted movement and verified arrival | +| Story interactions | Dialog and menu primitives | Oak escort/locks, ball selection, rival trigger, Mart parcel receipt, Oak delivery and actual Dex proof | +| Recovery / diagnostics | ScreenMachine, StepTrace, SV retry draft | Exact attempt budget, verified saved state, no reset before preservation, timeout screenshots, trace of observed vs predicted position | + +Before ordinary wild-encounter travel, establish a health policy. Start simple: +verify usable starter and PP, flee where safe, and stop/recover on unsupported +battle states. Add healing only when the observed route needs it. Do not allow +a loss to silently invalidate the next checkpoint's assumed party state. + +## Implementation slices and acceptance evidence + +| Slice | Deliverable | Acceptance gate | +|---|---|---| +| 0. Fixtures and contracts | Recorded fresh intro, keyboard, trainer card, save prompts, starter-facing save and post-rival state | Named start/end states, supported settings, recovery rules and screenshots; no inferred save success | +| 1. Maps and loader | Small deterministic normalized map pack; typed JSON loader | Native tests reject malformed dimensions, unsupported schema/terrain, broken enabled transitions; test outdoor offsets, directional ledges and warp resolution; enforce resource/cell limits and checked allocation sizes | +| 2. One observed walk | Bounded planner, prepared save, Pallet/Route 1 movement and one interior transition | Pass search-budget/cancellation tests and record memory/time measurements; verify destination/facing; forced missed movement and NPC obstruction lead to re-localization or bounded stop, not an invented exact coordinate | +| 3. Parcel trip | Full route from post-rival save to saved Dex | Wild interruption resumes from observed state; parcel/Dex evidence; deliberate failure reloads verified checkpoint and completes replay; repeated replans remain within documented resource limits | +| 4. Naming / SID handoff | Enter player name and stop before OK; resume after existing helper | No extra queued input; default rival retained; TID/candidate record associated correctly; first new-identity save verified before any reset | +| 5. Starter handoff / startup | Verified ball-facing save; ordinary starter/rival path; supported resume after chosen RNG result | No accidental starter acceptance at handoff; no reset of unsaved chosen result; actual rival outcome and save verified | +| 6. Chain and extract | Startup → parcel demo; compare FRLG and BDSP execution | Repeat unattended ordinary run and supported manual RNG handoff run; extract only demonstrated common policy with both adapters covered | + +For ordinary startup and the parcel demo, require three consecutive unattended +completions from the declared start, plus the deliberate failure/recovery run. +For RNG compatibility, validate each automated leg independently and record +manual handoffs separately; do not call the combined workflow unattended. + +Slices 1–3 can precede 4–5 using prepared saves. Slice 0 starts immediately for +both. Validation records must distinguish manual stepping, unattended completion, +repeat runs and synthetic tests; record console time rather than promise a +hardware budget before measurements exist. + +## Reuse decisions to defer until the demo + +- Reuse BDSP's already-shared `CommonTools/ScreenMachine` and + `Pokemon/Navigation/Pokemon_TileGrid` / `Pokemon_MapSet` via explicit + prerequisite commits. MapSet is for adjacent outdoor maps, not interiors + superimposed on a world canvas. Move pure planner tests out of BDSP-specific + registration when adding the second consumer. +- Keep FRLG input timings, screenshots, battle/dialog interpretation, save + verification and story milestones local. BDSP RouteWalk is useful evidence, + but combines all of these and should not simply move wholesale to Common. +- SV #43–46 provide small selection/stats/retry candidates; use only what the + demo immediately consumes. Its legacy retry default executes 102 attempts + and does not guarantee the new-save recovery contract. Do not silently + change SV behavior while adopting a stricter FRLG policy. #47's SV developer + harness is not a prerequisite. +- SwSh's seven-segment prototype does not supply a proven checkpoint/retry + implementation. Its timed movement and save assumptions are not the FRLG + acceptance standard. +- After both games run, compare a concrete navigation result type (arrived, + interrupted, uncertain, failed), the replan/attempt policy, and checkpoint + orchestration. Share these only where both adapters agree on semantics. + +## Immediate next implementation task + +Collect startup/handoff fixtures and implement the three-map conversion plus +loader as the first narrow code change. Also verify the prepared post-rival save and the +first observed Pallet/Route 1 walk. Naming is the first startup-specific driver; +it should expose "enter text" separately from "confirm" from day one.