From be05e8f6ba2aa48960fb764953803c803c4d1df3 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 00:33:18 -0700 Subject: [PATCH 01/24] Design doc: shared AutoStory run flow, 2D movement, and an FRLG AutoStory Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory.md | 629 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 docs/design/AutoStory.md diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md new file mode 100644 index 0000000000..50a0ffff58 --- /dev/null +++ b/docs/design/AutoStory.md @@ -0,0 +1,629 @@ +# AutoStory: shared run flow, 2D movement, and an FRLG AutoStory + +Status: draft for discussion, 2026-10-25. Not proposed upstream yet. +Sources: SV AutoStory on `main`; BDSP WIP +[PokemonAutomation/Arduino-Source#1717](https://github.com/PokemonAutomation/Arduino-Source/pull/1717) +at `65094d4cd`; SwSh WIP PokemonAutomation/Arduino-Source#1207 at `32d506c27`; +FRLG code on `main`; the [pret/pokefirered](https://github.com/pret/pokefirered) +decompilation; the [52poke walkthrough](https://wiki.52poke.com/wiki/%E9%99%84%E5%BD%95:%E5%AF%B6%E5%8F%AF%E5%A4%A2_%E7%81%AB%E7%B4%85%EF%BC%8F%E8%91%89%E7%B6%A0%E6%B5%81%E7%A8%8B). +Paths: `SV/` = `SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/`, +`BDSP/` = `SerialPrograms/Source/PokemonBDSP/Programs/AutoStory/` (PR ref), +`FRLG/` = `SerialPrograms/Source/VideoGames/PokemonFRLG/`. + +## 0. Summary + +- **Run flow.** BDSP copied SV's framework almost name for name (segment and + checkpoint interfaces, registries, start/end selects, save-then-retry loop, + stats). The two copies have already drifted: retry limits (SV 100 with an + off-by-one, BDSP 20), error reporting (SV only), day skip (SV only), start > + end check (SV only). SwSh #1207 does not use the framework at all. A small + game-agnostic core (retry loop behind a hooks interface, index/range math, + stats, select databases) can be extracted from SV as pure moves in five + small PRs, then adopted by BDSP and FRLG. Each game keeps its own options, + save/reset functions and checkpoints. +- **2D movement.** FRLG and BDSP both move on a tile grid, and both + codebases reinvented the same three things badly or partially: a path as + `{direction, tiles}` data, walking under interrupt watchers, and getting + back on the path after an interrupt. BDSP's best idea is closed-loop + landmark alignment (segments 00–03); its later segments are blind scripts + with per-trainer hard-coded "move back" pushes, one of which never runs + (§5.2). A shared, console-free core (path executor with resume bookkeeping, + interrupt policy, alignment control law) plus per-game adapters (timings, + detectors, matchers) fits both. Timing constants stay per game. +- **FRLG AutoStory** is smaller than SV or BDSP because GBA movement is + frame-exact, the camera is fixed with the player centred, Kanto has no + lighting changes, and the decomp gives exact trainer positions and sight + ranges. Estimate: ~3–5k lines of infrastructure, ~90–110 checkpoints at + 40–80 lines each, ~10–12k lines total (SV 22.4k, BDSP 32.7k). The + bottleneck is Switch time to validate each checkpoint, not code. +- **Order:** (1) run-flow prework from SV, (2) shared tile movement with FRLG + as the first adopter (moving `EliteFourFarmer`'s walker out), (3) FRLG + pilot Pallet → Pewter to measure lines and hours per checkpoint, (4) the + rest of FRLG by segment. Offer the shared pieces to the BDSP team; their + detector-first extraction plan (Mysticial's request) is independent of it. + +## 1. Design from first principles + +Written before reading SV or BDSP; the rest of the doc checks it against them. + +1. **Checkpoint = story between two saves.** Precondition and postcondition + are observable states ("standing in Pewter Center, party healed"). On any + failure: reset to the last save and retry, up to a limit. +2. **Program = ordered checkpoint list.** User picks start and end; the save + file is the resume state. +3. **Checkpoints are short compositions of a small step vocabulary:** walk a + path, interact, clear dialog to a stop state, battle, menu choice, shop, + heal, fly, save. Each step names the screen it ends on and waits for it + with a timeout. +4. **Movement is the game-specific layer.** Tile games (FRLG, BDSP d-pad) can + walk by count; 3D (SV) aligns a camera to markers. They should not share + code. +5. **One battle handler** with policies (trainer: chosen move; wild: flee or + repel; prompts: evolution, move learn, faint switch; blackout: fail the + checkpoint). +6. **Game actions behind interfaces** so the runner, the path executor and + battle decisions get unit tests with scripted fakes, like + `WildBattleExitActions` (`FRLG/PokemonFRLG_Navigation.h:88-127`). + +SV and BDSP match 1–2 closely, partially do 3 (helpers, not a vocabulary), +and do 5–6 weakly (no tests of the flow; BDSP's smarter battle code is +unused). 4 is where BDSP split into two styles. + +## 2. Run flow: what exists + +| Element | SV (`main`) | BDSP #1717 | Verdict | +|---|---|---|---| +| Segment interface | `name/start_text/end_text/run_segment(env, ctx, AutoStoryOptions, AutoStoryStats&)` `SV/PokemonSV_AutoStoryTools.h:96-107` | identical `BDSP/PokemonBDSP_AutoStoryTools.h:126-138` | same | +| Checkpoint interface | same + `checkpoint_text()` `SVT.h:109-123` | no `checkpoint_text()` `BT.h:140-152` | same | +| Registries | function-local statics, public `ALL_AUTO_STORY_SEGMENT_LIST()` `SV/PokemonSV_AutoStory.cpp:146`, `..._CHECKPOINT_LIST()` `:321` | file-static `ALL_SEGMENTS()/ALL_CHECKPOINTS()` `BA.cpp:51,245` | renamed | +| Select databases | 6 near-duplicate `make_*_database` `SVA.cpp:152-198,326-372` | one `section_database(bool,bool)` `BA.cpp:257-283` | BDSP's is better | +| Index math | `.index() + (LAST_TUTORIAL+1)` `SVA.cpp:1102-1168` | `stoul(slug())` `BA.cpp:735-750` | same result | +| Tutorial split | hard-coded 9 / 20 `SVA.cpp:93-94` | segment 0, 6 checkpoints `BA.cpp:256` | same idea | +| start > end | `UserSetupError` `SVA.cpp:1304-1313` | none (loop clamps) | BDSP missing | +| Options | `{language, starter_choice, notif_status_update&, notif_error_recoverable&}` `SVT.h:89-94` | `{language, starter, notif_status_update&, help_mode, outside_help, save_mode, retry_scope}` `BT.h:111-119` | per game | +| Stats | Checkpoint / Segment / Reset `SVT.h:27-40` | same + non-atomic `m_first_run` `BT.h:50` | same keys | +| Save | `save_game_from_overworld` via `checkpoint_save` `SVT.cpp:1180` | verified save, 3 retries, blind fallback; FAKE diagnostic mode `BT.cpp:75-185` | per game | +| Reset | `reset_game(info, console, ctx)` | `reset_game_from_home(...)`, throws on false `BT.cpp:236-243` | per game | +| Day skip on retry | yes, if enabled `SVT.cpp:1443-1446` | no | SV only | +| Retry limit | `i > 100` → 102 attempts (off by one) `SVT.cpp:1436,1471` | 20, rethrows `BT.cpp:210,230` | diverged | +| Error report | at attempt 10, telemetry `SVT.cpp:1457-1469` | none | SV only | +| Post-success check | `enter_menu_from_overworld` (retry if not overworld) `SVT.cpp:1453` | none | SV only | +| Tutorial loop | separate copy `SVT.cpp:1491-1547` | — | SV only | +| `save=false` path | — | `reload_backup_save` is an empty TODO `BT.cpp:188-197`, no callers | dead | +| Dev harness | `test_checkpoints` / `test_code` `SVA.cpp:901-1080,1196-1291` | none | SV only | +| End of program | `GO_HOME_WHEN_DONE`, start-up checks | neither; language hard-coded English `BA.cpp:701` | BDSP missing | + +Coupling worth knowing before moving anything: + +- SV's segment list is used outside AutoStory: + `ClaimMysteryGift::run_autostory_until_pokeportal_unlocked` runs segments + 0..6 (`SV/../Farming/PokemonSV_ClaimMysteryGift.cpp:371-382`). Keep the + list and `AutoStoryOptions` exported. +- `ML/Inference/ML_YOLONavigation.cpp:20,87` includes SV AutoStoryTools: a + layering inversion to leave alone in this work, but not to copy. +- Segments construct their checkpoints inline + (`AutoStory_Checkpoint_04().run_checkpoint(...)`), so checkpoint order is + written twice: in each segment and in the registry. In BDSP this already + went wrong twice (§5.2). +- Code-health limits (fork #41: functions ≤50 lines, nesting ≤4, ≤7 params) + are exceeded by: SV constructor ~397 lines, `test_checkpoints` 180 lines / + 8 params / nesting 5, `test_code` 96, `on_config_value_changed` 87, + `program` 82, both retry loops (64 and 57 lines, 8 and 7 params), and every + `checkpoint_NN` (8 params). BDSP: constructor 282 (four copies of the + 14-move list), `program` 74, `save_game` 71, retry loop 51 / 8 params. Pure + moves keep these as legacy; anything new should not add more. + +## 3. Run flow: shared core and prework + +### 3.1 What is shared, what is per game + +Shared, in a new `SerialPrograms/Source/Pokemon/AutoStory/` (that module has +no `NintendoSwitch/` includes today; keep it that way): + +- `run_checkpoint_with_retries(hooks, policy, checkpoint_text, action)`: the + loop only. +- `CheckpointRetryPolicy{max_attempts, report_at_attempt, ...}`. +- `AutoStoryStats` (same three keys; persisted stats depend on the strings). +- `make_index_database(list, begin, end)` and `to_global_range(...)`: the + select/slug/index math. +- Optionally `AutoStorySegmentT` / `CheckpointT<...>` so a + game declares `using AutoStory_Segment = ...`. + +Per game: Options struct, save/reset/day-skip, post-success check, the +start-up checks, the registries, and every checkpoint. + +```cpp +// Pokemon/AutoStory/Pokemon_AutoStoryRetry.h +namespace PokemonAutomation{ +namespace Pokemon{ + +struct CheckpointRetryPolicy{ + size_t max_attempts; // SV 100, BDSP 20 + bool fatal_when_greater; // SV: i > max (keeps today's off-by-one) + size_t report_at_attempt; // SV 10; SIZE_MAX = never +}; + +class CheckpointHooks{ +public: + virtual ~CheckpointHooks() = default; + virtual void log(const std::string& message) = 0; + virtual void save_checkpoint() = 0; // save, m_checkpoint++, status notification + virtual void before_attempt(size_t attempt) = 0; // SV: day skip + save on retries + virtual void after_success() = 0; // SV: confirm overworld; else no-op + virtual void report_recoverable(const std::string& message) = 0; + [[noreturn]] virtual void fail(const OperationFailedException& e, size_t max_attempts) = 0; + virtual void reset_for_retry() = 0; // reset, m_reset++, update stats +}; + +void run_checkpoint_with_retries( + CheckpointHooks& hooks, + const CheckpointRetryPolicy& policy, + const std::string& checkpoint_text, + const std::function& action +); + +} +} +``` + +SV keeps `checkpoint_reattempt_loop(...)` and `..._tutorial(...)` with their +current signatures as thin wrappers that build `SVCheckpointHooks` / +`SVTutorialCheckpointHooks`, so none of the ~102 call sites in 40 segment +files change. + +### 3.2 Behaviours the move must keep (SV) + +- Save on attempt 0 happens inside the `try`; if the save throws, later + attempts do not save again. +- `i > max_attempts` fires the fatal error (102 attempts run). Fix later in + its own behaviour-change PR, not in the move. +- Recoverable report exactly once at attempt 10. +- `wait_for_all_requests()` before the action and before the reset. +- `after_success` throwing (the overworld check) counts as a failed attempt. +- Each loop's own fatal message text. + +### 3.3 Prework PR sequence (SV only, no behaviour change) + +| # | PR | What moves | Risk | Review | +|---|---|---|---|---| +| P1 | Shared select databases | 6 `make_*_database` → `make_index_database`; same slugs/labels | low | `--color-moved` | +| P2 | Range math | `get_*_index` arithmetic → pure `to_global_range` + tests | low | tests | +| P3 | Shared stats | `AutoStoryStats` → `Pokemon/AutoStory`; alias in `SVT.h` | low (keys) | pure move | +| P4 | Retry core | hooks + `run_checkpoint_with_retries`; SV loops become adapters; fake-hook tests | medium | loop body moved, adapters new | +| P5 | Dev harness out of the program class | `test_checkpoints` / `test_code` → `PokemonSV_AutoStoryDevTests.cpp`; delete the dead 106-line comment block | low | `--color-moved` | +| P6 (opt.) | Templated segment/checkpoint base | aliases in SV; no segment file changes | low | small | + +Tests enabled by P2/P4 (fake hooks recording steps as strings, registered +through a new `Pokemon::add_tests_AutoStory` in +`ComputerPrograms/UnitTestRunner.cpp`, or in `PokemonSV_Tests.cpp` first): +first-try success sequence; save only on attempt 0 (also when the save +throws); day skip only on retries; report exactly once at 10; SV fatal at 101 +vs BDSP rethrow after 20; reset exception propagates; non-`OperationFailed` +exceptions are not caught; `after_success` failure retries; range math for +SV (10/21 offsets) and BDSP (1/6); slugs equal global indices. + +Separate behaviour-change PRs after the move, each titled as such: fix the +off-by-one; the BDSP-style single `section_database` if P1 did not already +get there; registry-driven segments (a segment = a range of the checkpoint +registry, removing the duplicated order). + +## 4. 2D movement: what exists + +### 4.1 Primitives + +| | FRLG (`main`) | BDSP #1717 | +|---|---|---| +| Grid walker | `WalkSegment{DpadPosition, steps}`, `walk_path` in `FRLG/Programs/Farming/PokemonFRLG_EliteFourFarmer.cpp:395-449`: decomp timings `FRAME_MS=16.74`, `TURN_FRAMES=8`, `STEP_FRAMES=16`; one continuous hold, direction switched mid last step (±8 frames tolerance) | `repeat_dpad` `BDSP/PokemonBDSP_AutoStoryTools.cpp:327-343`: one tap per tile, an extra tap when turning; 211 uses | +| Elsewhere | millisecond holds: `StarterRng.cpp:224-230,413-449`, `PickupFarmer.cpp:142-167`, `EvTrainer.cpp:206-277`, `BlindNavigation.cpp:414-477` (RNG timing budgets), 33 ms turn taps in `grass_spin` `Navigation.cpp:1571-1592` | joystick holds dominate (Seg03: 328 holds, 0 `repeat_dpad`); tile counts only in comments (`1600ms // 8`, `8100ms // 27++ (snow)`) | +| Facing | passed in by caller; not detected | `DpadState::last_dir` | +| Doors | `walk_through_door` (:451): path + 300 ms under `BlackScreenOverWatcher`; `check_room` floor colour | `BlackScreenOverWatcher` everywhere; `walk_until_doorway` `Segment_01.cpp:85-187` (black screen then battle menu = wild battle, else doorway) | +| Arrival | the transition only | transition, or landmark match (00–03) | +| Executor stubs | — | `Utils/PokemonBDSP_AutoStory_Navigation.cpp:19-52`: `walk_steps`, `walk_until_dialog`, `walk_until_battle` are TODO | + +FRLG screen geometry: `GAME_BOX` (`FRLG/PokemonFRLG_Settings.cpp:110-115`) +is exactly 6.5× of 240×160 at 1080p; one tile = 104 px; the view is 15×10 +tiles with the player in the centre tile. + +### 4.2 Interruptions + +- **FRLG:** no walking code watches for trainers, wild battles, NPC dialog or + items (the E4 paths are safe only because the League has none). + `exit_wild_battle` (`Navigation.cpp:576-660`) is a good, tested state + machine for leaving a battle, but nothing feeds position back into a path. +- **BDSP:** trainer spotting is watched with `MarkDetector` ("!"), then + battle, then `move_back_after_unexpected_battle(trainer_id)`, a per-segment + if-chain of hard-coded pushes (Seg04:188, Seg05:185, Seg06:138, Seg07:203, + Seg08:134, Seg09:66). `handle_unexpected_battle` (`Utils/..._Battle.cpp:73-100`) + re-runs the whole action after a battle instead of resuming. + `recalibrate_after_battle` and `handle_unexpected_battle` are never called + by segments. Wild battles are mostly avoided with Repel; Repel expiry is a + `ShortDialogWatcher` interrupt (Seg07:687-698). +- **Neither** reports "which step and tile was I on", handles item pickups or + generic NPC dialog during a walk, or re-localizes other than by hard-coded + pushes or a reset. + +### 4.3 Landmark alignment (BDSP 00–03) + +`match_landmarks` (`Utils/PokemonBDSP_OverworldMatchers.cpp:46-126`): +downscale to 960×540 grey (optional local-contrast or blue-fraction +features), `TM_CCOEFF_NORMED` per landmark in a search box, margin over the +best competitor outside an exclusion radius, multiple landmarks must agree +within ~1/64 × 1/54 of the screen; fine pass then a coarse pass that can +never declare "at target". Lighting variants per hour count as one landmark +(`match_lighting_pair` :309-340), with a lighting sweep test program. + +Control loop (`align_to_route204_floaroma_turn`, `Segment_02.cpp:406-463`): +snapshot → if dialog or battle, return interrupted → match → 3 consecutive +at-target hits with 150 ms waits = done → else one-axis joystick nudge of 40 +or 100 ms, 250 ms settle → "blocked" if dx moved < 1/384 over 3 moves, switch +axis → throw after 12 frames lost → give up after 60. + +This is the strongest movement code in the PR. It also fits FRLG better than +BDSP: no lighting changes, exact pixels, and an offset in game-box fractions +converts directly to whole tiles (`round(dx·15)`, `round(dy·10)`), so FRLG +alignment becomes "measure → emit a `{dir, n}` path → re-measure" instead of +nudging. Sample only while standing still (the view scrolls during a step); +avoid animated tiles; Flash-dark caves are the exception. + +## 5. 2D movement: shared design + +### 5.1 Pieces + +Shared, console-free, in `SerialPrograms/Source/Pokemon/Navigation/` +(precedent: `Pokemon/Pokemon_AdvRng.h` is shared by FRLG and RSE): + +```cpp +namespace PokemonAutomation{ +namespace Pokemon{ + +enum class TileDirection{ UP, DOWN, LEFT, RIGHT }; + +struct TileStep{ + TileDirection direction; + uint16_t tiles; + bool ends_in_warp = false; // door/stairs: expect a fade at the end + std::optional trainer_stops_at; // sight line triggers after this many tiles +}; +using TilePath = std::vector; + +enum class WalkInterrupt{ NONE, WILD_BATTLE, TRAINER_BATTLE, DIALOG, ITEM, EARLY_WARP, NO_WARP, BLOCKED }; + +struct StepOutcome{ + WalkInterrupt reason = WalkInterrupt::NONE; + std::chrono::milliseconds walked{0}; // input start -> detection frame time +}; + +struct PathRunResult{ + bool completed = false; + WalkInterrupt last_reason = WalkInterrupt::NONE; + size_t step = 0; // where it stopped + uint16_t tiles_done_in_step = 0; + bool tiles_exact = false; + size_t interrupts = 0; +}; + +class TileMovementActions{ +public: + virtual ~TileMovementActions() = default; + virtual StepOutcome walk(std::optional facing, const TileStep& step) = 0; + virtual uint16_t estimate_tiles(const TileStep& step, std::chrono::milliseconds walked) const = 0; + virtual bool resolve(WalkInterrupt reason) = 0; // battle/dialog handled, back in overworld + virtual std::optional relocalize(const TileStep& step) = 0; // landmark fix, if any +}; + +class InterruptPolicy{ +public: + enum class Decision{ RESUME, RESTART_PATH, ABORT }; + virtual ~InterruptPolicy() = default; + virtual Decision on_interrupt(const PathRunResult& state) = 0; +}; + +PathRunResult run_tile_path( + Logger& logger, + TileMovementActions& actions, + InterruptPolicy& policy, + std::optional facing, + const TilePath& path, + size_t max_interrupts = 10 +); + +// Alignment: BDSP nudges the joystick, FRLG emits whole tiles. +struct LandmarkFix{ bool located = false, at_target = false, coarse = false; double dx = 0, dy = 0; }; +class AlignActions{ +public: + virtual ~AlignActions() = default; + virtual std::optional observe() = 0; // nullopt = interrupted + virtual void move_toward(double dx, double dy) = 0; + virtual void settle() = 0; +}; +struct AlignConfig{ size_t max_attempts = 60, confirmations = 3, max_missing = 12; double blocked_epsilon = 1.0/384; }; +enum class AlignResult{ ALIGNED, INTERRUPTED, LOST, DID_NOT_CONVERGE }; +AlignResult align_to_landmark(Logger& logger, AlignActions& actions, const AlignConfig& config); + +} +} +``` + +Per game (adapters in the game module, so dependencies point +VideoGames → Pokemon): frame timings and speeds (walk, run, bike, surf, +snow), how a step is sent (FRLG one continuous d-pad hold; BDSP d-pad taps), +detectors (black screen box, battle start, dialog, "!" mark, item jingle), +landmark matchers and templates, field moves, battle resolution. Do **not** +share timing constants: two engines are not evidence for a common model. + +### 5.2 Getting back on the path after an interrupt + +Options for "how many tiles of the interrupted step were done": + +- **A. Time estimate** `floor((t_detect − t_start − turn) / step)`, using the + detecting frame's timestamp and starting the clock only after + `wait_for_all_requests()`. ±1 tile from emulator/capture latency. +- **B. Path data.** A trainer's sight line triggers on a fixed tile, so the + step can declare `trainer_stops_at`. Exact. This is what BDSP's hard-coded + pushes encode, without a schema, and keyed by strings: `Segment_07.cpp:214` + matches `"route_215_skier_edward"` but the only caller (`:773`) passes + `"route_216_skier_edward"`, so the 8.1 s push never runs. +- **C. Landmark fix** (§4.3). Exact where templates exist. +- **D. Bonk anchor.** Walk into a known wall, counter or door until blocked + or warped; overshoot is harmless. Already how Pokécenter entry works. + +Recommendation: B when the step declares it; otherwise A, marked inexact, and +end with C or D before anything that needs an exact tile (doors beside walls, +interacting, the next trainer). Never chain two inexact estimates. + +### 5.3 Tests (no console) + +Following `ScriptedWildBattleExit` (`FRLG/PokemonFRLG_Tests.cpp:46-166`): +executor bookkeeping (step/tile indices, splitting the remainder after an +interrupt, early warp vs missing warp, `max_interrupts`, RESUME vs +RESTART_PATH vs ABORT); FRLG hold-duration maths (turn cost, mid-step switch) +if computed by a pure function; `estimate_tiles` boundaries; the alignment +control law fed scripted `LandmarkFix` sequences (converging, blocked, lost +13 frames, interrupted). Matchers themselves: screenshot tests in +CommandLineTests, one PR per detector (Mysticial's request on #1717). + +### 5.4 Risks + +- NSO GBA runs ~59.73 Hz inside a 60 Hz output; long holds drift. Split long + paths at anchors. +- Input and capture latency hurt option A; dropped 33–40 ms taps (use ≥80 ms + or continuous holds). +- BDSP joystick moves are not grid-locked: snap back to the grid (d-pad or a + wall bump) after any joystick alignment. +- Variable speed tiles and forced movement (snow, bike, ledges = 2 tiles, + spin tiles, currents), wandering NPCs blocking or pushing. +- Battle intro and door fade both look like a black screen: check for a + battle menu after the fade (BDSP `walk_until_doorway` does; FRLG must). + +## 6. Feedback for the BDSP team (draft; the user decides whether to post) + +They asked for feedback on "the SV-derived architecture, checkpoint and +recovery contracts, BDSP helper/detector boundaries, resource distribution, +and the order in which to extract focused PRs". + +**Architecture.** Following SV is right, and their `section_database` is +cleaner than SV's six copies. Rather than a third copy of the framework +(SwSh #1207 will need one too), propose the shared core in §3 and adopt it +when it lands; their loop becomes a hooks object with policy `{20, ..., never +report}` and their stats/base classes/database code are deleted. + +**Checkpoint and recovery contracts.** +- `reload_backup_save` is an empty TODO but the `save=false` path calls it + and then re-runs the action without any reset (`BT.cpp:188-197`); remove + the path or implement it. +- No start > end check, no recoverable-error report, no `GO_HOME_WHEN_DONE`, + language fixed to English (`BA.cpp:701`): adopt SV's behaviour here. +- Diagnostic options marked "remove before production" (`BA.h:42-46`) and + `CheckpointRetryScope`: gate behind developer mode or drop. +- Checkpoint order is written twice (segment + registry) and has drifted: + - Segment 08's `run_segment` stops at 0821 (`Segment_08.cpp:~116`), so + 0822–0826 (Sunyshore and the 8th gym) never run in segment mode. + - 0717 is missing from the advanced list (`BA.cpp:155-156` goes 0716 → + 0718). + - Deriving segments from registry ranges removes this class of bug. +- Badge texts swapped: Segment 04 says "Third badge (Hearthome)", Segment 05 + "Fifth badge (Veilstone)"; Veilstone is the 3rd, Hearthome the 5th. + +**Helper/detector boundaries.** +- Movement: replace per-segment `move_back_after_unexpected_battle` chains + with path data (`trainer_stops_at`, §5.2). Includes the dead skier push + above. +- The landmark loop (segments 00–03) deserves to become the shared alignment + routine (§5.1); later segments would gain from it most. +- `handle_battle` is copied into each of segments 04–09, keyed by trainer-id + strings, while `Battle.cpp`'s `handle_expert_battle` and + `handle_battle_with_outside_help` have no callers; pick one. +- `Navigation.cpp` stubs and `Dialog.cpp` (already agreed to delete). +- Changes to shared `DialogDetector` boxes affect every BDSP program; those + need screenshot tests before anything else depends on them. + +**Resources.** Templates live only in their Packages fork; per-hour variants +multiply them. Document which landmarks need lighting sets and keep the +lighting sweep program as a dev tool. + +**Extraction order.** Agree with Mysticial: detectors first, one PR each +with CommandLineTests images. Then navigation primitives (shared tile path +if it exists by then), then the battle handler, then segments 00–01. + +Tone: the PR is explicitly WIP and asks for early feedback; keep it to a few +concrete items plus the shared-core offer. + +## 7. FRLG AutoStory plan + +### 7.1 Reuse + +Already on `main` (`FRLG/`): + +- Detectors: dialogs, battle menu/dialogs/learn/level-up/out-of-PP, party + and summary, start menu, bag, load menu (untested on a new game), + selection arrows, faint watchers, fly map, E4 rooms, Hall of Fame. +- Navigation: `fly_from_kanto_map` (13 towns), `heal_at_pokecenter`, + `enter_leave_pokecenter`, `use_teleport_from_overworld`, + `open_party_menu_from_overworld`, `save_game_to_overworld`, `soft_reset`. +- Battle: tested `exit_wild_battle`; `spam_first_move`; + `EliteFourFarmer::run_battle` (OCR the opponent, move plan per opponent, + out-of-PP) as the model for a trainer battle handler. +- Story fragments: StarterRng's `walk_to_rival_battle`, + `walk_to_route1_from_lab`, `auto_battle_rival`; SidHelper's + `finish_intro_animations`. +- **Money:** `NuggetBridgeFarmer` already loops the Nugget Bridge event + (loses the battle on purpose, ~72 s per Nugget by its "100 ≈ 2 hours" + default, Nugget sells for 5,000, so ≈250k/hour). Wrap it as an optional + "money top-up" checkpoint after Nugget Bridge (or any time later, by flying + to Cerulean), with a target amount. +- `ItemDuplication` (Retro Mail glitch; needs Farfetch'd from the Vermilion + trade): optional way to duplicate Rare Candies instead of grinding. Keep + it out of the default route; offer it as a config. + +### 7.2 Missing pieces (infrastructure, ~3–5k lines) + +1. Shared run flow (§3) adopted in FRLG: FRLG hooks (save via start menu, + reset via `soft_reset` + load menu), options, registries. +2. Shared tile path (§5) with the FRLG adapter, moving `walk_path` and the + constants out of `EliteFourFarmer.cpp`; add run (8 frames/tile), bike (6), + surf (8) per decomp; ledge steps. +3. Overworld detector (overworld vs dialog vs battle vs menu without opening + the start menu) and facing detection (player sprite in the centre tile). +4. Walk interrupts: trainer "!" or approach, wild battle (black screen + + battle menu), item pickup jingle/dialog, NPC dialog; resume via §5.2. +5. Trainer battle handler: move choice (per-checkpoint plan first, type + table later), "will you switch?" (avoid by Battle Style = Set), next + Pokémon after a faint, move learn (skip or replace per config), + evolution (allow/cancel per config), whiteout → fail the checkpoint. +6. New game: intro, naming keyboard (preset names avoid it), options menu + (text Fast, animations Off, style Set), load menu on a fresh save. +7. Field moves: teach HM from bag, use Cut/Surf/Strength from the party + menu, Fly (exists), Bike on/off; puzzles below. +8. Shop and PC: buy list per Mart, deposit/withdraw for HM carriers. +9. Catch routine and the requirements planner (§7.6). + +English only (decision 5), so text detectors and OCR need one language. + +### 7.3 Route data + +The decomp (`data/maps//map.json`) gives every object event with x, y, +movement type, `trainer_type`, sight range and script, plus warps, coord +events and signs; `data/layouts//map.bin` gives metatiles and collision +(behaviours such as ledges, spin tiles and currents come from tileset +attributes). That is enough to: + +- plan paths offline with a small planner over collision + ledges (prior + art: `40Cakes/pokebot-gen3` `modules/map_path.py`, GPL-3.0, which plans on + live RAM; we would run the same idea over the decomp files and **emit + reviewed C++ `TilePath` literals**, not ship the planner); +- mark each trainer's sight line on the path so `trainer_stops_at` is + computed, not guessed; +- simulate spin tiles (Rocket Hideout) and plan Strength boulder pushes + (Seafoam optional; Victory Road mandatory). + +Online maps (Bulbapedia route pages, PokeTools) list trainers but not exact +positions; the decomp is the source of truth. + +### 7.4 Segments (draft) + +| Seg | Content | Notes | +|---|---|---| +| 00 | New game → starter → lab rival | names, options, starter config | +| 01 | Parcel → Pokédex → Viridian Forest → Brock | Route 22 rival optional | +| 02 | Route 3 → Mt. Moon (fossil) → Misty → Nugget Bridge → Bill (S.S. Ticket) | money top-up available from here | +| 03 | S.S. Anne (Cut) → Surge; VS Seeker; Bike (opt.) | HM carrier for Cut | +| 04 | Route 9/10 → Rock Tunnel → Lavender → Celadon → Erika; Tea | Flash optional | +| 05 | Rocket Hideout (spin tiles, Lift Key, Silph Scope) → Pokémon Tower → Poké Flute | | +| 06 | Snorlax (Route 12 or 16) → Fuchsia → Koga → Safari (Surf, Strength) | Safari is a step-limited zone | +| 07 | Saffron: Silph Co. (Card Key, warp pads, rival, Giovanni) → Sabrina | Lapras optional | +| 08 | To Cinnabar (Route 21 by default) → Mansion (Secret Key) → Blaine | Seafoam optional; decline One Island | +| 09 | Giovanni (Viridian) → Route 22 rival → Victory Road (Strength boulders) | | +| 10 | Elite Four + Champion | reuse `EliteFourFarmer` pieces | +| opt | Money top-up, leveling loop, gift Pokémon, fossils | config-driven, outside the main order | + +Estimate ~90–110 checkpoints. Hardest: 00 (keyboard, intro), 05 (spin +tiles), 07 (warp pads), 09 (boulders), and leveling before each gym. + +### 7.5 Config (in game order) + +Player/rival names (presets by default); options (forced by the program); +starter; nickname prompts (always no); Magikarp (skip); Mt. Moon fossil +(Dome/Helix); Old Amber (skip); Bike (yes: shortens Cycling Road and +travel); Flash (skip); Eevee and stone (skip); Game Corner prizes (skip); +Snorlax route (12 or 16) and catch or defeat; Hitmonlee/Hitmonchan; Lapras +(yes: Surf carrier); Sevii trip (decline); optional legendaries (skip); HM +carriers (Cut/Surf/Strength: default to gifts and route catches); shop list +per Mart; move learning (keep starter's best moves per a table); money +target for the top-up; leveling targets per gym; Rare Candy duplication +(off). + +Facts to design around (decomp): HM field use needs Cascade (Cut), Rainbow +(Strength), Soul (Surf); Flash/Fly/Rock Smash are optional for Kanto; Rock +Tunnel's darkness is cosmetic for movement; Saffron guards want Tea; the +Viridian Gym opens after badges 2–7; blacking out costs level × 4 × a +badge-based multiplier, not half the money. + +### 7.6 Working backwards: the requirements plan + +The team, catches and purchases follow from what the route and the chosen +options require, each with a deadline. Write this down as data, one row per +requirement, and derive the catch/gift/shop checkpoints from it: + +| Requirement | Needed by | Providers (pick per version and options) | +|---|---|---| +| Cut user (Cascade badge) | Vermilion Gym tree (seg 03) | Oddish/Bellsprout (Routes 24/25, version exclusive), Paras (Mt. Moon), Farfetch'd (Vermilion in-game trade) | +| Surf user (Soul badge) | Cinnabar (seg 08) | Lapras (Silph Co. 7F gift, seg 07), a Water starter, Seel/Psyduck etc. | +| Strength user (Rainbow badge) | Victory Road (seg 09) | Machop line, Snorlax, Lapras | +| Battle strength per gym | each gym and the E4 | starter + leveling loops; Rare Candies (duplication option); type coverage for Brock/Misty | +| Money for each Mart list | per Mart | trainer prize money; Nugget Bridge top-up option | +| Retro Mail duplication (option) | when enabled | Farfetch'd from the Vermilion trade (needs the Pokémon it asks for), Retro Mail, the item to copy; see `ItemDuplication` | +| Nugget Bridge top-up (option) | after seg 02 | party able to lose on purpose and heal; `NuggetBridgeFarmer` preconditions | + +Consequences: + +- A **catch routine** is part of the infrastructure (weaken without + fainting, throw until caught, handle box-full and nickname prompts), plus + the encounter detector to know what appeared (`WildEncounterReader` + exists). +- **HM teaching** and party order (who leads, who carries HMs) are steps + derived from the table, not written by hand in each segment. +- A small **planner** checks a chosen config before the run: every + requirement has a provider before its deadline, the money plan covers the + Mart lists, version exclusives exist in the chosen version. A config that + 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 Milestones + +| M | Deliverable | Rough size | Validation | +|---|---|---|---| +| F0 | Run-flow prework P1–P5 (SV) | ~1k moved, ~400 new incl. tests | SV AutoStory smoke run of a few checkpoints | +| F1 | Shared tile path + FRLG adapter; E4 farmer switched to it | ~800 | unit tests; E4 farmer run unchanged | +| F2 | FRLG overworld/facing detectors, walk interrupts, trainer battle handler | ~1.5k | screenshot tests; scripted fakes | +| F3 | FRLG AutoStory program shell (options, hooks, registries) + segment 00–01 pilot | ~1.5k | live: new game → Boulder Badge, each checkpoint ×3 from its save | +| F4 | Route-planning tool (offline) and segments 02–04 | ~2k | live per checkpoint | +| F5 | Segments 05–07 (puzzles) | ~2k | live | +| F6 | Segments 08–10, optional segments, money top-up | ~2k | full run | + +Decide after F3 using measured lines and Switch hours per checkpoint. + +## 8. Process + +- All new work as fork drafts on `dayfine/Arduino-Source`; per AGENTS.md, + Codex owns new feature branches until the first fork PR and does the live + validation; Claude prepares PRs. Nothing goes upstream without the user. +- F0 touches SV AutoStory, which is someone else's merged program: pure moves + first, behaviour changes separately, `--color-moved` reviewable. +- Code-health limits apply to every new file (functions ≤50 lines); the + segment style should be short checkpoint functions calling path data and + helpers, which also keeps reviews small. + +## 9. Decisions (user, 2026-10-25) + +1. **Shared pieces:** propose them to the BDSP team and offer to work on them + (F0, F1), not wait for them to ask. +2. **Scope:** main story to the Champion. No Sevii or post-game. +3. **Shortcuts** (Nugget Bridge money, Retro Mail duplication): available as + options. They need planning, e.g. catching the right Pokémon at the right + time, so they feed into the requirements plan (§7.6). +4. **Team:** worked out backwards from what the route and options need + (§7.6), not chosen up front. +5. **Language:** English only. + +Still open: FireRed vs LeafGreen first (encounter tables and version +exclusives differ; the console has LeafGreen installed). From ae7c32ad317719a60ac29ca3698f30cc2fe25b97 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 00:37:13 -0700 Subject: [PATCH 02/24] Design doc: lead with problem, situation and proposal; FireRed, solo from a new game Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory.md | 91 ++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 32 deletions(-) diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 50a0ffff58..985cf408dc 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -12,35 +12,58 @@ Paths: `SV/` = `SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/`, ## 0. Summary -- **Run flow.** BDSP copied SV's framework almost name for name (segment and - checkpoint interfaces, registries, start/end selects, save-then-retry loop, - stats). The two copies have already drifted: retry limits (SV 100 with an - off-by-one, BDSP 20), error reporting (SV only), day skip (SV only), start > - end check (SV only). SwSh #1207 does not use the framework at all. A small - game-agnostic core (retry loop behind a hooks interface, index/range math, - stats, select databases) can be extracted from SV as pure moves in five - small PRs, then adopted by BDSP and FRLG. Each game keeps its own options, - save/reset functions and checkpoints. -- **2D movement.** FRLG and BDSP both move on a tile grid, and both - codebases reinvented the same three things badly or partially: a path as - `{direction, tiles}` data, walking under interrupt watchers, and getting - back on the path after an interrupt. BDSP's best idea is closed-loop - landmark alignment (segments 00–03); its later segments are blind scripts - with per-trainer hard-coded "move back" pushes, one of which never runs - (§5.2). A shared, console-free core (path executor with resume bookkeeping, - interrupt policy, alignment control law) plus per-game adapters (timings, - detectors, matchers) fits both. Timing constants stay per game. -- **FRLG AutoStory** is smaller than SV or BDSP because GBA movement is - frame-exact, the camera is fixed with the player centred, Kanto has no - lighting changes, and the decomp gives exact trainer positions and sight - ranges. Estimate: ~3–5k lines of infrastructure, ~90–110 checkpoints at - 40–80 lines each, ~10–12k lines total (SV 22.4k, BDSP 32.7k). The - bottleneck is Switch time to validate each checkpoint, not code. -- **Order:** (1) run-flow prework from SV, (2) shared tile movement with FRLG - as the first adopter (moving `EliteFourFarmer`'s walker out), (3) FRLG - pilot Pallet → Pewter to measure lines and hours per checkpoint, (4) the - rest of FRLG by segment. Offer the shared pieces to the BDSP team; their - detector-first extraction plan (Mysticial's request) is independent of it. +**Problem.** AutoStory programs (play a game's story from a new save, +unattended) are being written one game at a time. SV has one on `main` +(22.4k lines). A team is building BDSP +(PokemonAutomation/Arduino-Source#1717, 32.7k lines, WIP), SwSh has an +early draft (#1207), and we want one for FireRed. Each copies or reinvents +the same two things: + +- **The run flow:** an ordered list of checkpoints, each starting from a + save, retried from that save when it fails, with start/end selection, + stats and notifications. +- **Walking on a grid** (FRLG and BDSP): following a path, and getting back + on it after a trainer, a wild Pokémon or a dialog interrupts the walk. + +**Situation.** + +- BDSP copied SV's run flow almost name for name, and the copies have + already drifted: different retry limits (SV allows 100 but runs 102, BDSP + 20), error reporting and day skip only in SV, BDSP's backup reload still a + TODO. SwSh does not use the framework at all. None of them has unit tests + of the flow. +- Neither SV, BDSP nor the existing FRLG code can tell which step of a path + it was on when something interrupted it. BDSP's later segments push the + player back by hard-coded amounts per trainer, keyed by strings; one of + those pushes never runs because the names do not match. Its earlier + segments have a good image-based landmark alignment loop that the rest of + the PR does not use. +- FRLG on `main` has most of the low-level pieces (detectors, fly, heal, + a tested wild-battle exit, a frame-exact tile walker inside the Elite Four + farmer) but nothing that plays the story. +- The pokefirered decompilation gives exact positions and sight ranges of + every trainer, so FRLG paths can be planned offline instead of tuned by + hand. + +**What we think should happen.** + +1. Move SV's run flow into a small shared module, as pure moves in five + small PRs with unit tests, keeping SV's behaviour exactly. Each game keeps + its own options, save/reset and checkpoints. +2. Build a shared, console-free tile-path executor (path as data, resume + after an interrupt, pluggable interrupt policy, landmark alignment), with + per-game timings and detectors. FRLG is the first user; BDSP can adopt + it. We offer to do both and to help BDSP move onto them. +3. Build a FireRed AutoStory to the Champion on top of them: roughly 90–110 + checkpoints, ~10–12k lines, piloted on Pallet Town → Pewter City first. + It must work solo from a new game: no trades and no transferring a + levelled Pokémon in. The team, catches and purchases are derived from + what the route needs (§7.6); shortcuts such as the Nugget Bridge money + loop are options. + +The rest of the doc gives the evidence (§2, §4), the proposed interfaces and +PR sequence (§3, §5), feedback for the BDSP draft (§6) and the FireRed plan +(§7). ## 1. Design from first principles @@ -566,7 +589,7 @@ requirement, and derive the catch/gift/shop checkpoints from it: | Requirement | Needed by | Providers (pick per version and options) | |---|---|---| -| Cut user (Cascade badge) | Vermilion Gym tree (seg 03) | Oddish/Bellsprout (Routes 24/25, version exclusive), Paras (Mt. Moon), Farfetch'd (Vermilion in-game trade) | +| Cut user (Cascade badge) | Vermilion Gym tree (seg 03) | Oddish (Routes 24/25; FireRed exclusive, Bellsprout in LeafGreen), Paras (Mt. Moon), Farfetch'd (Vermilion in-game trade, option only) | | Surf user (Soul badge) | Cinnabar (seg 08) | Lapras (Silph Co. 7F gift, seg 07), a Water starter, Seel/Psyduck etc. | | Strength user (Rainbow badge) | Victory Road (seg 09) | Machop line, Snorlax, Lapras | | Battle strength per gym | each gym and the E4 | starter + leveling loops; Rare Candies (duplication option); type coverage for Brock/Misty | @@ -625,5 +648,9 @@ Decide after F3 using measured lines and Switch hours per checkpoint. (§7.6), not chosen up front. 5. **Language:** English only. -Still open: FireRed vs LeafGreen first (encounter tables and version -exclusives differ; the console has LeafGreen installed). +6. **Version:** FireRed (LeafGreen is already finished on the test + console). +7. **Solo from a new game:** the program must not require a trade, a + trade-back, or a levelled Pokémon brought in from another save. Optional + trades the game itself offers (e.g. the Vermilion Farfetch'd) are + allowed only behind an option. From d309957116f946c4d525023953745c318cb950aa Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 00:37:21 -0700 Subject: [PATCH 03/24] Design doc: full upstream reference for the SwSh draft Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 985cf408dc..a5110ed2c1 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -16,7 +16,7 @@ Paths: `SV/` = `SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/`, unattended) are being written one game at a time. SV has one on `main` (22.4k lines). A team is building BDSP (PokemonAutomation/Arduino-Source#1717, 32.7k lines, WIP), SwSh has an -early draft (#1207), and we want one for FireRed. Each copies or reinvents +early draft (PokemonAutomation/Arduino-Source#1207), and we want one for FireRed. Each copies or reinvents the same two things: - **The run flow:** an ordered list of checkpoints, each starting from a From f8481a0e062fef984d8f26b1c424ad15475f57b3 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 00:42:03 -0700 Subject: [PATCH 04/24] Design doc: prior art (junari's FRLG script) and ComputerControl#259 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory.md | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index a5110ed2c1..294677e805 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -44,6 +44,15 @@ the same two things: - The pokefirered decompilation gives exact positions and sight ranges of every trainer, so FRLG paths can be planned offline instead of tuned by hand. +- It has been done before outside this project: a Poke-Controller script + (`FRLG_Story_Auto.py`, [junari's blog](https://junari.hatenablog.com/entry/2024/08/02/234339)) + plays FRLG to the Hall of Fame with the starter alone in about 12–14 + hours, on a GameCube Game Boy Player or a Switch, resetting to the last + save on failure. Users asked for the same here + ([ComputerControl#259](https://github.com/PokemonAutomation/ComputerControl/issues/259)); + Mysticial's reply there is that an AutoStory takes far more effort than it + looks (SV took over a year). Shared infrastructure and decomp-planned paths + are how this plan tries to keep that cost down. **What we think should happen.** @@ -473,6 +482,35 @@ concrete items plus the shared-core offer. ## 7. FRLG AutoStory plan +### 7.0 Prior art: junari's FRLG script + +From the [blog post](https://junari.hatenablog.com/entry/2024/08/02/234339) +(Poke-Controller MODIFIED, Python; we have not read its code): + +- **Scope and time:** new game to the Network Machine, Silph Co., the + ending or the Hall of Fame (selectable stop point); about 12–14 hours to + the end. +- **Team:** the starter alone fights every trainer. Squirtle is fastest, + then Charmander, then Bulbasaur. Moves come from TMs and tutors: Squirtle + Mega Kick + Water Pulse; Charmander Mega Kick, Dig, Dragon Claw; Bulbasaur + Return, Earthquake. No transfers from another save. This confirms the + solo rule (§9) is workable and shrinks the requirements plan (§7.6) to HM + users, TMs and tutors, and money. +- **Recovery:** on a lost battle or a loop running too long, reset and + restart from the nearest save. +- **Options:** start/stop number, version, hardware, language, gender, + player/rival names, starter, fossil, Dojo Pokémon, and a "Nugget farm" + mode (lose to the Nugget Bridge Rocket repeatedly, 1.5–2 min each), the + same trick as our `NuggetBridgeFarmer`. +- **Setup it requires:** delete the save from the title screen (Y + B + Up + on Switch), 720p output, screen size 100%. +- **Images:** none shipped; it crops reference images at run time on the + first run and reuses them. + +Its terms forbid redistribution and claiming authorship, so it is a +reference for the route, team and options, not a source of code. Its demo +videos are useful for checking routes. + ### 7.1 Reuse Already on `main` (`FRLG/`): @@ -592,7 +630,7 @@ requirement, and derive the catch/gift/shop checkpoints from it: | Cut user (Cascade badge) | Vermilion Gym tree (seg 03) | Oddish (Routes 24/25; FireRed exclusive, Bellsprout in LeafGreen), Paras (Mt. Moon), Farfetch'd (Vermilion in-game trade, option only) | | Surf user (Soul badge) | Cinnabar (seg 08) | Lapras (Silph Co. 7F gift, seg 07), a Water starter, Seel/Psyduck etc. | | Strength user (Rainbow badge) | Victory Road (seg 09) | Machop line, Snorlax, Lapras | -| Battle strength per gym | each gym and the E4 | starter + leveling loops; Rare Candies (duplication option); type coverage for Brock/Misty | +| Battle strength per gym | each gym and the E4 | the starter alone, levelled by every trainer on the way (proven by junari's script, §7.0); TMs and tutors (e.g. Water Pulse from Misty, Mega Kick tutor, Dig, Dragon Claw, Return, Earthquake); leveling loops or Rare Candies (duplication option) as a fallback | | Money for each Mart list | per Mart | trainer prize money; Nugget Bridge top-up option | | Retro Mail duplication (option) | when enabled | Farfetch'd from the Vermilion trade (needs the Pokémon it asks for), Retro Mail, the item to copy; see `ItemDuplication` | | Nugget Bridge top-up (option) | after seg 02 | party able to lose on purpose and heal; `NuggetBridgeFarmer` preconditions | From 088bf620d4366d1b625e722dd3e735bb56651c19 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 00:46:27 -0700 Subject: [PATCH 05/24] Design doc: PR plan with sizes for reviewers Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory.md | 73 +++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 294677e805..9a3d050007 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -70,6 +70,11 @@ the same two things: what the route needs (§7.6); shortcuts such as the Nugget Bridge money loop are options. +**What reviewers should expect:** about 30 PRs, most 200–600 lines, in +the order of §7.7. The first eight (shared run flow and tile movement) stand +on their own and help SV and BDSP whether or not the FireRed program goes +ahead. + The rest of the doc gives the evidence (§2, §4), the proposed interfaces and PR sequence (§3, §5), feedback for the BDSP draft (§6) and the FireRed plan (§7). @@ -649,19 +654,61 @@ 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 Milestones - -| M | Deliverable | Rough size | Validation | -|---|---|---|---| -| F0 | Run-flow prework P1–P5 (SV) | ~1k moved, ~400 new incl. tests | SV AutoStory smoke run of a few checkpoints | -| F1 | Shared tile path + FRLG adapter; E4 farmer switched to it | ~800 | unit tests; E4 farmer run unchanged | -| F2 | FRLG overworld/facing detectors, walk interrupts, trainer battle handler | ~1.5k | screenshot tests; scripted fakes | -| F3 | FRLG AutoStory program shell (options, hooks, registries) + segment 00–01 pilot | ~1.5k | live: new game → Boulder Badge, each checkpoint ×3 from its save | -| F4 | Route-planning tool (offline) and segments 02–04 | ~2k | live per checkpoint | -| F5 | Segments 05–07 (puzzles) | ~2k | live | -| F6 | Segments 08–10, optional segments, money top-up | ~2k | full run | - -Decide after F3 using measured lines and Switch hours per checkpoint. +### 7.7 PR plan for reviewers + +Reviewers should know up front what is coming. The whole plan is about 30 +PRs. Most are 200–600 changed lines, each does one thing, and each says what +to read first. Upstream allows two open PRs from us at a time, so they arrive +in order; the rest wait as drafts on the fork. + +| # | PR | Depends on | Kind | Size (lines) | What the reviewer reads | +|---|---|---|---|---|---| +| **Run flow (SV, no behaviour change)** | | | | | | +| R1 | Shared start/end select databases | — | move | ~150 | `--color-moved`; same slugs and labels | +| R2 | Story range maths + tests | R1 | move + tests | ~200 | the pure function and its table test | +| R3 | Shared `AutoStoryStats` | — | move | ~80 | stat keys unchanged | +| R4 | Retry core behind hooks + tests | R3 | move + new | ~400 (half tests) | §3.2 list of kept behaviours; SV adapters | +| R5 | Dev harness out of the SV program class | — | move | ~300, mostly a deleted dead block | `--color-moved` | +| **Tile movement (shared)** | | | | | | +| T1 | Tile-path executor + interrupt policy + tests | — | new | ~500 (half tests) | result types, resume bookkeeping | +| T2 | FRLG adapter; Elite Four farmer uses it | T1 | move + new | ~300 | walker moved out of `EliteFourFarmer.cpp`; farmer unchanged on hardware | +| T3 | Landmark alignment loop + tests | T1 | new | ~300 | control law against scripted fixes | +| **FRLG detectors (one per PR, images in CommandLineTests)** | | | | | | +| D1 | Overworld detector | — | new | ~150 + images | detector + screenshot tests | +| D2 | Facing detector | D1 | new | ~150 + images | same | +| D3 | Trainer spotting / item pickup watchers | — | new | ~150 + images | same | +| D4 | New-game screens and naming keyboard | — | new | ~200 + images | same | +| **FRLG building blocks** | | | | | | +| B1 | Walk interrupts for FRLG (battle, dialog, item) | T2, D1, D3 | new | ~300 | resolve() paths; fakes | +| B2 | Trainer battle handler + tests | — | new | ~500 (half tests) | decisions with scripted fakes | +| B3 | Field moves: teach HM, Cut/Surf/Strength, Bike | D1 | new | ~300 | menus; hardware run | +| B4 | Mart purchases | — | new | ~250 | buy list; hardware run | +| **FRLG AutoStory** | | | | | | +| S0 | Program shell: options, hooks, registries, requirements check | R1–R4 | new | ~500 | options; start-up checks; tests of the requirements plan | +| S1–S11 | One PR per segment (00 … 10) | S0, B1–B4 | new + path data | ~500–900 each | checkpoint list, start/end states, the paths as data; hardware runs of each checkpoint | + +Notes: + +- R1–R5 and T1–T3 are useful on their own (SV and BDSP gain from them), so + they can be reviewed before anyone decides on the FRLG program. +- Segment PRs are mostly path data and short checkpoint functions. Paths + are planned offline from the decomp; the planner stays outside the repo + unless reviewers want it under `devtools/`. +- Optional features (Nugget Bridge top-up, Retro Mail duplication) come as + separate small PRs after S0, so they never hold up a segment. + +Milestones, for our own tracking: + +| M | PRs | Validation | +|---|---|---| +| F0 | R1–R5 | SV AutoStory smoke run of a few checkpoints | +| F1 | T1–T3 | unit tests; Elite Four farmer unchanged on hardware | +| F2 | D1–D4, B1–B4 | screenshot tests, fakes, short hardware runs | +| F3 | S0, S1–S2 (pilot: new game → Boulder Badge) | each checkpoint ×3 from its save | +| F4–F6 | S3–S11 | each checkpoint from its save, then full runs | + +Decide whether to go past F3 using the measured lines and Switch hours per +checkpoint. ## 8. Process From 14dd3dd71c43c22c39b417e9cb0641cef8f682c5 Mon Sep 17 00:00:00 2001 From: dayfine Date: Sun, 25 Oct 2026 08:01:26 -0700 Subject: [PATCH 06/24] Design doc: FRLG pilot to Brock first, shared code later Reorder the plan so the first PRs touch only FRLG files and end in a runnable pilot (new game -> Boulder Badge in about 10 PRs, first runnable at PR 5), with an F3 go/no-go gate on checkpoints and Switch hours. The SV/BDSP shared run flow moves to a later phase. Add a one-page upstream-facing proposal, standalone review comment drafts for PokemonAutomation/Arduino-Source#1717 (not posted), and the FRLG authors on main. Drop the agent process section. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-1717-review-drafts.md | 66 ++++ docs/design/AutoStory-Proposal.md | 73 ++++ docs/design/AutoStory.md | 370 ++++++++++++-------- 3 files changed, 372 insertions(+), 137 deletions(-) create mode 100644 docs/design/AutoStory-1717-review-drafts.md create mode 100644 docs/design/AutoStory-Proposal.md diff --git a/docs/design/AutoStory-1717-review-drafts.md b/docs/design/AutoStory-1717-review-drafts.md new file mode 100644 index 0000000000..9d134d7907 --- /dev/null +++ b/docs/design/AutoStory-1717-review-drafts.md @@ -0,0 +1,66 @@ +# Review comment drafts for PokemonAutomation/Arduino-Source#1717 (BDSP AutoStory) + +**Not for merge, and not posted.** These are ready-to-paste drafts for the +user, who decides whether to post them, and when. Each one stands on its own +and makes no request beyond the fix. None of them proposes shared code or +asks the BDSP team to restructure anything. + +Checked against PR head `65094d4cd` (2026-10-25). Before posting, check that +the head has not moved (`gh pr view 1717 -R PokemonAutomation/Arduino-Source +--json headRefOid`), and recheck the line numbers if it has. Paths are under +`SerialPrograms/Source/PokemonBDSP/Programs/AutoStory/`. + +Each draft is meant as an inline comment on the file and line given in its +heading. If posted as a plain PR comment instead, add the path. + +--- + +### 1. `PokemonBDSP_AutoStoryTools.cpp:245-246` (the retry with no save) + +> When `save` is false and the retry scope isn't `SELECTED_RANGE`, a failed +> attempt logs "Reloading from backup save before retry..." and calls +> `reload_backup_save`, which is still an empty TODO (lines 188-197). The +> next attempt then starts from wherever the failure left the player. Until +> the backup reload exists, resetting from HOME here as well (the `save` +> branch just above) would at least retry from a known state. + +### 2. `StorySegments/PokemonBDSP_AutoStory_Segment_08.cpp:116` (segment end) + +> `AutoStory_Segment_08::run_segment` stops after 0821, but the registry +> (`PokemonBDSP_AutoStory.cpp:181-185`) continues to 0826. In segment mode, +> 0822-0826 (the house west of Sunyshore through the eighth gym) never run. + +### 3. `PokemonBDSP_AutoStory.cpp:155-156` (checkpoint list) + +> The checkpoint list goes from 0716 to 0718, so 0717 can't be selected as a +> start or end checkpoint in advanced mode. + +### 4. `StorySegments/PokemonBDSP_AutoStory_Segment_07.cpp:214` (trainer id) + +> This branch matches `"route_215_skier_edward"`, but the only caller +> (`:773`) passes `"route_216_skier_edward"`, the id that `handle_battle` +> (`:242`) also uses. The 8.1 s push back after that battle never runs. + +### 5. `StorySegments/PokemonBDSP_AutoStory_Segment_04.cpp:31` and `Segment_05.cpp:30` (badge texts) + +> In BDSP the third badge is Veilstone (Maylene) and the fifth is Hearthome +> (Fantina). Segment 04's start text says "Third Gym Badge acquired +> (Hearthome City)" and Segment 05's end text says "Fifth Gym Badge acquired +> (Veilstone City)", so the two city names are swapped. + +### 6. `Utils/PokemonBDSP_AutoStory_Battle.cpp:208, 698` (unused handlers), optional + +> `handle_battle_with_outside_help` and `handle_expert_battle` have no +> callers in the PR. Each of segments 04-09 uses its own `handle_battle`, +> keyed by trainer-id strings. Is the plan to switch the segments over to +> these? + +Draft 6 is a question rather than a bug. Leave it out if the thread is +already long. + +--- + +Left out on purpose (design opinions, not defects): the shared run-flow +core, the tile-path executor, moving the landmark alignment loop into shared +code, and the retry-limit differences from SV. Raise them only after the FRLG +pilot is running and only if they are asked about. See AutoStory.md §6. diff --git a/docs/design/AutoStory-Proposal.md b/docs/design/AutoStory-Proposal.md new file mode 100644 index 0000000000..6a98df6baf --- /dev/null +++ b/docs/design/AutoStory-Proposal.md @@ -0,0 +1,73 @@ +# FireRed AutoStory: proposal + +Status: draft, 2026-10-25. The full internal plan, with the evidence and line +references, is [AutoStory.md](AutoStory.md). + +## Problem + +FRLG on `main` has most of the low-level pieces an AutoStory needs: dialog, +battle and menu detectors, fly, heal, a tested wild-battle exit, and a +frame-exact tile walker inside the Elite Four farmer. Nothing plays the story, +and users have asked for it +([ComputerControl#259](https://github.com/PokemonAutomation/ComputerControl/issues/259)). +A Poke-Controller script outside this project already plays FireRed to the +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 is built only in FRLG files and uses +its own copy of the SV-style run flow (checkpoints, retries from the last +save, start/end selection, stats), as BDSP's draft does. I accept that +duplication for now; merging the copies is only worth proposing once one of +them is used. + +About 10 PRs, each 150–500 lines, each doing one thing: + +1. Tile-path executor with unit tests, FRLG-only. +2. Elite Four farmer moved onto it, with no behaviour change. +3. New-game screen and naming-keyboard detectors. +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. + +## 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 cost, honestly + +Mysticial has said that SV AutoStory took over a year. Most of that time +went into hardware hours per checkpoint: writing a checkpoint, then tuning +it and running it again on a console until it is reliable. Shared code and +decomp-planned paths do not shorten that. So the pilot is there to measure +this cost before committing to the rest of the game (about 100 checkpoints +to the Champion). + +## Go/no-go gate + +The pilot passes if **every pilot checkpoint (new game → Boulder Badge, +about 12) succeeds 3 times in a row starting from its own save**, and this +takes **at most 3 Switch hours per checkpoint on average**, counting both +development and validation. If the pilot misses either target, I stop at +Brock. The pilot stays a working program, and I write up what it cost. If +it passes, the projection is roughly 300 hardware hours to the Champion, and +I'll post the measured numbers before continuing. + +## Later, only if the pilot is used + +- The remaining segments to the Champion, one PR per segment. +- Having written a third copy of the run flow, I'd offer to move it into a + shared module, migrate SV AutoStory onto it as pure moves with unit tests, + and offer the same to BDSP. None of this is a precondition for the FRLG + work. diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 9a3d050007..3ecf5f0078 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -1,6 +1,10 @@ -# AutoStory: shared run flow, 2D movement, and an FRLG AutoStory +# AutoStory: FRLG pilot first, shared run flow and 2D movement later -Status: draft for discussion, 2026-10-25. Not proposed upstream yet. +Status: internal plan, revised 2026-10-25 after 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 +file has been posted. Sources: SV AutoStory on `main`; BDSP WIP [PokemonAutomation/Arduino-Source#1717](https://github.com/PokemonAutomation/Arduino-Source/pull/1717) at `65094d4cd`; SwSh WIP PokemonAutomation/Arduino-Source#1207 at `32d506c27`; @@ -16,8 +20,8 @@ Paths: `SV/` = `SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/`, unattended) are being written one game at a time. SV has one on `main` (22.4k lines). A team is building BDSP (PokemonAutomation/Arduino-Source#1717, 32.7k lines, WIP), SwSh has an -early draft (PokemonAutomation/Arduino-Source#1207), and we want one for FireRed. Each copies or reinvents -the same two things: +early draft (PokemonAutomation/Arduino-Source#1207), and we want one for +FireRed. Each copies or reinvents the same two things: - **The run flow:** an ordered list of checkpoints, each starting from a save, retried from that save when it fails, with start/end selection, @@ -51,33 +55,50 @@ the same two things: save on failure. Users asked for the same here ([ComputerControl#259](https://github.com/PokemonAutomation/ComputerControl/issues/259)); Mysticial's reply there is that an AutoStory takes far more effort than it - looks (SV took over a year). Shared infrastructure and decomp-planned paths - are how this plan tries to keep that cost down. - -**What we think should happen.** - -1. Move SV's run flow into a small shared module, as pure moves in five - small PRs with unit tests, keeping SV's behaviour exactly. Each game keeps - its own options, save/reset and checkpoints. -2. Build a shared, console-free tile-path executor (path as data, resume - after an interrupt, pluggable interrupt policy, landmark alignment), with - per-game timings and detectors. FRLG is the first user; BDSP can adopt - it. We offer to do both and to help BDSP move onto them. -3. Build a FireRed AutoStory to the Champion on top of them: roughly 90–110 - checkpoints, ~10–12k lines, piloted on Pallet Town → Pewter City first. - It must work solo from a new game: no trades and no transferring a - levelled Pokémon in. The team, catches and purchases are derived from - what the route needs (§7.6); shortcuts such as the Nugget Bridge money - loop are options. - -**What reviewers should expect:** about 30 PRs, most 200–600 lines, in -the order of §7.7. The first eight (shared run flow and tile movement) stand -on their own and help SV and BDSP whether or not the FireRed program goes -ahead. - -The rest of the doc gives the evidence (§2, §4), the proposed interfaces and -PR sequence (§3, §5), feedback for the BDSP draft (§6) and the FireRed plan -(§7). + looks (SV took over a year). + +**What that year was, honestly.** Most of it was hardware hours per +checkpoint: writing a checkpoint, then tuning it and rerunning it on a +console until it is reliable. Shared infrastructure does not shorten that. +Decomp-planned paths might reduce the tuning, but that is unproven. What we +can do is measure the cost per checkpoint early and stop if it is too high +(the gate in §7.7). + +**Order (revised 2026-10-25): own something before proposing changes to +anyone else's code.** + +1. **Phase A, the pilot: FRLG files only, about 10 PRs.** Build a FireRed + AutoStory from a new game to Brock, with a *third* copy of the run flow + in FRLG, as BDSP copied SV's. We accept the duplication for now. The + tile-path executor (T1) lives in the FRLG module at first, and the Elite + Four farmer moves onto it (T2). Users can run something at PR 5 (new game + → rival battle); the pilot is complete at PR 10 (Boulder Badge). +2. **Gate F3**, a public commitment in the proposal: every pilot checkpoint + passes 3 times in a row from its save, at an average of at most 3 Switch + hours per checkpoint, counting development and validation. Otherwise we + stop at Brock. +3. **Phase B:** the remaining segments to the Champion, one PR per segment. +4. **Phase C, any time and independent of A and B:** the BDSP bugs found + while reading #1717 become standalone review comments with no request + attached. They are drafted in the sibling file and not posted; the user + decides. +5. **Phase D, only after the Brock pilot runs and people use it:** "I wrote + the third copy; I'll migrate SV and offer it to BDSP." The shared run + flow (R0–R5) and the shared tile path move out of FRLG as pure moves with + tests. The PRs are the same as before; they come later and are framed + differently. + +Requirements unchanged (§9): FireRed, to the Champion, solo with no trades, +shortcuts as options, the team worked out backwards from what the route +needs. + +**What reviewers should expect:** about 10 FRLG-only PRs to the pilot, most +150–500 lines, in the order of §7.7, then a go/no-go decision with measured +numbers. The likely reviewers are the FRLG authors in §8. + +The rest of the doc gives the evidence (§2, §4), the interfaces (§3, §5), +the BDSP findings (§6), the FireRed plan and PR sequence (§7), and who +wrote the FRLG code we build on (§8). ## 1. Design from first principles @@ -126,7 +147,7 @@ unused). 4 is where BDSP split into two styles. | Error report | at attempt 10, telemetry `SVT.cpp:1457-1469` | none | SV only | | Post-success check | `enter_menu_from_overworld` (retry if not overworld) `SVT.cpp:1453` | none | SV only | | Tutorial loop | separate copy `SVT.cpp:1491-1547` | — | SV only | -| `save=false` path | — | `reload_backup_save` is an empty TODO `BT.cpp:188-197`, no callers | dead | +| `save=false` path | — | the retry loop calls `reload_backup_save` (`BT.cpp:245-246`), an empty TODO (`:188-197`), and reruns the action without resetting | bug | | Dev harness | `test_checkpoints` / `test_code` `SVA.cpp:901-1080,1196-1291` | none | SV only | | End of program | `GO_HOME_WHEN_DONE`, start-up checks | neither; language hard-coded English `BA.cpp:701` | BDSP missing | @@ -141,7 +162,7 @@ Coupling worth knowing before moving anything: - Segments construct their checkpoints inline (`AutoStory_Checkpoint_04().run_checkpoint(...)`), so checkpoint order is written twice: in each segment and in the registry. In BDSP this already - went wrong twice (§5.2). + went wrong twice (§6). - Code-health limits (fork #41: functions ≤50 lines, nesting ≤4, ≤7 params) are exceeded by: SV constructor ~397 lines, `test_checkpoints` 180 lines / 8 params / nesting 5, `test_code` 96, `on_config_value_changed` 87, @@ -150,7 +171,13 @@ Coupling worth knowing before moving anything: 14-move list), `program` 74, `save_game` 71, retry loop 51 / 8 params. Pure moves keep these as legacy; anything new should not add more. -## 3. Run flow: shared core and prework +## 3. Run flow: shared core (phase D) + +In phase A, FRLG gets its own copy of the run flow inside the FRLG module +(S0). That copy is written in the shape below from the start: hooks, a +policy struct, and fake-hook unit tests. Phase D's first PR (R0) can then +move it to the shared module as a pure move. SV and BDSP are untouched +until phase D. ### 3.1 What is shared, what is per game @@ -219,10 +246,13 @@ files change. - `after_success` throwing (the overworld check) counts as a failed attempt. - Each loop's own fatal message text. -### 3.3 Prework PR sequence (SV only, no behaviour change) +### 3.3 Phase D PR sequence (after the pilot is in use; SV only, no behaviour change) + +P1–P5 here are R1–R5 in §7.7. | # | PR | What moves | Risk | Review | |---|---|---|---|---| +| R0 | FRLG's run flow → `Pokemon/AutoStory` | S0's copy moved unchanged | low | `--color-moved` | | P1 | Shared select databases | 6 `make_*_database` → `make_index_database`; same slugs/labels | low | `--color-moved` | | P2 | Range math | `get_*_index` arithmetic → pure `to_global_range` + tests | low | tests | | P3 | Shared stats | `AutoStoryStats` → `Pokemon/AutoStory`; alias in `SVT.h` | low (keys) | pure move | @@ -306,8 +336,12 @@ avoid animated tiles; Flash-dark caves are the exception. ### 5.1 Pieces -Shared, console-free, in `SerialPrograms/Source/Pokemon/Navigation/` -(precedent: `Pokemon/Pokemon_AdvRng.h` is shared by FRLG and RSE): +Console-free. In phase A it lives in the FRLG module +(`FRLG/Navigation/`, namespace `PokemonFRLG`), so the pilot touches only +FRLG files. In phase D, if BDSP wants it, it moves to +`SerialPrograms/Source/Pokemon/Navigation/` (precedent: +`Pokemon/Pokemon_AdvRng.h` is shared by FRLG and RSE). The sketch below +shows the final shared form. ```cpp namespace PokemonAutomation{ @@ -432,58 +466,60 @@ CommandLineTests, one PR per detector (Mysticial's request on #1717). - Battle intro and door fade both look like a black screen: check for a battle menu after the fade (BDSP `walk_until_doorway` does; FRLG must). -## 6. Feedback for the BDSP team (draft; the user decides whether to post) +## 6. BDSP #1717: findings (phase C) + +**Revised 2026-10-25.** We do not own anything yet, so we don't ask the BDSP +team to restructure their WIP, adopt a shared core, or reorder their PRs. +The defects below become standalone review comments with no request +attached, drafted in +[AutoStory-1717-review-drafts.md](AutoStory-1717-review-drafts.md) and +re-checked at `65094d4cd`. The user decides whether and when to post them. +Design opinions stay in this internal doc until phase D, and come up +earlier only if someone asks. They asked for feedback on "the SV-derived architecture, checkpoint and recovery contracts, BDSP helper/detector boundaries, resource distribution, and the order in which to extract focused PRs". -**Architecture.** Following SV is right, and their `section_database` is -cleaner than SV's six copies. Rather than a third copy of the framework -(SwSh #1207 will need one too), propose the shared core in §3 and adopt it -when it lands; their loop becomes a hooks object with policy `{20, ..., never -report}` and their stats/base classes/database code are deleted. +**Defects (drafted as comments 1–5):** -**Checkpoint and recovery contracts.** -- `reload_backup_save` is an empty TODO but the `save=false` path calls it - and then re-runs the action without any reset (`BT.cpp:188-197`); remove - the path or implement it. -- No start > end check, no recoverable-error report, no `GO_HOME_WHEN_DONE`, - language fixed to English (`BA.cpp:701`): adopt SV's behaviour here. -- Diagnostic options marked "remove before production" (`BA.h:42-46`) and - `CheckpointRetryScope`: gate behind developer mode or drop. +- `reload_backup_save` is an empty TODO (`BT.cpp:188-197`), but the retry + loop calls it when `save` is false (`:245-246`) and then reruns the action + without any reset. - Checkpoint order is written twice (segment + registry) and has drifted: - - Segment 08's `run_segment` stops at 0821 (`Segment_08.cpp:~116`), so - 0822–0826 (Sunyshore and the 8th gym) never run in segment mode. - - 0717 is missing from the advanced list (`BA.cpp:155-156` goes 0716 → + - Segment 08's `run_segment` stops at 0821 (`Segment_08.cpp:116`), while + the registry goes on to 0826 (`BA.cpp:181-185`), so 0822–0826 (Sunyshore + and the 8th gym) never run in segment mode. + - 0717 is missing from the checkpoint list (`BA.cpp:155-156` goes 0716 → 0718). - - Deriving segments from registry ranges removes this class of bug. -- Badge texts swapped: Segment 04 says "Third badge (Hearthome)", Segment 05 - "Fifth badge (Veilstone)"; Veilstone is the 3rd, Hearthome the 5th. - -**Helper/detector boundaries.** -- Movement: replace per-segment `move_back_after_unexpected_battle` chains - with path data (`trainer_stops_at`, §5.2). Includes the dead skier push - above. -- The landmark loop (segments 00–03) deserves to become the shared alignment - routine (§5.1); later segments would gain from it most. -- `handle_battle` is copied into each of segments 04–09, keyed by trainer-id - strings, while `Battle.cpp`'s `handle_expert_battle` and - `handle_battle_with_outside_help` have no callers; pick one. -- `Navigation.cpp` stubs and `Dialog.cpp` (already agreed to delete). -- Changes to shared `DialogDetector` boxes affect every BDSP program; those - need screenshot tests before anything else depends on them. - -**Resources.** Templates live only in their Packages fork; per-hour variants -multiply them. Document which landmarks need lighting sets and keep the -lighting sweep program as a dev tool. - -**Extraction order.** Agree with Mysticial: detectors first, one PR each -with CommandLineTests images. Then navigation primitives (shared tile path -if it exists by then), then the battle handler, then segments 00–01. - -Tone: the PR is explicitly WIP and asks for early feedback; keep it to a few -concrete items plus the shared-core offer. +- `Segment_07.cpp:214` matches `"route_215_skier_edward"`, but the only + caller (`:773`) passes `"route_216_skier_edward"`, so the 8.1 s push never + runs. +- Badge texts swapped: Segment 04 (`:31`) says "Third Gym Badge acquired + (Hearthome City)", Segment 05 (`:30`) "Fifth Gym Badge acquired (Veilstone + City)"; Veilstone is the 3rd, Hearthome the 5th. + +**Question (draft 6, optional):** `handle_battle` is copied into each of +segments 04–09, keyed by trainer-id strings, while `Battle.cpp`'s +`handle_expert_battle` (`:698`) and `handle_battle_with_outside_help` +(`:208`) have no callers. + +**Held back (design opinions, for phase D or if asked):** + +- A shared run-flow core (§3) instead of per-game copies; their + `section_database` is cleaner than SV's six copies and would be the model. +- No start > end check, no recoverable-error report, no `GO_HOME_WHEN_DONE`, + language fixed to English (`BA.cpp:701`), diagnostic options marked + "remove before production" (`BA.h:42-46`). These are normal for a WIP + and not worth a comment. +- Movement: path data with `trainer_stops_at` (§5.2) instead of + per-segment `move_back_after_unexpected_battle` chains; the landmark loop + (segments 00–03) as a shared alignment routine (§5.1). +- Changes to shared `DialogDetector` boxes affect every BDSP program and + need screenshot tests; Mysticial has already asked for detectors first, + one PR each. +- Templates live only in their Packages fork, and per-hour lighting variants + multiply them. ## 7. FRLG AutoStory plan @@ -543,11 +579,13 @@ Already on `main` (`FRLG/`): ### 7.2 Missing pieces (infrastructure, ~3–5k lines) -1. Shared run flow (§3) adopted in FRLG: FRLG hooks (save via start menu, - reset via `soft_reset` + load menu), options, registries. -2. Shared tile path (§5) with the FRLG adapter, moving `walk_path` and the - constants out of `EliteFourFarmer.cpp`; add run (8 frames/tile), bike (6), - surf (8) per decomp; ledge steps. +1. FRLG's own copy of the run flow, in the §3 shape (hooks, policy, + fake-hook tests): FRLG hooks (save via start menu, reset via + `soft_reset` + load menu), options, registries. It is shared only in + phase D. +2. Tile path (§5) in the FRLG module with the FRLG adapter, moving + `walk_path` and the constants out of `EliteFourFarmer.cpp`; add run + (8 frames/tile), bike (6), surf (8) per decomp; ledge steps. 3. Overworld detector (overworld vs dialog vs battle vs menu without opening the start menu) and facing detection (player sprite in the centre tile). 4. Walk interrupts: trainer "!" or approach, wild battle (black screen + @@ -656,75 +694,133 @@ Consequences: ### 7.7 PR plan for reviewers -Reviewers should know up front what is coming. The whole plan is about 30 -PRs. Most are 200–600 changed lines, each does one thing, and each says what +Reviewers should know up front what is coming. Phase A is about 10 PRs, +touches only FRLG files, and produces something users can run at PR 5. +Most PRs are 150–500 changed lines, each does one thing, and each says what to read first. Upstream allows two open PRs from us at a time, so they arrive in order; the rest wait as drafts on the fork. -| # | PR | Depends on | Kind | Size (lines) | What the reviewer reads | +**Phase A: pilot, new game → Brock (FRLG files only)** + +| # | ID | PR | Depends on | Kind | Size (lines) | What the reviewer reads | +|---|---|---|---|---|---|---| +| 1 | T1 | Tile-path executor + interrupt policy + tests, in the FRLG module | — | new | ~500 (half tests) | result types, resume bookkeeping | +| 2 | T2 | FRLG adapter; Elite Four farmer uses it | T1 | move + new | ~300 | walker moved out of `EliteFourFarmer.cpp`; farmer unchanged on hardware | +| 3 | D4 | New-game screens and naming keyboard | — | new | ~200 + images | detector + screenshot tests | +| 4 | S0 | Program shell: options, FRLG run-flow copy (hooks + tests), registries | — | new | ~500 (a third of it tests) | retry behaviour against fake hooks; options | +| 5 | S1 | Segment 00: new game → starter → lab rival | S0, D4, T2 | new + path data | ~500 | **first runnable**; checkpoint list, paths as data; hardware runs | +| 6 | D1 | Overworld detector | — | new | ~150 + images | detector + screenshot tests | +| 7 | D3 | Trainer spotting / item pickup watchers | — | new | ~150 + images | same | +| 8 | B1 | Walk interrupts for FRLG (battle, dialog, item) | T2, D1, D3 | new | ~300 | resolve() paths; fakes | +| 9 | B2 | Trainer battle handler + tests | — | new | ~500 (half tests) | decisions with scripted fakes | +| 10 | S2 | Segment 01: parcel → Pokédex → Viridian Forest → Brock | S1, B1, B2 | new + path data | ~700 | **pilot complete**; hardware runs of each checkpoint | + +The pilot does not need the facing detector (D2): path data knows the +facing after each step, as the E4 farmer does today. The requirements +planner (§7.6) is not needed either, because the pilot route has no HM, +shop or catch requirements. S1 reuses StarterRng's `walk_to_rival_battle` / +`auto_battle_rival` and SidHelper's `finish_intro_animations` where they +fit. + +**Phase B: to the Champion (only if gate F3 passes)** + +| ID | PR | Depends on | Kind | Size (lines) | +|---|---|---|---|---| +| D2 | Facing detector | D1 | new | ~150 + images | +| T3 | Landmark alignment loop + tests (FRLG; whole-tile output) | T1 | new | ~300 | +| B3 | Field moves: teach HM, Cut/Surf/Strength, Bike | D1 | new | ~300 | +| B4 | Mart purchases | — | new | ~250 | +| B5 | Catch routine | D1 | new | ~300 | +| S0b | Requirements plan + start-up check (§7.6) + tests | S0 | new | ~400 | +| S3–S11 | One PR per segment (02 … 10) | S2, B3–B5, S0b | new + path data | ~500–900 each | +| opt | Nugget Bridge top-up, Retro Mail duplication | S0b | new | small, one each | + +**Phase C: BDSP findings (independent, any time).** Not PRs: the review +comment drafts in +[AutoStory-1717-review-drafts.md](AutoStory-1717-review-drafts.md), for the +user to post or not. + +**Phase D: shared code (after the pilot runs and people use it).** Framing: +"I wrote the third copy; I'll migrate SV and offer it to BDSP." + +| ID | PR | Depends on | Kind | Size (lines) | What the reviewer reads | |---|---|---|---|---|---| -| **Run flow (SV, no behaviour change)** | | | | | | -| R1 | Shared start/end select databases | — | move | ~150 | `--color-moved`; same slugs and labels | +| R0 | FRLG run flow → `Pokemon/AutoStory` | S0 | move | ~300 | `--color-moved`; FRLG unchanged | +| R1 | Shared start/end select databases (SV) | R0 | move | ~150 | `--color-moved`; same slugs and labels | | R2 | Story range maths + tests | R1 | move + tests | ~200 | the pure function and its table test | -| R3 | Shared `AutoStoryStats` | — | move | ~80 | stat keys unchanged | -| R4 | Retry core behind hooks + tests | R3 | move + new | ~400 (half tests) | §3.2 list of kept behaviours; SV adapters | +| R3 | SV `AutoStoryStats` onto the shared one | R0 | move | ~80 | stat keys unchanged | +| R4 | SV retry loops become adapters over the shared core | R0, R3 | move + new | ~400 (half tests) | §3.2 list of kept behaviours | | R5 | Dev harness out of the SV program class | — | move | ~300, mostly a deleted dead block | `--color-moved` | -| **Tile movement (shared)** | | | | | | -| T1 | Tile-path executor + interrupt policy + tests | — | new | ~500 (half tests) | result types, resume bookkeeping | -| T2 | FRLG adapter; Elite Four farmer uses it | T1 | move + new | ~300 | walker moved out of `EliteFourFarmer.cpp`; farmer unchanged on hardware | -| T3 | Landmark alignment loop + tests | T1 | new | ~300 | control law against scripted fixes | -| **FRLG detectors (one per PR, images in CommandLineTests)** | | | | | | -| D1 | Overworld detector | — | new | ~150 + images | detector + screenshot tests | -| D2 | Facing detector | D1 | new | ~150 + images | same | -| D3 | Trainer spotting / item pickup watchers | — | new | ~150 + images | same | -| D4 | New-game screens and naming keyboard | — | new | ~200 + images | same | -| **FRLG building blocks** | | | | | | -| B1 | Walk interrupts for FRLG (battle, dialog, item) | T2, D1, D3 | new | ~300 | resolve() paths; fakes | -| B2 | Trainer battle handler + tests | — | new | ~500 (half tests) | decisions with scripted fakes | -| B3 | Field moves: teach HM, Cut/Surf/Strength, Bike | D1 | new | ~300 | menus; hardware run | -| B4 | Mart purchases | — | new | ~250 | buy list; hardware run | -| **FRLG AutoStory** | | | | | | -| S0 | Program shell: options, hooks, registries, requirements check | R1–R4 | new | ~500 | options; start-up checks; tests of the requirements plan | -| S1–S11 | One PR per segment (00 … 10) | S0, B1–B4 | new + path data | ~500–900 each | checkpoint list, start/end states, the paths as data; hardware runs of each checkpoint | +| T4 | Tile path → `Pokemon/Navigation`, if BDSP wants it | T1 | move | ~300 | `--color-moved` | + +R1–R5 touch SV AutoStory, which is someone else's merged program: pure +moves first, behaviour changes separately (§3.3). The SV AutoStory author +and Mysticial are the reviewers for these (§8). The BDSP team gets an offer, +not a request. Notes: -- R1–R5 and T1–T3 are useful on their own (SV and BDSP gain from them), so - they can be reviewed before anyone decides on the FRLG program. - Segment PRs are mostly path data and short checkpoint functions. Paths are planned offline from the decomp; the planner stays outside the repo unless reviewers want it under `devtools/`. - Optional features (Nugget Bridge top-up, Retro Mail duplication) come as - separate small PRs after S0, so they never hold up a segment. + separate small PRs after S0b, so they never hold up a segment. -Milestones, for our own tracking: +**Milestones** -| M | PRs | Validation | -|---|---|---| -| F0 | R1–R5 | SV AutoStory smoke run of a few checkpoints | -| F1 | T1–T3 | unit tests; Elite Four farmer unchanged on hardware | -| F2 | D1–D4, B1–B4 | screenshot tests, fakes, short hardware runs | -| F3 | S0, S1–S2 (pilot: new game → Boulder Badge) | each checkpoint ×3 from its save | -| F4–F6 | S3–S11 | each checkpoint from its save, then full runs | - -Decide whether to go past F3 using the measured lines and Switch hours per -checkpoint. - -## 8. Process - -- All new work as fork drafts on `dayfine/Arduino-Source`; per AGENTS.md, - Codex owns new feature branches until the first fork PR and does the live - validation; Claude prepares PRs. Nothing goes upstream without the user. -- F0 touches SV AutoStory, which is someone else's merged program: pure moves - first, behaviour changes separately, `--color-moved` reviewable. -- Code-health limits apply to every new file (functions ≤50 lines); the - segment style should be short checkpoint functions calling path data and - helpers, which also keeps reviews small. +| M | PRs (count to here) | Users can run | Validation | +|---|---|---|---| +| F1 | T1, T2 (2) | the E4 farmer, on the new walker | unit tests; E4 farmer unchanged on hardware | +| F2 | D4, S0, S1 (5) | **new game → rival battle** | each checkpoint ×3 from its save | +| F3 (gate) | D1, D3, B1, B2, S2 (10) | **new game → Boulder Badge** | each checkpoint ×3 from its save; Switch hours logged per checkpoint | +| F4–F6 | phase B | further, one segment at a time | each checkpoint from its save, then full runs | +| F7 | phase D | SV unchanged; FRLG on the shared core | SV AutoStory smoke run of a few checkpoints | + +**Gate F3 (public, in the proposal).** Continue past Brock only if every +pilot checkpoint (about 12) succeeds 3 times in a row from its own save, +**and** the measured cost is at most **3 Switch hours per checkpoint on +average**, counting both development and validation. If either target is +missed, stop at Brock: the pilot stays a working program, and we post the +measured cost. At 3 hours, the full game (~100 checkpoints) is about 300 +hardware hours. Also record lines per checkpoint against the ~100–120 that +the 10–12k-line estimate implies. (The 3-hour budget was added in this +revision; the earlier gate named only the ×3 runs. The user should confirm +it before the proposal is posted.) + +## 8. Who wrote the FRLG code we build on + +From `git log` / `git blame` on `upstream/main` at `f9cf36f7a` +(2026-10-25). Paths are under `FRLG/`. They are the likely reviewers, and +one of them may sponsor the work. + +| Author | What | Blame share | Last activity | +|---|---|---|---| +| thewhitewolfking | `Programs/Farming/PokemonFRLG_EliteFourFarmer.cpp/.h`, the tile walker T2 moves (#1536, #1544) | all 1,004 lines of the .cpp | 2026-10-08 (#1544); no other commits, no open PRs | +| theAstroGoth | `Programs/RngManipulation/PokemonFRLG_StarterRng.cpp` (the story fragments S1 reuses), most of `PokemonFRLG_Navigation.cpp` | 831 of 862 StarterRng lines; 686 Navigation lines; 88 FRLG commits, the most | 2026-10-21 (#1662); open BDSP starter RNG #1366 | +| Dalton (Dalton-V) | `Programs/Farming/PokemonFRLG_NuggetBridgeFarmer.cpp` (money top-up option), selection arrows and start menu (#1129), StarterRng input trim (#1679) | 213 of 235 NuggetBridge lines; 354 Navigation lines; 27 FRLG commits | 2026-10-24 (#1720, CONTRIBUTING testing additions); open #1614 FRLG box sorter | +| kichithewolf | started `PokemonFRLG_Navigation.cpp` (2025-01-29), party slot detection | 234 Navigation lines; 23 FRLG commits | 2026-09-20 (#1485) | +| Alexander Yee (Mysticial) | maintainer; moves and cleanups | 64 FRLG commits | 2026-10-25 (repo); FRLG 2026-10-15 | +| us (dayfine) | `WildBattleExitActions` seam and tests (#1663), evolution exit fix (#1684), both merged | 229 lines of `PokemonFRLG_Tests.cpp` | 2026-10-23 | + +Reading: theAstroGoth is the most likely FRLG reviewer and sponsor (largest +and most recent FRLG author, and owns the code S1 reuses). Ask +thewhitewolfking to look at T2, since it moves their walker; they have been +quiet since 2026-10-08. Dalton is active and owns the Nugget Bridge code +behind the money option. For phase D, the SV AutoStory author is jw098 (117 +commits under SV AutoStory; last SV AutoStory commit 2026-08-30, last repo +commit 2026-10-09). + +Process notes that apply to the PRs: code-health limits apply to every new +file (functions ≤50 lines); the segment style is short checkpoint functions +calling path data and helpers, which also keeps reviews small. Who does what +among the agents is recorded outside this doc. ## 9. Decisions (user, 2026-10-25) -1. **Shared pieces:** propose them to the BDSP team and offer to work on them - (F0, F1), not wait for them to ask. +1. **Shared pieces:** offer to work on them rather than waiting to be + asked. *Revised 2026-10-25 after review:* the offer comes in phase D, + after the FRLG pilot runs and people use it. Until then, BDSP gets only + the standalone bug comments (phase C). 2. **Scope:** main story to the Champion. No Sevii or post-game. 3. **Shortcuts** (Nugget Bridge money, Retro Mail duplication): available as options. They need planning, e.g. catching the right Pokémon at the right From 8a8b50438853bb16a18bb90d9d6b9208802102eb Mon Sep 17 00:00:00 2001 From: dayfine Date: Tue, 27 Oct 2026 23:37:18 -0700 Subject: [PATCH 07/24] Design doc: reusable pieces in their final homes, no copy-then-move The plan wrote FRLG's run flow and tile path inside the FRLG module and moved them out in phase D (R0, T4): move-only PRs of our own code. Adding new files to a shared module changes no one else's code, so they now start in Pokemon/AutoStory and Pokemon/Navigation. New section 0.1 lists the game-neutral pieces from SV, BDSP #1717, SwSh #1207, BBQ and the BDSP lab work (screen machine, step trace, failure policy, list selection, system keyboard, Lab Console, run flow, tile path, decision tests) with their homes; D4 builds the FRLG intro on the screen machine. The proposal says the same. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Proposal.md | 21 +++-- docs/design/AutoStory.md | 133 +++++++++++++++++++----------- 2 files changed, 93 insertions(+), 61 deletions(-) diff --git a/docs/design/AutoStory-Proposal.md b/docs/design/AutoStory-Proposal.md index 6a98df6baf..d823ad849e 100644 --- a/docs/design/AutoStory-Proposal.md +++ b/docs/design/AutoStory-Proposal.md @@ -16,17 +16,17 @@ 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 is built only in FRLG files and uses -its own copy of the SV-style run flow (checkpoints, retries from the last -save, start/end selection, stats), as BDSP's draft does. I accept that -duplication for now; merging the copies is only worth proposing once one of -them is used. +checkpoints), solo with no trades. It changes no existing program: 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, FRLG-only. +1. Tile-path executor with unit tests, in a new `Pokemon/Navigation/`. 2. Elite Four farmer moved onto it, with no behaviour change. -3. New-game screen and naming-keyboard detectors. +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. @@ -67,7 +67,6 @@ I'll post the measured numbers before continuing. ## Later, only if the pilot is used - The remaining segments to the Champion, one PR per segment. -- Having written a third copy of the run flow, I'd offer to move it into a - shared module, migrate SV AutoStory onto it as pure moves with unit tests, - and offer the same to BDSP. None of this is a precondition for the FRLG - work. +- With FRLG running on the shared run flow, I'd offer to migrate SV + AutoStory onto it (pure moves with unit tests first) and offer the same to + BDSP. None of this is a precondition for the FRLG work. diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 3ecf5f0078..cf20e4b071 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -65,14 +65,18 @@ can do is measure the cost per checkpoint early and stop if it is too high (the gate in §7.7). **Order (revised 2026-10-25): own something before proposing changes to -anyone else's code.** - -1. **Phase A, the pilot: FRLG files only, about 10 PRs.** Build a FireRed - AutoStory from a new game to Brock, with a *third* copy of the run flow - in FRLG, as BDSP copied SV's. We accept the duplication for now. The - tile-path executor (T1) lives in the FRLG module at first, and the Elite - Four farmer moves onto it (T2). Users can run something at PR 5 (new game - → rival battle); the pilot is complete at PR 10 (Boulder Badge). +anyone else's code.** Revised again 2026-10-27: new code goes in its final +home from its first PR (§0.1). Adding new files to a shared module changes no +one else's code, so "FRLG files only" bought nothing, and "write it in FRLG, +move it out later" was a plan for move-only PRs of our own code. + +1. **Phase A, the pilot: about 10 PRs, touching only new files and FRLG.** + Build a FireRed AutoStory from a new game to Brock. The run flow (S0) + and the tile-path executor (T1) are written in `Pokemon/AutoStory/` and + `Pokemon/Navigation/` from the start, used only by FRLG; SV and BDSP are + not touched. The Elite Four farmer moves onto the tile path (T2). Users + can run something at PR 5 (new game → rival battle); the pilot is + complete at PR 10 (Boulder Badge). 2. **Gate F3**, a public commitment in the proposal: every pilot checkpoint passes 3 times in a row from its save, at an average of at most 3 Switch hours per checkpoint, counting development and validation. Otherwise we @@ -82,23 +86,53 @@ anyone else's code.** while reading #1717 become standalone review comments with no request attached. They are drafted in the sibling file and not posted; the user decides. -5. **Phase D, only after the Brock pilot runs and people use it:** "I wrote - the third copy; I'll migrate SV and offer it to BDSP." The shared run - flow (R0–R5) and the shared tile path move out of FRLG as pure moves with - tests. The PRs are the same as before; they come later and are framed - differently. +5. **Phase D, only after the Brock pilot runs and people use it:** "FRLG + runs on the shared core; I'll migrate SV and offer it to BDSP." Nothing + of ours moves: phase D changes SV's code to use the shared core (R1–R5), + and BDSP gets an offer. Requirements unchanged (§9): FireRed, to the Champion, solo with no trades, shortcuts as options, the team worked out backwards from what the route needs. -**What reviewers should expect:** about 10 FRLG-only PRs to the pilot, most -150–500 lines, in the order of §7.7, then a go/no-go decision with measured -numbers. The likely reviewers are the FRLG authors in §8. +**What reviewers should expect:** about 10 PRs to the pilot, most 150–500 +lines, in the order of §7.7, then a go/no-go decision with measured +numbers. The likely reviewers are the FRLG authors in §8, plus Mysticial +for the new shared folders. -The rest of the doc gives the evidence (§2, §4), the interfaces (§3, §5), -the BDSP findings (§6), the FireRed plan and PR sequence (§7), and who -wrote the FRLG code we build on (§8). +The rest of the doc gives the code layout (§0.1), the evidence (§2, §4), +the interfaces (§3, §5), the BDSP findings (§6), the FireRed plan and PR +sequence (§7), and who wrote the FRLG code we build on (§8). + +### 0.1 Code layout: reusable pieces and their homes (2026-10-27) + +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 +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. + +| Piece | What it is | Home | First PR | +|---|---|---|---| +| Screen machine | Closed loop over known screens: each state has a detector, one step, the screens it may lead to, a visit limit and an in-a-row limit; a screen counts once two frames agree; fails on an unexpected screen, a stall (8 steps with no change) or a timeout. Replaces mash-for-N-seconds. | `CommonTools/` (templated on the controller context, like `run_until`) | BDSP new-game intro (lab), then FRLG D4 | +| Step trace | Logs each recognized screen and action, saves a screenshot when the screen changes, and fails with the last screens attached. | `CommonTools/` | same | +| Failure policy | On a failed operation: keep the error screenshot, go HOME, close the game, rethrow, so every run ends in a known state. | `NintendoSwitch/Programs/` (next to `GameEntry`) | same | +| List selection | Read the selected row, move until the target row, confirm, verify the result. Readers are per game (BDSP name list, FRLG start menu, SV menus). | routine in `CommonTools/`; readers per game | same | +| System keyboard | Detector, cursor finder, `type_on_system_keyboard`. | `NintendoSwitch/Inference/` | lab Lab Console PR | +| Lab Console | Probe and debug runner (command files, per-game detector registry, `detect name image` offline). | `NintendoSwitch/Programs/LabConsole/` | lab Lab Console PR | +| Run flow | Checkpoint list, save, retry from save, start/end range, stats (§3). | `Pokemon/AutoStory/` | fork #43–#46 / S0 | +| Tile path | Path data, interrupt and resume, landmark alignment (§5). | `Pokemon/Navigation/` (console-free) | T1 | +| Decision tests | Game steps injected as fakes (`WildBattleExitActions`, the BBQ Tera tests). | a test file per program, from its first PR | every program PR | + +Per game, deliberately not shared: detectors and templates, timings and +speeds, battle UI, menus, new-game screens, path data. + +Rules that follow (also in the PR workflow): no "copy now, move later" +step in any plan; tests go into the program's own test file in the PR that +adds them; a seam PR sets the interface later PRs need, and behaviour PRs +change policy, not signatures. ## 1. Design from first principles @@ -171,13 +205,14 @@ Coupling worth knowing before moving anything: 14-move list), `program` 74, `save_game` 71, retry loop 51 / 8 params. Pure moves keep these as legacy; anything new should not add more. -## 3. Run flow: shared core (phase D) +## 3. Run flow: shared core -In phase A, FRLG gets its own copy of the run flow inside the FRLG module -(S0). That copy is written in the shape below from the start: hooks, a -policy struct, and fake-hook unit tests. Phase D's first PR (R0) can then -move it to the shared module as a pure move. SV and BDSP are untouched -until phase D. +The shared core is written in `Pokemon/AutoStory/` in the shape below +(hooks, a policy struct, fake-hook unit tests) by the first PR that needs +it: fork #46 already does this for SV, and S0 adds FRLG's hooks on top of +it. FRLG is its first user only if S0 lands before #46; either way the code +is written once, in its final place (§0.1). SV changes only in phase D, +BDSP not at all. ### 3.1 What is shared, what is per game @@ -252,7 +287,6 @@ P1–P5 here are R1–R5 in §7.7. | # | PR | What moves | Risk | Review | |---|---|---|---|---| -| R0 | FRLG's run flow → `Pokemon/AutoStory` | S0's copy moved unchanged | low | `--color-moved` | | P1 | Shared select databases | 6 `make_*_database` → `make_index_database`; same slugs/labels | low | `--color-moved` | | P2 | Range math | `get_*_index` arithmetic → pure `to_global_range` + tests | low | tests | | P3 | Shared stats | `AutoStoryStats` → `Pokemon/AutoStory`; alias in `SVT.h` | low (keys) | pure move | @@ -336,12 +370,10 @@ avoid animated tiles; Flash-dark caves are the exception. ### 5.1 Pieces -Console-free. In phase A it lives in the FRLG module -(`FRLG/Navigation/`, namespace `PokemonFRLG`), so the pilot touches only -FRLG files. In phase D, if BDSP wants it, it moves to -`SerialPrograms/Source/Pokemon/Navigation/` (precedent: -`Pokemon/Pokemon_AdvRng.h` is shared by FRLG and RSE). The sketch below -shows the final shared form. +Console-free. It lives in `SerialPrograms/Source/Pokemon/Navigation/` +from T1 on (precedent: `Pokemon/Pokemon_AdvRng.h` is shared by FRLG and +RSE), with FRLG's adapter in the FRLG module. BDSP can adopt it later +without anything moving. ```cpp namespace PokemonAutomation{ @@ -579,12 +611,12 @@ Already on `main` (`FRLG/`): ### 7.2 Missing pieces (infrastructure, ~3–5k lines) -1. FRLG's own copy of the run flow, in the §3 shape (hooks, policy, - fake-hook tests): FRLG hooks (save via start menu, reset via - `soft_reset` + load menu), options, registries. It is shared only in - phase D. -2. Tile path (§5) in the FRLG module with the FRLG adapter, moving - `walk_path` and the constants out of `EliteFourFarmer.cpp`; add run +1. The run flow (§3), shared core in `Pokemon/AutoStory/`; FRLG hooks + (save via start menu, reset via `soft_reset` + load menu), options, + registries in the FRLG module. +2. Tile path (§5) in `Pokemon/Navigation/`, the FRLG adapter in the FRLG + module, moving `walk_path` and the constants out of + `EliteFourFarmer.cpp` (thewhitewolfking's code, not ours); add run (8 frames/tile), bike (6), surf (8) per decomp; ledge steps. 3. Overworld detector (overworld vs dialog vs battle vs menu without opening the start menu) and facing detection (player sprite in the centre tile). @@ -595,7 +627,9 @@ Already on `main` (`FRLG/`): Pokémon after a faint, move learn (skip or replace per config), evolution (allow/cancel per config), whiteout → fail the checkpoint. 6. New game: intro, naming keyboard (preset names avoid it), options menu - (text Fast, animations Off, style Set), load menu on a fresh save. + (text Fast, animations Off, style Set), load menu on a fresh save. Built + on the screen machine and step trace (§0.1), as the BDSP intro is in the + lab: every input follows a screen read, no mash-for-N-seconds. 7. Field moves: teach HM from bag, use Cut/Surf/Strength from the party menu, Fly (exists), Bike on/off; puzzles below. 8. Shop and PC: buy list per Mart, deposit/withdraw for HM carriers. @@ -700,14 +734,14 @@ Most PRs are 150–500 changed lines, each does one thing, and each says what to read first. Upstream allows two open PRs from us at a time, so they arrive in order; the rest wait as drafts on the fork. -**Phase A: pilot, new game → Brock (FRLG files only)** +**Phase A: pilot, new game → Brock (new files and FRLG only)** | # | ID | PR | Depends on | Kind | Size (lines) | What the reviewer reads | |---|---|---|---|---|---|---| -| 1 | T1 | Tile-path executor + interrupt policy + tests, in the FRLG module | — | new | ~500 (half tests) | result types, resume bookkeeping | +| 1 | T1 | Tile-path executor + interrupt policy + tests, in `Pokemon/Navigation/` | — | new | ~500 (half tests) | result types, resume bookkeeping | | 2 | T2 | FRLG adapter; Elite Four farmer uses it | T1 | move + new | ~300 | walker moved out of `EliteFourFarmer.cpp`; farmer unchanged on hardware | -| 3 | D4 | New-game screens and naming keyboard | — | new | ~200 + images | detector + screenshot tests | -| 4 | S0 | Program shell: options, FRLG run-flow copy (hooks + tests), registries | — | new | ~500 (a third of it tests) | retry behaviour against fake hooks; options | +| 3 | D4 | Screen machine + step trace (`CommonTools/`), then FRLG new-game screens and naming on it | — | new | ~400 + images | machine tests with fake screens; detector + screenshot tests | +| 4 | S0 | Program shell: options, FRLG hooks on the shared run flow (`Pokemon/AutoStory/`, + tests), registries | — | new | ~500 (a third of it tests) | retry behaviour against fake hooks; options | | 5 | S1 | Segment 00: new game → starter → lab rival | S0, D4, T2 | new + path data | ~500 | **first runnable**; checkpoint list, paths as data; hardware runs | | 6 | D1 | Overworld detector | — | new | ~150 + images | detector + screenshot tests | | 7 | D3 | Trainer spotting / item pickup watchers | — | new | ~150 + images | same | @@ -740,18 +774,17 @@ comment drafts in [AutoStory-1717-review-drafts.md](AutoStory-1717-review-drafts.md), for the user to post or not. -**Phase D: shared code (after the pilot runs and people use it).** Framing: -"I wrote the third copy; I'll migrate SV and offer it to BDSP." +**Phase D: SV onto the shared code (after the pilot runs and people use +it).** Framing: "FRLG runs on the shared core; I'll migrate SV and offer it +to BDSP." Nothing of ours moves in phase D. | ID | PR | Depends on | Kind | Size (lines) | What the reviewer reads | |---|---|---|---|---|---| -| R0 | FRLG run flow → `Pokemon/AutoStory` | S0 | move | ~300 | `--color-moved`; FRLG unchanged | -| R1 | Shared start/end select databases (SV) | R0 | move | ~150 | `--color-moved`; same slugs and labels | +| R1 | Shared start/end select databases (SV) | — | move | ~150 | `--color-moved`; same slugs and labels | | R2 | Story range maths + tests | R1 | move + tests | ~200 | the pure function and its table test | -| R3 | SV `AutoStoryStats` onto the shared one | R0 | move | ~80 | stat keys unchanged | -| R4 | SV retry loops become adapters over the shared core | R0, R3 | move + new | ~400 (half tests) | §3.2 list of kept behaviours | +| R3 | SV `AutoStoryStats` onto the shared one | — | move | ~80 | stat keys unchanged | +| R4 | SV retry loops become adapters over the shared core | R3 | move + new | ~400 (half tests) | §3.2 list of kept behaviours | | R5 | Dev harness out of the SV program class | — | move | ~300, mostly a deleted dead block | `--color-moved` | -| T4 | Tile path → `Pokemon/Navigation`, if BDSP wants it | T1 | move | ~300 | `--color-moved` | R1–R5 touch SV AutoStory, which is someone else's merged program: pure moves first, behaviour changes separately (§3.3). The SV AutoStory author From ec2e68655e86dc833ef18c5f2d812862108d4ad1 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 06:50:27 -0700 Subject: [PATCH 08/24] Design doc: what broke on the console and the rule each break taught Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/design/AutoStory-Lessons.md diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md new file mode 100644 index 0000000000..2e37b5dc51 --- /dev/null +++ b/docs/design/AutoStory-Lessons.md @@ -0,0 +1,84 @@ +# AutoStory: what broke on a real console, and the rule each break taught + +Each entry is a failure seen on a Switch while running BDSP AutoStory (Developer-Butters' +U#1717 plus our intro work, October 2026), the pattern behind it, and the rule we now follow. +Runs are the lab builds r14 to r39 on console B. The patterns repeat, so the rules matter +more than the individual fixes. + +## 1. Timed movement drifts; stop on what the screen shows + +| Run | What happened | +|---|---| +| r27 | "Route 201 align east 2300ms" walked into the trees; the next dialogue never came. | +| r31 | Two timed grass walks ended a tile short; Tristan never saw us. | +| r33, r39 | Five timed legs to the Potion giver ended one grass row off; A faced nobody. | +| r35 | Walking 5 s into Jubilife ran past the spot where Dawn's scene starts. | + +Error from each timed leg adds up, and the same leg lands in different places from run to run. + +**Rule:** a duration is only a cap. A walk ends on a screen event: a wall (the view stops +scrolling), a dialogue, a black transition, a battle, or a landmark. Between two anchors, use +as few timed legs as possible. Walking to a wall is the cheapest anchor: hold long enough to +reach it from anywhere the previous legs could have left us, and the wall puts us in the same +place every time. (`walk_until`, `walk_to_talk` in `PokemonBDSP_AutoStory_Walk`.) + +## 2. Checks tied to one capture, one starter or one time of day + +| Run | What happened | +|---|---| +| r27 | The Potion bag search matched pixels against the author's capture. Console B is warmer (blank list 235 blue vs 253) and softer, so the Potion in row 1 failed the match. | +| r28 | The Tristan fight required "Ember" in move slot 3: Chimchar only. We had Piplup. | +| r28 | Grass-exit landmarks scored 0.41 and 0.60 after the console clock had drifted 3.5 h from the time the references were taken at. | +| r34, r36 | "Blocked" was read from screen change; in tall grass the sway keeps the screen changing. | + +**Rule:** if the screenshot plainly shows the thing a check looks for, the check is too +narrow. Fix the check, don't gather more runs. Prefer signals that survive other capture +cards and other playthroughs: OCR of names (items, moves, route banners), layout facts, +colour-normalised comparison. Never assume the starter: pick moves from what the Fight menu +shows. When an image check depends on lighting, set the clock right before it, including on +retries. + +## 3. A retry is not a fix + +Butters' checkpoint retry reloads the save and runs the same steps again. A deterministic +failure (wrong starter, wrong row, a narrow check) fails all 20 attempts. r27 spent three +attempts on the Potion check, and every r28 to r39 failure retried until we stopped it. + +**Rule:** stop at the first failure, go HOME and close the game, find the cause. Save the +screen before the retry resets it (`Screenshots/AutoStory/failures/`), and save the save prompt +at each checkpoint (`Screenshots/AutoStory/saves/`: play time, badges, party). + +## 4. Know what a stop means before reacting to it + +| Run | What happened | +|---|---| +| r30 | Walking toward Tristan read as "blocked": he had spotted us and frozen the player while he walked over. | +| r32 | Natalie spotted us, but her walk kept the screen changing, so the walk ran out its time instead. | + +**Rule:** for a trainer or a scene, the walk can end in any way short of a transition; the +dialogue decides. Walk, then wait for the dialogue with its own timeout. + +## 5. Watch what was dropped, not just the latest number + +Max Lair StrongBoss dropped a path at 14/19 because a bad stretch (2/6) pulled the overall rate +under 0.75. New paths then won 5 of 12. The "drop in win rate" came from the program throwing +away its best path. Losing a path cannot be undone, so dropping it should need stronger evidence +than keeping it. (Draft: `maxlair/path-keeping`, an option next to the old rule.) + +## 6. Our own process + +- Look at the screen, then the code, before rerunning. Every run since r28 that failed in a new + way was explained by one screenshot. +- Put new code in its final module first; no copy-then-move PRs of our own code. +- Keep line endings as they are (CRLF files stay CRLF); compare `git diff --stat` with + `--ignore-cr-at-eol`. +- When a program is stuck or failing, stop it and close the game at once; don't let retries run. + +## 7. Next: a map instead of recorded legs + +BDSP keeps DP's overworld layouts: Bulbapedia's DP map of Route 202 (37 x 26 tiles of 16 px) +matches our console B screenshots (the 202 sign by the L-shaped path, the eastern tree wall, the +Potion giver at the edge of the grass by the trees). The DP maps can be turned into a walkability +grid per route: walls, grass, ledges, doors, NPCs and trainer sightlines. +Planned legs then end at known walls; the route banner (OCR) and the walls we hit tell us where +we are. This replaces the recorded stick movements, and FRLG can use the same tool. From 5e4722b97639d2be006a2cc7bf59b98bd9e5e1a7 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 06:52:13 -0700 Subject: [PATCH 09/24] Design doc lessons: drop the Max Lair entry, it is not AutoStory Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 2e37b5dc51..b7c380ebd9 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -58,14 +58,7 @@ at each checkpoint (`Screenshots/AutoStory/saves/`: play time, badges, party). **Rule:** for a trainer or a scene, the walk can end in any way short of a transition; the dialogue decides. Walk, then wait for the dialogue with its own timeout. -## 5. Watch what was dropped, not just the latest number - -Max Lair StrongBoss dropped a path at 14/19 because a bad stretch (2/6) pulled the overall rate -under 0.75. New paths then won 5 of 12. The "drop in win rate" came from the program throwing -away its best path. Losing a path cannot be undone, so dropping it should need stronger evidence -than keeping it. (Draft: `maxlair/path-keeping`, an option next to the old rule.) - -## 6. Our own process +## 5. Our own process - Look at the screen, then the code, before rerunning. Every run since r28 that failed in a new way was explained by one screenshot. @@ -74,7 +67,7 @@ than keeping it. (Draft: `maxlair/path-keeping`, an option next to the old rule. `--ignore-cr-at-eol`. - When a program is stuck or failing, stop it and close the game at once; don't let retries run. -## 7. Next: a map instead of recorded legs +## 6. Next: a map instead of recorded legs BDSP keeps DP's overworld layouts: Bulbapedia's DP map of Route 202 (37 x 26 tiles of 16 px) matches our console B screenshots (the 202 sign by the L-shaped path, the eastern tree wall, the From 41ddeb91167551bf405ddf2ffd0c2717a69410d2 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 07:26:56 -0700 Subject: [PATCH 10/24] AutoStory design notes: screen machine, walking, map, planner, executor Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Design.md | 186 +++++++++++++++++++++++++++++++ docs/design/AutoStory-Lessons.md | 1 + 2 files changed, 187 insertions(+) create mode 100644 docs/design/AutoStory-Design.md diff --git a/docs/design/AutoStory-Design.md b/docs/design/AutoStory-Design.md new file mode 100644 index 0000000000..6726e8ecc0 --- /dev/null +++ b/docs/design/AutoStory-Design.md @@ -0,0 +1,186 @@ +# AutoStory: design of the closed-loop pieces + +Companion to [AutoStory-Lessons.md](AutoStory-Lessons.md): that doc lists the failures, this one +describes the pieces built in response and how they fit together. Status as of 2026-10-28; +each section says what is built, where, and what is still planned. + +The common idea: **never act on an assumption the screen could have checked.** Each piece +reads the screen, takes one step, and reads again. Durations are caps, not plans. + +``` + story segment (00.04 after-catch, 01 Roark, 02 Floaroma ...) + | | | + scripted screens overworld walking battles + (intro, menus) map -> plan -> execute fight / escape / heal + | | | + ScreenMachine TileGrid + MapSet battle helpers + + StepTrace planner, executor (starter-agnostic) + \_______________________|________________________/ + | + walk_until / screen reads + (dialog, black screen, battle menu, screen change) +``` + +## 1. Screen machine (built) + +`CommonTools/ScreenMachine/{ScreenMachine,StepTrace}` (branch `lab/console`, merged into +`bdsp/new-game-intro-v2`). Used by the BDSP new-game intro. + +- A routine is a list of `ScreenState`s: a matcher, one step to take on that screen, the + screens the step may lead to, and visit limits. States are tried in order; the last one + matches anything ("other"). +- Loop: wait for inputs to finish, read the screen (a state counts only when two frames + 150 ms apart agree), check, act. Stop after a terminal state acts. +- Checks between reads turn silent drift into an early, explained failure: + - the new screen must be one the previous state lists in `next`; + - no state may be seen more than `max_visits` times, or `max_in_a_row` in a row; + - eight steps in a row that change nothing on screen is a dead end; + - an overall timeout. +- `StepTrace` logs every recognised screen change with a numbered screenshot and every input, + and a failure message ends with the last few screens ("dialog -> keyboard -> dialog"). + This is what makes a failed run explainable from one folder. + +Why not a fixed script: a dropped A press or an extra dialog page shifts every later press of +a script. The machine does the right thing for whatever screen is up, so an extra page is just +one more "dialog" visit. + +Use it for menu-like stretches with a small set of recognisable screens. Overworld walking is +not a good fit (the screen is always "overworld"); it uses the walk loop below. + +## 2. Walking by the screen (built) + +`PokemonBDSP_AutoStory_Walk.{h,cpp}`. + +`walk_until(x, y, limit)` holds the stick in 400 ms chunks and returns why it stopped: + +| Stop | Read from | Meaning | +|---|---|---| +| ARRIVED | caller's matcher | a landmark is on screen | +| DIALOG | short dialog box | an NPC or a trainer stopped us | +| TRANSITION | black screen with no battle after it | door, building, new area | +| BLOCKED | screen change < 10 (RMSD at 192x108) for two chunks | walking into a wall | +| LIMIT | time | none of the above | + +Wild battles on the way (white flash, black screen then battle UI, battle menu) are escaped +and the walk resumes; they are counted, not returned. +`walk_to_talk` walks in 400 ms steps and presses A after each until a dialog opens, for NPCs +in tall grass, where the grass sway hides BLOCKED. `walk_expecting` fails with a screenshot if +the stop is not the expected one. + +The caller decides what a stop means (lesson 4): a wall leg accepts BLOCKED or LIMIT; a trainer +leg accepts anything but TRANSITION and then waits for the dialog. + +Known limits: 400 ms granularity is about 1.5 tiles; BLOCKED does not register in tall grass. +The probe (section 6) samples every ~100 ms instead. + +## 3. Map: tile grid and map set (built, being extended) + +`Pokemon/Navigation/Pokemon_TileGrid.{h,cpp}`, `Pokemon_MapSet.{h,cpp}`; data in +`PokemonBDSP/Programs/AutoStory/Data/` (Route 201, Sandgem Town, Route 202, `story_maps()`). + +**Source.** BDSP keeps DP's overworld layouts, so each grid is traced from Bulbapedia's DP map +(16 px tiles). Fetched maps and the tracing scripts stay out of the repo; only the ASCII grid is +committed, with a comment naming the source image. + +**Encoding.** One ASCII row per tile row, so a grid reads like the map and diffs like text: + +``` +# blocked (trees, walls, ground items) . walkable " tall grass (encounters) +v ledge, south only, hop over N NPC/trainer S sign +D door ? off the map / exit +``` + +Named tiles (catch spot, Potion giver's talk tile, exits) and trainers with facing and sight +range sit next to the grid. + +**Joining maps.** `MapSet` places each grid at an offset on one world grid, so a plan can cross +from Route 201 into Sandgem and on to Route 202. Overlaps are allowed only where both maps are +blocked; a conflict throws at start-up (and in the unit tests). `describe()` turns a world tile +back into "Route 201 (45,3)" for logs. + +## 4. Planner (built) + +`plan_tile_route(grid, from, to, costs)` returns straight legs (direction + tiles). It is a +cheapest-path search over (tile, direction) with costs per tile, per grass tile, per leg, and +a large extra for a leg that **stops in the open** rather than against a wall. + +Why the wall preference: a leg that ends at a wall lands on the same tile however long the stick +is held past it (lesson 1). A leg that ends in the open depends on timing; the planner uses one +only when nothing else reaches the goal, and the executor treats it as the leg to localise +after. + +Also built: `walk_to_wall` (where a straight walk stops, and whether it is held there), +`sight_tiles` / `legs_crossing_sight` (which legs walk into a trainer's view; reported, used to +expect a battle, not avoided, since we want the experience before Roark), `trace_legs` (the +tiles a plan visits, for tests and logs). + +## 5. Executor, localisation and calibration (planned) + +The piece that turns a plan into stick input: + +- **Leg to walk.** Each leg becomes one `walk_until` with an *expected* stop: + - ends at a wall: hold for `tiles x ms_per_tile` plus a margin; BLOCKED or LIMIT both mean + "at the wall"; + - ends in the open: hold `tiles x ms_per_tile`, then localise; + - enters a trainer's sight: expect DIALOG, run the trainer battle, then re-plan from where + the trainer stopped us; + - ends at a door or an exit: expect TRANSITION. +- **Localisation.** We know where we are when: + - a wall stopped us (the stop tile is known from the grid); + - the route banner appeared (OCR of "Route 201" etc. on entering a map); + - a scripted scene started (it fixes a tile). + After any surprise (wrong stop, extra battle), walk to the nearest walls on two axes to + re-anchor, then re-plan from there. Re-planning beats replaying. +- **Calibration.** `ms_per_tile` (walking, ~267 ms in DP) and the start-up delay are measured + on the console by probing known wall distances, not guessed. Running shoes would be a second + speed; we walk. + +This replaces Butters' recorded legs in 00.04 (catch -> Potion giver -> Jubilife) first, then +segments 01 and 02. + +## 6. Verifying the map on the console (next) + +Before the executor trusts a grid, check it against the game: + +1. `bdsp_probe ` Lab Console command: hold the stick, sample the screen every + ~100 ms, report the time moved before the stop. +2. From the post-catch save, probe the walls in all four directions; compare with the grid's + predicted tile counts to pin the start tile and fit `ms_per_tile`. +3. Repeat at each corner of the planned route (Route 202, Sandgem, Route 201 to the Potion + giver), with a screenshot at each stop and the route banner at map joins. +4. Output: predicted vs measured tiles per probe; grid fixes where they disagree. + +Probes run on open ground, since grass sway hides the stop. + +Doubts to settle first (from tracing the DP images): Route 202's row offset against Sandgem +(the images overlap by only 8 px, so it may be off by one); Sandgem's lab sign at row 6 or 7 +and which roof rows block; Route 201's tree line sits about 3 px off the grass grid; trainer +sight range (4 tiles is a guess). + +## 7. Battles (built: general; planned: move choice) + +- Trainer battles: `fight_trainer` uses move slot 1, whatever the starter (lesson 2: the old + code needed Chimchar's Ember in slot 3). Wild battles are escaped while walking. +- Items are found by OCR of their names (Potion), not by pixel templates. +- Planned: a move picker that OCRs the move names and chooses by power, type and the + opponent's type (Piplup gets Water Gun early, which matters for Roark); healing between + trainer battles; levelling before Roark, fighting the trainers on the way. + +## 8. Evidence and repeatability (built) + +- The clock is set (2026-01-01 00:00:50) at the start of each attempt, because some landmark + matchers depend on lighting. +- A failure saves its screenshot under `Screenshots/AutoStory/failures/` before the retry + resets the game; each save prompt is saved under `Screenshots/AutoStory/saves/` (play + time, badges). +- Runs stop at the first failure and close the game (lesson 3); retries are for real + randomness, not for deterministic failures. + +## Open questions + +- Is BDSP really 1:1 with DP everywhere along the route? Section 6 answers this for the + first three maps; buildings and towns changed most in the remake. +- Can tall grass get a stop signal (e.g. the player sprite's position instead of the whole + view)? That would remove the special case in section 2. +- How much of the planner and map set is shared with FRLG (same 16 px tiles, same ledges)? + The code lives in `Pokemon/Navigation` so it can be. diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index b7c380ebd9..99c7701a08 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -75,3 +75,4 @@ Potion giver at the edge of the grass by the trees). The DP maps can be turned i grid per route: walls, grass, ledges, doors, NPCs and trainer sightlines. Planned legs then end at known walls; the route banner (OCR) and the walls we hit tell us where we are. This replaces the recorded stick movements, and FRLG can use the same tool. +The pieces and their status are in [AutoStory-Design.md](AutoStory-Design.md). From 8e154a780e5c1b4e58181f57c5e9512a20147367 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 07:29:40 -0700 Subject: [PATCH 11/24] AutoStory design: plan on routes, trust town grids only once verified Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Design.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/design/AutoStory-Design.md b/docs/design/AutoStory-Design.md index 6726e8ecc0..610ea01f28 100644 --- a/docs/design/AutoStory-Design.md +++ b/docs/design/AutoStory-Design.md @@ -135,6 +135,13 @@ The piece that turns a plan into stick input: on the console by probing known wall distances, not guessed. Running shoes would be a second speed; we walk. +**Routes first, towns only when trusted.** Routes are open ground between tree walls, where the +DP layout carries over and walls make good anchors. Towns changed more in the remake (buildings, +signs, roofs), so a town grid is used for planning only once the console check (section 6) +confirms it. Until then a town is crossed with screen-driven legs: walk to a wall or fence, +then to the exit, ending on the route banner (OCR) or the transition. Each map carries a +confidence flag that the executor checks before planning across it. + This replaces Butters' recorded legs in 00.04 (catch -> Potion giver -> Jubilife) first, then segments 01 and 02. From 6b857bc826f3c89f217ba935e50d0468175d4455 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 15:50:13 -0700 Subject: [PATCH 12/24] AutoStory docs: what broke in Butters' 00.04 and 00.05, and what replaced it Lessons: a table of his recorded route against what console B showed (timed legs, slot-3 Ember, no healing, pixel-matched Potion, the Poke Mart lady and Barry missed by a tile), our own mistakes in this round (an optional step kept for hours, claims not checked on screen, map errors, untiled movement, a fixed OCR cut), and stepping through new ground before automating it. Design: the executor, move choice, training and Potion healing as built, and the Lab Console stepping. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Design.md | 60 +++++++++++++++++++++++------ docs/design/AutoStory-Lessons.md | 66 ++++++++++++++++++++++++++------ 2 files changed, 104 insertions(+), 22 deletions(-) diff --git a/docs/design/AutoStory-Design.md b/docs/design/AutoStory-Design.md index 610ea01f28..7dffe0b88c 100644 --- a/docs/design/AutoStory-Design.md +++ b/docs/design/AutoStory-Design.md @@ -1,8 +1,10 @@ # AutoStory: design of the closed-loop pieces Companion to [AutoStory-Lessons.md](AutoStory-Lessons.md): that doc lists the failures, this one -describes the pieces built in response and how they fit together. Status as of 2026-10-28; -each section says what is built, where, and what is still planned. +describes the pieces built in response and how they fit together. Status as of 2026-10-28 +(evening): 00.04, from the catch to Dawn in Jubilife, runs unattended on console B (r79); +00.05 is being stepped through. Each section says what is built, where, and what is still +planned. The common idea: **never act on an assumption the screen could have checked.** Each piece reads the screen, takes one step, and reads again. Durations are caps, not plans. @@ -114,7 +116,25 @@ Also built: `walk_to_wall` (where a straight walk stops, and whether it is held expect a battle, not avoided, since we want the experience before Roark), `trace_legs` (the tiles a plan visits, for tests and logs). -## 5. Executor, localisation and calibration (planned) +## 5. Executor, localisation and calibration (built for 00.04) + +Built in `Utils/PokemonBDSP_AutoStory_RouteWalk` (`walk_route`), with `plan_robust_route` in +the planner. What it does differs from the plan below in these ways: + +- **Plans for uncertainty.** The robust planner tracks every tile we may be on (at most 5 + after the start). An open leg of n tiles may end 1 + n/5 tiles off; wall legs bring the + possible tiles back together. Offline tests check each plan the segment uses. +- **Turning is its own action.** A tap facing another way only turns, so an open leg turns + first (`route_turn`). Measured speeds: 160 ms per tile across, 240 ms up or down; an open + leg holds (n - 1/2) tiles' worth. +- **Things the map lacks.** A walk that stops early waits twice for the way to clear, then + presses A (a trainer who saw us from the side, or someone standing in the way), fights + if a battle follows, marks the tile blocked, and plans again. +- **Map changes** are checked against the location banner (OCR). +- **Every leg** saves a screenshot under `Screenshots/AutoStory/route/`, and the overlay and + log show the checkpoint's steps, the current one and the next. + +The original plan: The piece that turns a plan into stick input: @@ -164,16 +184,34 @@ Doubts to settle first (from tracing the DP images): Route 202's row offset agai and which roof rows block; Route 201's tree line sits about 3 px off the grass grid; trainer sight range (4 tiles is a guess). -## 7. Battles (built: general; planned: move choice) - -- Trainer battles: `fight_trainer` uses move slot 1, whatever the starter (lesson 2: the old - code needed Chimchar's Ember in slot 3). Wild battles are escaped while walking. +## 7. Battles and healing (built) + +- **Move choice:** each turn the Fight menu's move names are read by OCR, with the threshold + set per button (the one under the cursor is light blue). The strongest known attack is + used, so Water Gun once Piplup learns it, whatever the starter. If no attack can be read, + the last move that is not a known status move is used: the starter's own-type attack. +- **Training:** before the Route 202 trainers, three wild battles in the catch grass. The + run walks up and down between the tree walls north and south of the grass, never in short + sideways steps (lesson 7). +- **Healing:** 00.04 first gets 10 Potions from the Poké Mart lady on Route 201, saves on + Route 202, then heals from the Bag. That means full after training, and a Potion after any + trainer that leaves the lead under half (`use_potion_first_pokemon(…, heal_below)`). The + Pokémon Center routine (lining up with the lit doorway, the nurse) is kept for later. - Items are found by OCR of their names (Potion), not by pixel templates. -- Planned: a move picker that OCRs the move names and chooses by power, type and the - opponent's type (Piplup gets Water Gun early, which matters for Roark); healing between - trainer battles; levelling before Roark, fighting the trainers on the way. +- Wild battles while walking are run from. +- Planned: the opponent's type in the move choice (Roark), and a lead that faints (the + "can't battle" party screen). + +## 8. Stepping through new ground (Lab Console) + +A Lab Console program on the console takes command files: walk until stopped +(`bdsp_walk x y ms`), presses, stick holds, detector reads and screenshots. New ground is +stepped through in batches of 5 to 10 commands (15 to 30 s), each ending with a screenshot, +and each stop and dialogue is written down before the automated version is written. This is +how the Poké Mart lady's tile, her dialogue timing, and Barry's position in the Trainers' +School were found, after whole-run attempts had failed on each. -## 8. Evidence and repeatability (built) +## 9. Evidence and repeatability (built) - The clock is set (2026-01-01 00:00:50) at the start of each attempt, because some landmark matchers depend on lighting. diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 99c7701a08..e8662f88dc 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -2,8 +2,9 @@ Each entry is a failure seen on a Switch while running BDSP AutoStory (Developer-Butters' U#1717 plus our intro work, October 2026), the pattern behind it, and the rule we now follow. -Runs are the lab builds r14 to r39 on console B. The patterns repeat, so the rules matter -more than the individual fixes. +Runs are the lab builds r14 to r79 on console B. The patterns repeat, so the rules matter +more than the individual fixes. Sections 6 to 8 cover r40 to r79, which took 00.04 from the +catch to Dawn in Jubilife unattended (r79). ## 1. Timed movement drifts; stop on what the screen shows @@ -67,12 +68,55 @@ dialogue decides. Walk, then wait for the dialogue with its own timeout. `--ignore-cr-at-eol`. - When a program is stuck or failing, stop it and close the game at once; don't let retries run. -## 6. Next: a map instead of recorded legs - -BDSP keeps DP's overworld layouts: Bulbapedia's DP map of Route 202 (37 x 26 tiles of 16 px) -matches our console B screenshots (the 202 sign by the L-shaped path, the eastern tree wall, the -Potion giver at the edge of the grass by the trees). The DP maps can be turned into a walkability -grid per route: walls, grass, ledges, doors, NPCs and trainer sightlines. -Planned legs then end at known walls; the route banner (OCR) and the walls we hit tell us where -we are. This replaces the recorded stick movements, and FRLG can use the same tool. -The pieces and their status are in [AutoStory-Design.md](AutoStory-Design.md). +## 6. Butters' 00.04 and 00.05, checked against the game + +What his recorded version does, what went wrong with it on console B, and what replaced it. + +| His version | What happened | Now | +|---|---|---| +| Every leg is a stick hold of a recorded length (00.05 alone is ~150 lines of them). | Drift, as in section 1. In r79 the 00.05 legs reached the Trainers' School, then "west 200 ms, A" faced an empty tile: Barry stands up and to the right, at the blackboard. | 00.04 walks map plans whose legs end at walls (design doc, sections 3 to 5). 00.05 is being stepped through (section 8 below). | +| Tristan is fought with move slot 3 (Ember). | Chimchar only; we had Piplup (r28). | The Fight menu is read by OCR and the strongest move picked. | +| No training, no healing before the Route 202 trainers. | A Lv5 Piplup with Pound fainted to Logan's Shinx (r72). | Three wild battles first (Piplup learns Water Gun), then Potions. | +| The Potion is found in the Bag by a pixel match. | Console B's colours differ; the match failed (r27). | OCR of the item name. | +| The Route 201 Poké Mart lady is reached by timed legs. | Missed her by a tile (r33, r39); so did our first planned route, which had her above the row (r77). | Walk west along her grass's top row until she stops us: she stands at (43,3), and we stop at (44,3) facing her. One A per line, 1.5 s apart. | +| Barry in the Trainers' School: "west 200 ms, A", then mash B. | Faced nobody (r79). | From the school door: one tile west, north until Barry stops us, then A per line. He gives the Town Map. | +| Leaving 00.04: walk north 5 s into Jubilife. | Ran past Dawn's spot (r35); with our route, walked into the wall beside the stairs (r78). | Walk north; when the wall stops us and no dialogue follows, step a tile west and try again. Next: put the stairs in the map. | +| Checkpoint retry reloads and repeats the same steps. | Deterministic failures retried up to 20 times. | Lab runs stop at the first failure (section 3). | + +His route did one thing right that we dropped for a while: the Poké Mart lady on Route 201 +gives **10 Potions**. With them, healing needs no trip to the Pokémon Center: heal to full +after training, and after each trainer read the HP bar in the Bag and use a Potion under half. +The run now gets the Potions first and saves on Route 202, (30,19), so later attempts skip her. + +## 7. Our own mistakes in this round + +- **An optional step kept for two hours.** We spent ~15 runs making the Route 201 detour + work before asking whether the story needs it. Rule: before automating an inherited + step, write down why the story needs it; after three different failures at one stage, + question the stage, not the symptom. +- **Claims not checked against the screen.** We concluded "the save already has Potions" + from log lines of runs that had, in fact, reached the lady; r76's Bag screenshot showed an + empty Medicine pocket. Rule: an inventory or position claim needs a screenshot of it. +- **Map errors, each found from one screenshot.** Route 202's east tree wall is at column 31 + in rows 15 to 17, not 33 (r75 lost its place by three rows); the lady is in the grass row, + not above it; Jubilife's south edge is a wall with stairs, not open ground. Rule: when a + wall leg stops somewhere unexpected, compare its screenshot with the grid before changing + any timing, and add the measured stop as a wall-hit test. +- **Movement is not tile-locked.** A short tap moves about 0.77 of a tile. A left/right + wiggle for encounters rocked across one tile edge and found no battle in three minutes + (r74). Walk wall to wall instead: the catch grass's rows sit between tree walls. +- **One fixed OCR cut for every button.** Move names under the cursor are dark text on a + light blue button, and status moves sit lower (no "Effective" line); a fixed cut and box + read "" for Water Gun and Growl (r73). Threshold halfway between each button's background + and its darkest pixel, and keep the tallest text band. +- **Not saying what we are doing.** The overlay and the log now print each checkpoint's steps, + the current one and the next, and every status report starts with the current problem. + +## 8. Step through new ground before automating it + +After hours of whole-run attempts at the lady, five minutes of stepping found her: the Lab +Console takes 5 to 10 commands at a time (walk until stopped, a few presses, a screenshot), +then waits while we look. Where the map or the scene is unknown (a new town, a building, +an NPC to talk to), step through it first, write down each stop and dialogue, and only then +write the automated version from what was seen. 00.05 (the Trainers' School, the Pokétch) +is being done this way. From 7309401f91844e877027188e03d18e92a1835e33 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 15:55:48 -0700 Subject: [PATCH 13/24] =?UTF-8?q?AutoStory=20lessons:=20link=20our=20commi?= =?UTF-8?q?t=20for=20each=20fix;=20the=20Pok=C3=A9tch=20president's=20talk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each row of the Butters comparison and each of our own mistakes now links the fork commit that fixed it, on bdsp/new-game-intro-v2. Adds what stepping through Phase 23 showed: A re-opens the president's talk, B advances it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index e8662f88dc..de32486c82 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -70,18 +70,22 @@ dialogue decides. Walk, then wait for the dialogue with its own timeout. ## 6. Butters' 00.04 and 00.05, checked against the game -What his recorded version does, what went wrong with it on console B, and what replaced it. - -| His version | What happened | Now | -|---|---|---| -| Every leg is a stick hold of a recorded length (00.05 alone is ~150 lines of them). | Drift, as in section 1. In r79 the 00.05 legs reached the Trainers' School, then "west 200 ms, A" faced an empty tile: Barry stands up and to the right, at the blackboard. | 00.04 walks map plans whose legs end at walls (design doc, sections 3 to 5). 00.05 is being stepped through (section 8 below). | -| Tristan is fought with move slot 3 (Ember). | Chimchar only; we had Piplup (r28). | The Fight menu is read by OCR and the strongest move picked. | -| No training, no healing before the Route 202 trainers. | A Lv5 Piplup with Pound fainted to Logan's Shinx (r72). | Three wild battles first (Piplup learns Water Gun), then Potions. | -| The Potion is found in the Bag by a pixel match. | Console B's colours differ; the match failed (r27). | OCR of the item name. | -| The Route 201 Poké Mart lady is reached by timed legs. | Missed her by a tile (r33, r39); so did our first planned route, which had her above the row (r77). | Walk west along her grass's top row until she stops us: she stands at (43,3), and we stop at (44,3) facing her. One A per line, 1.5 s apart. | -| Barry in the Trainers' School: "west 200 ms, A", then mash B. | Faced nobody (r79). | From the school door: one tile west, north until Barry stops us, then A per line. He gives the Town Map. | -| Leaving 00.04: walk north 5 s into Jubilife. | Ran past Dawn's spot (r35); with our route, walked into the wall beside the stairs (r78). | Walk north; when the wall stops us and no dialogue follows, step a tile west and try again. Next: put the stairs in the map. | -| Checkpoint retry reloads and repeats the same steps. | Deterministic failures retried up to 20 times. | Lab runs stop at the first failure (section 3). | +What his recorded version does, what went wrong with it on console B, and what replaced it. Our +changes are on the fork branch +[`bdsp/new-game-intro-v2`](https://github.com/dayfine/Arduino-Source/commits/bdsp/new-game-intro-v2), +on top of his segment 00 ([`bdsp/1717-seg00`](https://github.com/dayfine/Arduino-Source/compare/503a28fc6...bdsp/1717-seg00)). + +| His version | What happened | Now | Our commits | +|---|---|---|---| +| Every leg is a stick hold of a recorded length (00.05 alone is ~150 lines of them). | Drift, as in section 1. In r79 the 00.05 legs reached the Trainers' School, then "west 200 ms, A" faced an empty tile: Barry stands up and to the right, at the blackboard. | 00.04 walks map plans whose legs end at walls (design doc, sections 3 to 5). 00.05 is being stepped through (section 8 below). | [`1598fc2c7`](https://github.com/dayfine/Arduino-Source/commit/1598fc2c74e7cccf6356251bf35e21fdbcac5006), [`0a5311175`](https://github.com/dayfine/Arduino-Source/commit/0a5311175ec72feb0fcb326a38d7e2dc7b1ec673) | +| Tristan is fought with move slot 3 (Ember). | Chimchar only; we had Piplup (r28). | The Fight menu is read by OCR and the strongest move picked. | [`c16ee0262`](https://github.com/dayfine/Arduino-Source/commit/c16ee0262772a5519e489fb9ad360d263d07852c), [`97df88c43`](https://github.com/dayfine/Arduino-Source/commit/97df88c439845600a02d0114478bb66d4b158ad5) | +| No training, no healing before the Route 202 trainers. | A Lv5 Piplup with Pound fainted to Logan's Shinx (r72). | Three wild battles first (Piplup learns Water Gun), then Potions. | [`08a9fb7e0`](https://github.com/dayfine/Arduino-Source/commit/08a9fb7e01b6be5ee042708b89e32ca2149dca69), [`a95359311`](https://github.com/dayfine/Arduino-Source/commit/a953593111dba3d56b10cf995eb7e9c86455018d) | +| The Potion is found in the Bag by a pixel match. | Console B's colours differ; the match failed (r27). | OCR of the item name. | [`50c9d955d`](https://github.com/dayfine/Arduino-Source/commit/50c9d955d44d767d58d45834dc7e8d3a1b0e6c65) | +| The Route 201 Poké Mart lady is reached by timed legs. | Missed her by a tile (r33, r39); so did our first planned route, which had her above the row (r77). | Walk west along her grass's top row until she stops us: she stands at (43,3), and we stop at (44,3) facing her. One A per line, 1.5 s apart. | [`99715d5d6`](https://github.com/dayfine/Arduino-Source/commit/99715d5d6d3e2c373980b68123363a2b64ae1022), [`f823453e9`](https://github.com/dayfine/Arduino-Source/commit/f823453e9cea8966d20752c4da5f48f54e634d76) | +| Barry in the Trainers' School: "west 200 ms, A", then mash B. | Faced nobody (r79). | From the school door: one tile west, north until Barry stops us, then A per line. He gives the Town Map. | (not yet coded) | +| Leaving 00.04: walk north 5 s into Jubilife. | Ran past Dawn's spot (r35); with our route, walked into the wall beside the stairs (r78). | Walk north; when the wall stops us and no dialogue follows, step a tile west and try again. Next: put the stairs in the map. | [`3cef78b77`](https://github.com/dayfine/Arduino-Source/commit/3cef78b771877675c83356133d8917eb0de681c9) | +| The Pokétch president (Phase 23): timed legs, then wait for his dialogue. | He stands in the road and talks when we face him; pressing A to advance re-opened his talk each time it ended, so his first line came back again and again. | Talk once with A, then advance with B, which never starts a talk. | (stepped through; not yet coded) | +| Checkpoint retry reloads and repeats the same steps. | Deterministic failures retried up to 20 times. | Lab runs stop at the first failure (section 3). | lab scripts | His route did one thing right that we dropped for a while: the Poké Mart lady on Route 201 gives **10 Potions**. With them, healing needs no trip to the Pokémon Center: heal to full @@ -101,16 +105,17 @@ The run now gets the Potions first and saves on Route 202, (30,19), so later att in rows 15 to 17, not 33 (r75 lost its place by three rows); the lady is in the grass row, not above it; Jubilife's south edge is a wall with stairs, not open ground. Rule: when a wall leg stops somewhere unexpected, compare its screenshot with the grid before changing - any timing, and add the measured stop as a wall-hit test. + any timing, and add the measured stop as a wall-hit test. ([`a95359311`](https://github.com/dayfine/Arduino-Source/commit/a953593111dba3d56b10cf995eb7e9c86455018d), [`f823453e9`](https://github.com/dayfine/Arduino-Source/commit/f823453e9cea8966d20752c4da5f48f54e634d76), [`3cef78b77`](https://github.com/dayfine/Arduino-Source/commit/3cef78b771877675c83356133d8917eb0de681c9)) - **Movement is not tile-locked.** A short tap moves about 0.77 of a tile. A left/right wiggle for encounters rocked across one tile edge and found no battle in three minutes - (r74). Walk wall to wall instead: the catch grass's rows sit between tree walls. + (r74). Walk wall to wall instead: the catch grass's rows sit between tree walls. ([`68279ca9b`](https://github.com/dayfine/Arduino-Source/commit/68279ca9ba631a5012207ad664892a2bdf88e760)) - **One fixed OCR cut for every button.** Move names under the cursor are dark text on a light blue button, and status moves sit lower (no "Effective" line); a fixed cut and box read "" for Water Gun and Growl (r73). Threshold halfway between each button's background - and its darkest pixel, and keep the tallest text band. + and its darkest pixel, and keep the tallest text band. ([`97df88c43`](https://github.com/dayfine/Arduino-Source/commit/97df88c439845600a02d0114478bb66d4b158ad5)) - **Not saying what we are doing.** The overlay and the log now print each checkpoint's steps, the current one and the next, and every status report starts with the current problem. + ([`3cd874125`](https://github.com/dayfine/Arduino-Source/commit/3cd8741250dc03f1c166e15cfc9563f5ac36add9)) ## 8. Step through new ground before automating it From 5aa64c9ed818f75cd0a5b12f3d85ef6d2a1f427d Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 16:28:14 -0700 Subject: [PATCH 14/24] AutoStory lessons: 00.05 stepped through to the PC; read positions from the ground; towns need grids too Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index de32486c82..1433da4624 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -85,6 +85,9 @@ on top of his segment 00 ([`bdsp/1717-seg00`](https://github.com/dayfine/Arduino | Barry in the Trainers' School: "west 200 ms, A", then mash B. | Faced nobody (r79). | From the school door: one tile west, north until Barry stops us, then A per line. He gives the Town Map. | (not yet coded) | | Leaving 00.04: walk north 5 s into Jubilife. | Ran past Dawn's spot (r35); with our route, walked into the wall beside the stairs (r78). | Walk north; when the wall stops us and no dialogue follows, step a tile west and try again. Next: put the stairs in the map. | [`3cef78b77`](https://github.com/dayfine/Arduino-Source/commit/3cef78b771877675c83356133d8917eb0de681c9) | | The Pokétch president (Phase 23): timed legs, then wait for his dialogue. | He stands in the road and talks when we face him; pressing A to advance re-opened his talk each time it ended, so his first line came back again and again. | Talk once with A, then advance with B, which never starts a talk. | (stepped through; not yet coded) | +| Three coupon clowns: recorded legs, then press toward each and A until a dialogue opens. | The recorded legs ended a row off each clown; walking past a clown on the row above or below never talks. | Each clown stands still: below the Poké Mart's planters (from the south, facing north; Coupon 1), at the TV station door (from the east, facing west; Coupon 3), beside the Pokétch Company sign (from the south, facing north; Coupon 2). The default "Yes" answers both quiz questions; close "obtained" with A, the rest with B. | (stepped through; not yet coded) | +| Pokétch from the president: a landmark match, then align and talk. | — (not reached) | He is back at his first spot. Stand level with him on his east side, face west, A, then B. "Please press the R Button" means the Pokétch is ours. | (stepped through; not yet coded) | +| Into the Jubilife Pokémon Center, to the PC. | — (not reached) | The door opening is half a tile east of where the frame stops a walk north. Inside: north to the counter, about 4 tiles east, then the tile below the PC, facing north. | (stepped through; not yet coded) | | Checkpoint retry reloads and repeats the same steps. | Deterministic failures retried up to 20 times. | Lab runs stop at the first failure (section 3). | lab scripts | His route did one thing right that we dropped for a while: the Poké Mart lady on Route 201 @@ -113,6 +116,16 @@ The run now gets the Potions first and saves on Route 202, (30,19), so later att light blue button, and status moves sit lower (no "Effective" line); a fixed cut and box read "" for Water Gun and Growl (r73). Threshold halfway between each button's background and its darkest pixel, and keep the tallest text band. ([`97df88c43`](https://github.com/dayfine/Arduino-Source/commit/97df88c439845600a02d0114478bb66d4b158ad5)) +- **Reading positions from roofs and heads.** In the tilted 3D view, a roof shifts against the + ground as the camera follows us, and a sprite's head rises into the row above its feet. Fixed + clowns looked like they wandered, and we pressed A diagonally next to the president, which + talks to nobody. Rule: judge rows and columns by feet and ground features (planters, curbs, + plaza edges), and stand level with an NPC before talking. +- **Dead reckoning in a town without a map.** In Jubilife, open-street "walk until stopped" legs + ran far past what was meant, and buildings hid the player; we lost our place twice. Bulbapedia's + DP map of Jubilife matches the BDSP layout (school, Center, Mart, TV station, Pokétch Company, + fountain park all where DP has them), so towns get a tile grid too, checked against the + console, with the story NPCs on it. - **Not saying what we are doing.** The overlay and the log now print each checkpoint's steps, the current one and the next, and every status report starts with the current problem. ([`3cd874125`](https://github.com/dayfine/Arduino-Source/commit/3cd8741250dc03f1c166e15cfc9563f5ac36add9)) @@ -123,5 +136,6 @@ After hours of whole-run attempts at the lady, five minutes of stepping found he Console takes 5 to 10 commands at a time (walk until stopped, a few presses, a screenshot), then waits while we look. Where the map or the scene is unknown (a new town, a building, an NPC to talk to), step through it first, write down each stop and dialogue, and only then -write the automated version from what was seen. 00.05 (the Trainers' School, the Pokétch) -is being done this way. +write the automated version from what was seen. 00.05 was done this way on 2026-10-28: Barry and the Town Map, the president, all three +coupon clowns, the Pokétch and the Center PC, about 60 batches, ending in a save at the PC +(segment 0 complete). From 0443b0332264c79a7b6a8ffa6ade30a92c0587fc Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 17:19:58 -0700 Subject: [PATCH 15/24] AutoStory: segment 01 plan (story, trainers, maps, work order); segment 00 leftovers scheduled Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Design.md | 6 +- docs/design/AutoStory-Segment00-Finish.md | 37 ++++++++ docs/design/AutoStory-Segment01-Plan.md | 105 ++++++++++++++++++++++ 3 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 docs/design/AutoStory-Segment00-Finish.md create mode 100644 docs/design/AutoStory-Segment01-Plan.md diff --git a/docs/design/AutoStory-Design.md b/docs/design/AutoStory-Design.md index 7dffe0b88c..fbb111b5ac 100644 --- a/docs/design/AutoStory-Design.md +++ b/docs/design/AutoStory-Design.md @@ -3,8 +3,10 @@ Companion to [AutoStory-Lessons.md](AutoStory-Lessons.md): that doc lists the failures, this one describes the pieces built in response and how they fit together. Status as of 2026-10-28 (evening): 00.04, from the catch to Dawn in Jubilife, runs unattended on console B (r79); -00.05 is being stepped through. Each section says what is built, where, and what is still -planned. +00.05 was stepped through by hand and rewritten on a Jubilife grid (not yet run). Each section +says what is built, where, and what is still planned. Next work: +[AutoStory-Segment01-Plan.md](AutoStory-Segment01-Plan.md), then +[AutoStory-Segment00-Finish.md](AutoStory-Segment00-Finish.md). The common idea: **never act on an assumption the screen could have checked.** Each piece reads the screen, takes one step, and reads again. Durations are caps, not plans. diff --git a/docs/design/AutoStory-Segment00-Finish.md b/docs/design/AutoStory-Segment00-Finish.md new file mode 100644 index 0000000000..23b1168612 --- /dev/null +++ b/docs/design/AutoStory-Segment00-Finish.md @@ -0,0 +1,37 @@ +# AutoStory segment 00: what is left (scheduled after segment 01's first pass) + +Status 2026-10-28. Code: fork branch `bdsp/new-game-intro-v2`, worktree +`~/Projects/Arduino-Source-bdsp`, latest commit 6dbcc8e10 (00.05 on a Jubilife grid). +Testing: the `bdsp-autostory-test` skill. + +## Where it stands + +| Checkpoint | State | +|---|---| +| 00.00 to 00.03 (new game, intro, starter, Pokédex) | run unattended earlier (new-game intro on the screen machine) | +| 00.04 (Potions, training, Route 202, Dawn) | ran unattended from the Route 202 Potion save (r79) | +| 00.05 (Jubilife: Barry, president, clowns, Pokétch, Center PC) | done by hand on the console, then rewritten on a tile grid (6dbcc8e10); **not yet run** | + +The only save on console B is the end of segment 00 (at the Jubilife Center PC). There is no +00.05-start save any more. + +## Why it is deferred + +Testing 00.05 for real needs a new game through 00.00 to 00.04, which overwrites the +end-of-00 save that segment 01 starts from. Segment 01 is stepped through first from that save; +segment 00 is finished afterwards. + +## Plan + +1. **Dry run in town (no new game).** From the current save the NPCs are still there and still + talk. Walk the 00.05 legs with the Lab Console or a diagnostic entry: school door, president + (44,26), the three clowns (Mart clown at (54,23) is unverified), the Center door (51,30). + Fix the grid where the console disagrees. Story-specific dialogue lengths differ after the + story, so only walking and talk-starting are checked here. +2. **Shorten the zig-zag plans.** The school-to-president plan is about 30 legs because the + plazas have few walls to end legs on. Either accept open legs with localisation after them, + or add known stopping features (planters, curbs) to the grid as walls. +3. **New game, full segment 00, twice** (needs the user's OK at that time: it overwrites the + save). Each run must end with "Completed: 00.05" and a save at the PC; keep both runs' logs + and the save screenshots. +4. Push the branch and update the fork PR's description (2 to 5 sentences). diff --git a/docs/design/AutoStory-Segment01-Plan.md b/docs/design/AutoStory-Segment01-Plan.md new file mode 100644 index 0000000000..4c2a7dae4c --- /dev/null +++ b/docs/design/AutoStory-Segment01-Plan.md @@ -0,0 +1,105 @@ +# AutoStory segment 01 plan: Jubilife to the Coal Badge + +Status 2026-10-28: research done, nothing built yet. Companion to +[AutoStory-Design.md](AutoStory-Design.md) (the pieces) and +[AutoStory-Lessons.md](AutoStory-Lessons.md) (what went wrong in segment 00). +Testing is done by an agent with the `bdsp-autostory-test` skill +(`~/.claude/skills/bdsp-autostory-test/SKILL.md`). + +## 1. Starting point + +- **Save on console B:** end of segment 00, at the Jubilife Pokémon Center PC (play time 1:53, + "Last saved 01/01/2026 01:00"). This is 01.01's start, so segment 01 can be stepped through + and tested **without a new game**. +- **Party:** Piplup alone, about Lv 10 to 11 after the 00.04 training and three Route 202 + trainers, knowing Water Gun. Bag: the rest of the 10 Potions, Poké Balls, no money worth + speaking of beyond the trainer prize money. +- **Help mode:** `HELP_MODE = no_outside_help`. Butters' segment 01 assumes the starter was + swapped for a **level-100 Pokémon from HOME** at that PC (his 01.01 start text: "Received + Starter back from Pokemon Home. Max leveled pokemon"). With that, every battle is one + attack. Without it we must win with a Lv 10 to 15 Piplup, so training, healing and move + choice matter here, unlike in his version. + +## 2. The story, step by step + +| # | Where | What happens | Ends when | +|---|---|---|---| +| 1 | Jubilife Center | (optional) heal at the nurse; buy Potions at the Mart next door if money allows | back on the Center's front step | +| 2 | Jubilife east exit to Route 203 | Barry stops us at the route entrance: **rival battle**, Starly Lv 7 then Turtwig Lv 9 (we chose Piplup) | Barry's dialogue ends | +| 3 | Route 203 | trainers in sight along the way: Youngster **Dallas** (Kricketot 7), Youngster **Sebastian** (Machop 7). Off-path: Youngster Michael (Bidoof 5, Zubat 5), Lass Kaitlin (Bidoof, Budew, Starly 4), Lass Madeline (Starly 5, Bidoof 5) | the Oreburgh Gate door (cave entrance, east end) | +| 4 | Oreburgh Gate 1F | a Hiker gives **HM06 Rock Smash** (dialogue only). Camper **Curtis** (Shinx 7), Picnicker **Diana** (Budew 5, Psyduck 5). Wild: Geodude 4 to 8, Zubat 6 | white-screen exit east into Oreburgh City (end of 01.01) | +| 5 | Oreburgh City | a man stops us at the entrance and takes us on a short "tour" (dialogue); Roark is not in the gym yet | mine entrance (south of the city) | +| 6 | Oreburgh Mine 1F, B1F | Worker **Colin** (Geodude 7, Onix 7), Worker **Mason** (Machop 9); Roark is at the far end of B1F, talks, smashes a rock, sends us to the gym. Wild: Geodude 5 to 10, Zubat 7 to 8, Onix 8 to 9. Items: X Defense 1F, Potion and Escape Rope B1F | back outside (walk or Escape Rope), then gym door (end of 01.02) | +| 7 | Oreburgh Gym | tiered floor with stairs (BDSP layout, not DP's); one or two gym trainers that bridges let us skip. **Roark**: Geodude 12 (Stealth Rock, Defense Curl, Rollout), Onix 12 (Stealth Rock, Rock Throw, Bind), Cranidos 14 (Headbutt, Bulldoze, Leer; Mold Breaker) | Coal Badge, standing at Roark (end of 01.03) | + +Sources: Serebii's BDSP pages for Route 203, Oreburgh Gate, Oreburgh Mine and the gym list +(Bulbapedia's text pages are behind a Cloudflare check; its image archive is not). Trainer +lists for the gym and the exact Roark location in the mine are still to confirm on the console. + +## 3. Battles: what Piplup is up against + +Our move picker uses the strongest known attack (Water Gun) every turn. Where that is wrong: + +| Fight | Problem | Plan | +|---|---|---| +| Barry's Turtwig Lv 9 | Grass resists Water: Water Gun with STAB ≈ 30 power, Pound 40 | add type effectiveness to the move picker (step 3 below); Potions under half HP | +| Roark's Geodude / Onix | Rock/Ground, Water is ×4 | Water Gun is right | +| Roark's Cranidos Lv 14 | Headbutt hurts; Mold Breaker irrelevant | Water Gun ×2; reach Lv 14 to 15 first; Potion under half | +| Wild battles | run, as in 00.04 | unchanged | + +**Levels.** Aim for Piplup Lv 14 before Roark. The trainers on the way (Barry, Dallas, +Sebastian, Curtis, Diana, Colin, Mason) give roughly 3 to 4 levels; if short, train on +Geodude in the mine (Water Gun one-shots them, good experience). + +**Losing.** A whiteout returns us to the last Center with half the money. Detect it (black +screen into a Center, or the "can't battle" party screen) and fail the attempt with a clear +message; do not continue blindly. + +## 4. Maps and grids + +Following segment 00's rule: plan routes offline on tile grids traced from Bulbapedia's DP maps, +and put NPCs/trainers found on the console onto the grid. + +| Map | Source image | State | +|---|---|---| +| Route 203 | `Sinnoh_Route_203_DP.png` (976×368, three stitched panels; check that the panel joins sit on the 16 px grid) | downloaded, to trace | +| Oreburgh Gate 1F | filename not found yet (`Oreburgh_Gate_DP.png` etc. 404) | find the file name, or trace from console screenshots | +| Oreburgh City | not found yet | same | +| Oreburgh Mine 1F, B1F | `Oreburgh_Mine_B1F_DP.png` (400×396); 1F not found | B1F downloaded | +| Oreburgh Gym | BDSP layout differs from DP; `Oreburgh_Gym_BDSP.png` is one screenshot | trace from console screenshots | + +Archive URL: `https://archives.bulbagarden.net/media/upload///`, h = md5 of the +file name. Downloads go to the session scratchpad, not the repo; only the ASCII grid is +committed. + +Butters' segment 01 (fork branch `bdsp/autostory-1717`, `Segment_01.cpp`, 2111 lines) is +mostly timed stick holds (`pbf_move_left_joystick(…, 2694ms)`) plus picture matching inside +the mine (crate and rock patches compared at shifted positions). Useful as a record of the +order of events and dialogue counts, not as code to keep: the same timed-leg style failed in +00.04 and 00.05 (Lessons §6). + +## 5. Work order + +1. **Trace Route 203** into `Data/PokemonBDSP_AutoStory_Route203.{h,cpp}`, joined to Jubilife's + east exit in a `MapSet`. Offline plan tests for Center → Barry → Gate. +2. **Step through 01.01 on the console** from the current save with the Lab Console + (batches of 5 to 10 commands with a screenshot each): Barry's trigger tile, trainers' + positions and sight, the Gate's Hiker, Curtis and Diana, the white exit. Record each stop. +3. **Type-aware move choice**: read the opponent's species name (OCR of the battle text box), + look up its types, and score moves by power × STAB × effectiveness. Unit tests on saved + battle screenshots. +4. **Write 01.01** on the grid with `walk_route`, `talk_to_npc`, `finish_dialogue` and the + trainer handling from 00.04. Save at the Oreburgh Center when it ends. +5. **Gate, city and mine grids** (from the images or console screenshots), then step through + 01.02, then write it. Decide walk-out vs Escape Rope after seeing the mine. +6. **Gym**: step through, write 01.03 with a heal at the Oreburgh Center first. +7. **Test** each checkpoint twice from its start save with the testing skill; then the whole + segment once from the end-of-00 save. + +## 6. Open questions + +- Is Barry's trigger a tile (walk-in) or a line across the route? Step 2 answers it. +- Do Route 203's trainers stop us on the shortest path, or can the plan go around the optional + ones? We want the experience, so the plan should walk into Dallas and Sebastian on purpose. +- Money: enough for Potions after Barry (prize money) or not? Read it in the Mart. +- Where exactly is Roark in B1F, and does the scene move us? From 7136c6cadcfc4a10d0c7d681930b489ff03f9882 Mon Sep 17 00:00:00 2001 From: dayfine Date: Wed, 28 Oct 2026 20:29:18 -0700 Subject: [PATCH 16/24] AutoStory lessons: segment 01 runs r81 to r90, one rule per failure Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 39 +++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 1433da4624..7cb946930e 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -125,7 +125,8 @@ The run now gets the Potions first and saves on Route 202, (30,19), so later att ran far past what was meant, and buildings hid the player; we lost our place twice. Bulbapedia's DP map of Jubilife matches the BDSP layout (school, Center, Mart, TV station, Pokétch Company, fountain park all where DP has them), so towns get a tile grid too, checked against the - console, with the story NPCs on it. + console, with the story NPCs on it. *Later (r82):* the grid's walls in the open plaza are not + where the game has them, so it is not good enough to plan on there; see section 9. - **Not saying what we are doing.** The overlay and the log now print each checkpoint's steps, the current one and the next, and every status report starts with the current problem. ([`3cd874125`](https://github.com/dayfine/Arduino-Source/commit/3cd8741250dc03f1c166e15cfc9563f5ac36add9)) @@ -139,3 +140,39 @@ an NPC to talk to), step through it first, write down each stop and dialogue, an write the automated version from what was seen. 00.05 was done this way on 2026-10-28: Barry and the Town Map, the president, all three coupon clowns, the Pokétch and the Center PC, about 60 batches, ending in a save at the PC (segment 0 complete). + +## 9. Segment 01 to Oreburgh City (2026-10-28, r81 to r90) + +01.01 (Jubilife Center to Barry) and 01.02 (Route 203, Oreburgh Gate, Oreburgh City) were +stepped through by hand once, written from that ([`8dda984d5`](https://github.com/dayfine/Arduino-Source/commit/8dda984d5ca88a1d59b605a3312711162777bba7)), and then run on console B. Ten +runs, each stopped at its first failure, and one fix per failure: + +| Run | What happened | Rule / fix | Commit | +|---|---|---|---| +| r81 | West from the PC hit the end of the counter; the walk south then stopped at the stools. | The hand run had gone south first without our noticing. Write down every move of a hand run, including the ones that "did nothing". | [`da01cc799`](https://github.com/dayfine/Arduino-Source/commit/da01cc799ba92eb5723493d943414c881a4a36dc) | +| r82 | A grid leg to a wall the Jubilife map shows walked on ~19 tiles and ended at the Trainers' School. | Jubilife's plaza grid is wrong in its open areas. There, use the holds measured on the console, and end each leg with a search (walk east; at a wall, try the next row). | [`c4883f3cb`](https://github.com/dayfine/Arduino-Source/commit/c4883f3cb2e7c1ea18f1a34a1dd0f82b89d1b2f4) | +| r83 | Barry stopped us, but "only talked" was decided 0.6 s into the pause before his battle. | A trainer's talk and battle have a quiet gap with no text box: wait 4 s of overworld before calling it a talk, and for a story battle never call it one. | [`85ef91790`](https://github.com/dayfine/Arduino-Source/commit/85ef91790d74c0b6b2a9caa88c9890fa07886dfe) | +| r84 | Stuck for 4 min choosing Water Gun at 0 PP; the game refused it each turn. The user spotted the PP risk at the same time. | Read each move's PP by OCR (text = whatever differs from the button's own color, since PP text turns yellow to red); skip 0-PP moves; fail a battle still at its menu after 25 turns. | [`a5f91acde`](https://github.com/dayfine/Arduino-Source/commit/a5f91acdeff362da2e502e33b56e4c5aaf5ddd6a), [`9721801e3`](https://github.com/dayfine/Arduino-Source/commit/9721801e3f258cd49bae506434253df55528648e) | +| r85 | Barry started at 66 % with Water Gun 12/25: the nurse had not healed. Her Yes/No is on her third line, and the B after two A presses answered No. The in-battle Potion (15 % → 93 %) worked. | Count an NPC's lines before choosing how many A presses; an extra A on a later line is harmless, a B on a question is not. The run now also saves after Barry (01.01 split at him). | [`b2236ba72`](https://github.com/dayfine/Arduino-Source/commit/b2236ba72f48e09f237a2ea07b82da802c2efba9) | +| r85 | After the Hiker, a "Hidden Moves" tutorial card held the screen; it is no dialogue box, so the walk read it as a wall. | Tutorial cards close with B; press B after a scene that teaches something. | [`a9863ad8b`](https://github.com/dayfine/Arduino-Source/commit/a9863ad8b73b7941d2b0070025b2415b9913f3a3) | +| r86 | The nurse healed, but `finish_dialogue` ended during the healing jingle; her "Thank you for waiting" then stopped the walk out. | A scene with an animation in the middle needs a second wait for its last lines. | [`00c8fcbf7`](https://github.com/dayfine/Arduino-Source/commit/00c8fcbf7c1f88680ebf54a98e42001918a122a2) | +| r87 | Route 203: only one trainer stopped us, so "after two fights the next wall is the cliff" fired at the stairs between stretches. | Who stops us depends on our row, so trainer counts say nothing about where we are. | [`5345260db`](https://github.com/dayfine/Arduino-Source/commit/5345260dbb113e90cb0174a594561b3d3281bef7) | +| r88 | Reached the north-east corner by the second sign, but the row search counted blocked steps north as moves and never tried the cave's row. | The user's rule: at a wall, go north to the top wall (that pins the row), then try rows south of it one at a time. The cave is two rows below the corner. | [`22998e853`](https://github.com/dayfine/Arduino-Source/commit/22998e853caa8b8529165a33b0c5135511a869a5) | +| r89 | Got into the Gate on the first row, but the cave's fade did not read as a transition; the Hiker's talk was then taken for a trainer's, and his card stayed up. | On Route 203 only trainers start a talk, so a talk with no battle means the Hiker inside the Gate. | [`3cb2e2f78`](https://github.com/dayfine/Arduino-Source/commit/3cb2e2f78631648b132824997e9f8c757cefd657) | +| r90 | **01.02 passed**: trainer, Hiker, Curtis, Diana, the man at Oreburgh's entrance. | | | + +Also from these runs: + +- **01.02 ends too early.** The man at Oreburgh's entrance walks us to the Pokémon Center, + where Barry shows up ("Huh? There's someone there."). `finish_dialogue` returned while the + scene was walking, between lines. The next checkpoint must finish that scene first. The user + saved by hand there after r90. +- **The lab script's Stop click can miss.** r87's load step left the Lab Console running, so + AutoStory was refused as "console busy". `run_from_save.sh` now retries Stop until the + console reads free. +- **Overlay text was cut off** at the log box's width; AutoStory now wraps its overlay lines. + ([`344a050ce`](https://github.com/dayfine/Arduino-Source/commit/344a050cecc08a61a0f5b528c2c301493c2095e9)) +- **What held up:** the in-battle HP read and Potion, the PP read (29, 40, 12 → 11 in Barry's + battle), the walk out of the Center to the girls below the door, and Barry from the measured + holds plus row search. + From e5bd6d3bee36c21611751d2ff5952c5be9505a8d Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 02:43:11 -0700 Subject: [PATCH 17/24] =?UTF-8?q?AutoStory=20lessons=20=C2=A710:=20Oreburg?= =?UTF-8?q?h=20Mine,=20Roark's=20gym,=20Route=20204=20to=20Floaroma;=20But?= =?UTF-8?q?ters'=20segment=2001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 7cb946930e..0d8f4264a8 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -176,3 +176,51 @@ Also from these runs: battle), the walk out of the Center to the girls below the door, and Barry from the measured holds plus row search. + +## 10. Oreburgh Mine, Roark's gym and on to Floaroma (2026-10-28/29, r91 to r106, then by hand) + +01.03 (city → mine → Roark) was written from the parsed mine map (`devtools/maps/levels.py`) +and run r91 to r106. After that the user asked to fight the gym as we were, gaining +experience by losing, and to reach Floaroma by hand; the console now holds a save in the +Floaroma Pokémon Center (Badge 1, play time 4:23, Piplup Lv 15, Starly Lv 13). + +| Run | What happened | Rule / fix | Commit | +|---|---|---|---| +| r91–r93 | Timed holds put us a column off the mine's stairs, sometimes left, sometimes right. | Anchor on walls the map shows (the conveyor pillars, the fence below the Mart); never count on a hold's length for a column. | `1a77905e4` | +| r95, r96 | The walk south stopped early: the hard-hat worker by the fence wanders onto the path. | A stop that a wall cannot explain may be a wandering NPC: wait and walk again before trusting it. | `1a77905e4` | +| r96 | One column off, the walk ends on the sign above the mine's stairs. | The user: being stuck is fine if we can rescue ourselves. Step one tile east off the sign's column; the stairs are open on both sides. | `b3928e6fc` | +| r97 | Blocked legs left us a row high, probing Roark's own row with his rock in between. | End a search on a wall that pins the row (the bottom wall) before probing. | `f84c3ce3c`, `2f8be46f9` | +| r98 | Right below Roark; A started his camera zoom but the first line came after 2 s. | Story NPCs zoom the camera before the first line: wait up to 8 s. | `f59923b67` | +| r99, r103 | The route back walked through the corridor's top into the hall ("unexpected transition"); later the hall and the corridor turned out to be one walk. | End the planned route on a tile a wall pins (the corner at (14,11)) and let one walk do the transitions. | `a414e333a`, `f59a16e51` | +| r101, r104 | Below Roark, A did nothing, by hand too. | **Roark only answers after Barry has sent us** ("go down to the mine and ask him"), so talk to Barry at the gym door first. Confirmed by hand: after that talk, Roark answered the first A. | `a65a02b84` | +| r105, r106 | "Passed", but the nudge before A had stepped onto the rock beside Roark and the rock's one line ("It's a rugged rock…") was taken for his. | A dialogue opening is not proof: check the story effect. Movement is by whole tiles (30, 40 and 60 ms holds all move one tile; 20 ms only turns), so there are no half-tile nudges. 01.03 now steps onto Roark's tile after the talk and fails if he is still there. | `a65a02b84` | + +By hand, after 01.03: + +- **The gym.** Walking straight up the middle meets both gym trainers (one at the entrance, + one on the second tier). Roark (Geodude 12, Onix 12, Cranidos 14) beat Piplup Lv 10 and 14 + twice; the third try at Lv 14 with a fixed move choice won and Piplup reached 15. A whiteout + costs some money and keeps experience, so losing and retrying is a cheap way to level. +- **Battle loop on the Lab Console** (`~/BDSPLab/fight_lc.sh`, with a colour check for the + four battle buttons in `~/BDSPLab/battlemenu`): Battle, A, then the move; the move list + needs ~2 s to open, or the Down presses are lost and Pound is used. A double battle needs a + third A to pick the target. Move-learn prompts need "Keep old moves" (Down, A); B alone + loops on them. +- **Screenshots lag.** After long walks a `shot` can show a frame several seconds old, which + made us think the player was stuck. Wait ~3 s before a `shot` that decides the next move. +- **Route 204** (Jubilife → Floaroma): Jubilife's north road starts ~10 tiles west of where + Route 203 enters; Rowan, Dawn and two Galactic grunts stop us there for a tag battle with + Dawn. The Ravaged Path needs Rock Smash on its rocks (A, Yes, Yes); its north exit is the + lit opening a tile west of the corridor's east end, *south* of the entrance chamber, not + across the water. North of it: up the stairs, then a row down and east along the sand, + north through the grass to the flower beds, round the twins (a double battle), and north + between the beds into Floaroma. The Center is a few tiles east of where we arrive. + +### Butters' segment 01, checked against what we found + +| His version | What we found | Rule | +|---|---|---| +| Oreburgh city, mine and gym are timed stick holds and d-pad tap counts. | The same drift as section 6; d-pad taps are one tile each only when the player already faces that way. | Walls and the map, not counts. | +| Roark in the mine: A once, then up to 30 s for his first box, B to advance. | Right to wait long and to advance with B. But A does nothing until Barry has been talked to at the gym door, which his route gets from the tour scene's mashed B. | Make the Barry talk an explicit step. | +| Gym: up 3, left 4, up 5, right 8, up 11, left 5, up 4, then A at Roark. | That path goes round both gym trainers; straight up meets both. | Worth keeping as a plan for the gym grid; the trainers' experience helps an under-levelled team, though. | +| "Barry 1 battle logic can be used here since the moves don't matter this early." | Moves matter against Roark: Pound does almost nothing to rock types, and the first two tries were lost. | Pick Water Gun by name; heal or switch before Cranidos. | From 6141702bdf5cff74f4383b47c607dce863ea4d2e Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 17:33:45 -0700 Subject: [PATCH 18/24] AutoStory: shared navigation core and the FRLG Brock / BDSP Floaroma MVP branches Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Design.md | 4 +- docs/design/AutoStory-Navigation-Stack.md | 128 ++++++++++++++++++++++ docs/design/AutoStory.md | 10 ++ 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 docs/design/AutoStory-Navigation-Stack.md diff --git a/docs/design/AutoStory-Design.md b/docs/design/AutoStory-Design.md index fbb111b5ac..7989acfd9a 100644 --- a/docs/design/AutoStory-Design.md +++ b/docs/design/AutoStory-Design.md @@ -230,4 +230,6 @@ School were found, after whole-run attempts had failed on each. - Can tall grass get a stop signal (e.g. the player sprite's position instead of the whole view)? That would remove the special case in section 2. - How much of the planner and map set is shared with FRLG (same 16 px tiles, same ledges)? - The code lives in `Pokemon/Navigation` so it can be. + Answered 2026-10-29 in [AutoStory-Navigation-Stack.md](AutoStory-Navigation-Stack.md): the + planner and walker are shared through a per-game step model and mover; the tile legend and + `TileGrid` stay BDSP's. The BDSP MVP branch is `bdsp/floaroma-mvp`. diff --git a/docs/design/AutoStory-Navigation-Stack.md b/docs/design/AutoStory-Navigation-Stack.md new file mode 100644 index 0000000000..644aa64ee0 --- /dev/null +++ b/docs/design/AutoStory-Navigation-Stack.md @@ -0,0 +1,128 @@ +# AutoStory: shared navigation core and the two MVP branches + +Status: plan, 2026-10-29. Replaces the T1/T2 sketch in [AutoStory.md](AutoStory.md) §5.1 and §7.7 +and answers the open question in [AutoStory-Design.md](AutoStory-Design.md) ("how much of the +planner and map set is shared with FRLG"). Evidence: the BDSP lab branch +`bdsp/new-game-intro-v2` (00.04 runs unattended; 01.05 to Floaroma written) and the FRLG lab +branch `frlg/overworld-nav` (walked Nugget Bridge to Mewtwo on console B, 2026-10-29). + +## 1. What the two games built, side by side + +| Concern | BDSP (`Pokemon/Navigation`, AutoStory utils) | FRLG (`PokemonFRLG/Overworld`) | +|---|---|---| +| Direction, tile | `GridDirection`, `TilePos` | `MapDirection`, `MapPoint` (same thing again) | +| Map | `TileGrid`, hand-traced from DP maps: blocked, walk, grass, ledge (south), NPC, sign, door, unknown | `OverworldMap`, generated from pokefirered: walls, water, one-way tiles, ledges, doors / cave mouths / ladders / exit mats, elevation, objects with flags and wander boxes | +| Several maps | `MapSet`: grids placed on one world grid; no warps | maps joined by warps and edge connections with offsets | +| Planner | `plan_tile_route` (legs, extra for stopping in the open); `plan_robust_route` (a set of possible tiles, open legs a tile off) | search over (map, tile, elevation, surfing, facing, mid-leg), extra for stopping in the open, warps, Surf | +| Walking | `walk_route`: stick holds, 160 ms per tile across, 240 ms up/down; tracks possible tiles; re-plans after a trainer | `walk_overworld_route`: D-pad holds, 267 ms per tile (133 surfing); warps; Surf | +| Interruptions | hard-wired: trainer fight callback, fail on a wild battle in an open leg, dialog, transition | `OverworldInterrupt` list: battle flash (about 300 ms after the step), battle screen, message / Repel wore off (uses a Max Repel) | +| Facing | tracked; a tap only turns a player facing another way | tracked, and read from the player sprite | +| Trainers | sight lines on the grid | none yet (the decomp has them) | + +Written twice: the direction and tile types, legs that end at a wall, the extra cost for +stopping in the open, open leg timing ((n - 1/2) tiles of hold), the turn tap, and what to do +when something stops a leg. Neither planner can serve the other game, because each is bound to +its own map class. That is the layering problem to fix: the shared code should call into the +game once per step, not own the tile legend. + +## 2. Layers + +**Shared, `Pokemon/Navigation/` (console-free):** + +- `Pokemon_Grid.h`: `Direction`, `TilePos`. +- `Pokemon_LegPlanner.h`: the cheapest legs from a start to a goal, templated on a step model. + The game supplies `press(state, direction)`: the next state, whether the step ends the leg + (warp, starting or leaving Surf), and the facing after it; and `held_at(state, direction)`: + whether holding further keeps the player on this tile (a wall, not a person or a map edge). + The planner searches, merges steps into legs, marks legs that end at a wall, and charges for + turns, leg ends in the open, grass, warps. FRLG's `press()` and BDSP's `TileGrid::step()` both + fit as they are. +- `Pokemon_RobustPlanner.h`: planning over a set of possible tiles (BDSP's + `plan_robust_route`), on the same step model. Only BDSP needs it (stick walking drifts); FRLG + walks exactly. +- `MapSet` stays: one way for a game to build a step model (maps placed side by side). FRLG's + warp graph is the other. + +**Shared, `Pokemon/Navigation/Pokemon_LegWalker.h` (templated on the controller context, like +`run_until`, so `Pokemon/` stays free of `NintendoSwitch/`):** + +- `LegMover`, per game: how to turn (tap), how to hold a direction (D-pad or stick), the time + per tile for a leg (direction, surfing, biking). +- `LegInterrupt`, per game: a watcher, how long after the step it fires, how to clear it. +- `walk_leg()`, shared: hold the leg while watching every interrupt; on one, clear it, then + hold a wall leg again, or work out how far an open leg went from when it was seen. Reports + tiles walked and whether that is exact. + +**Per game:** the map data and its generator, the step rules, timings, detectors, interrupt +handlers (trainer, wild battle, message, Repel), the facing reader, landmarks. + +## 3. State: what is on screen, and where the player is + +Two different things, kept apart: + +- **Screen state**: which screen is up (overworld, dialogue, battle, menu, bag, black). The + shared mechanism is the screen machine and step trace (`CommonTools/ScreenMachine`, already + game-neutral); the per-game part is the detectors. Menus and scripted scenes run on the + screen machine. While walking, the same detectors are the leg walker's interrupts, so the + walker does not need a screen machine of its own. Missing: an FRLG overworld detector + (overworld vs anything else without opening a menu), planned as D1. +- **Overworld state**: where the player is and what the world looks like. The pose is shared + vocabulary: map, tile, facing, movement mode (walking, surfing, biking), plus how sure we are + (one tile, or a set of possible tiles). The world state is per game but follows one pattern + in both: maps are built from data with flags applied (FRLG event flags hiding objects; BDSP + defeated trainers and smashed rocks), and the planner reads the result. The walker updates + the pose after each leg and after an interrupt; the facing reader and landmarks (BDSP) or + wall anchors (both) correct it. + +Rule: the screen is read, the pose is tracked. A pose is never inferred from elapsed time +alone except for an open leg, and then it is marked inexact until a wall or a landmark fixes +it. + +## 4. Branches and PRs + +``` +upstream main + └─ nav/core shared: grid types, leg planner, leg walker, screen machine + ├─ frlg/brock-mvp FRLG: maps + step model, D-pad mover, interrupts, facing, + │ Brock route (new game -> Boulder Badge) + └─ bdsp/floaroma-mvp BDSP: TileGrid/MapSet on the planner, stick mover, interrupts, + AutoStory 00 and 01 to Floaroma, nothing else +``` + +`nav/core` (one fork PR per item, stacked): + +| ID | Contents | Tests | +|---|---|---| +| N1 | `Pokemon_Grid.h`, `Pokemon_LegPlanner.h` | a small made-up game: walls, a warp, a one-way tile, grass, open vs wall legs | +| N2 | `Pokemon_LegWalker.h` | scripted mover and interrupts: wall leg re-walked, open leg estimate, too many interrupts | +| N3 | `CommonTools/ScreenMachine` + `StepTrace` (from the BDSP lab) | the existing machine tests with fake screens | + +`frlg/brock-mvp` (on N1–N3): the FRLG overworld code moves onto the core types in its final +place (no move PRs of our own code later), then the Brock route. Includes the bag fix +(fork #65) and the facing reader. The Mewtwo route stays in the lab branch as the live test of +the walker. Brock route work follows §7.4 segments 00 and 01 of [AutoStory.md](AutoStory.md). + +`bdsp/floaroma-mvp` (on N1–N3): only what AutoStory 00 and 01 need to reach Floaroma. + +- In: the BDSP maps (Route 201 to Route 204 north, Jubilife, Oreburgh Mine, Ravaged Path) as a + step model, `walk_route` on the leg walker, the trainer and wild battle interrupts, the + AutoStory program with segments 00 and 01, the detectors and readers they use, the battle, + dialogue, Pokémon Center and new-game utilities, the system keyboard detector (in + `NintendoSwitch/Inference/`, its final home), their tests. +- Out: the old Lab Console and BDSP Lab Console commands (the Command File Runner, fork #58, + replaces them in the lab), the lighting test program, the unused `walk_steps` / + `walk_until_*` stubs, anything segment 02+. +- Risk: moving `walk_route` onto the shared walker changes code that ran unattended. The + branch is not done until 00.04 runs on a console again and 01.05 reaches Floaroma. + +Order: N1, then the FRLG child up to its planner tests (it already passes on the core idea), +then N2 with the FRLG walker on it (re-run the Mewtwo route), then the BDSP child. N3 can go +any time. The lab branches keep everything else and merge these branches in. + +## 5. Checks before each branch is called done + +- N1–N3: unit tests; no game code depends on anything not in the core. +- FRLG child: route tests; the Mewtwo route walked again on the console with the shared walker. +- BDSP child: offline plan tests for every segment plan; 00.04 and 01 run on the console. +- For both: `git diff --stat` against the lab branch shows only dropped lab code, no lost + game logic. diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index cf20e4b071..76fffda97e 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -368,6 +368,11 @@ avoid animated tiles; Flash-dark caves are the exception. ## 5. 2D movement: shared design +**Superseded 2026-10-29** by [AutoStory-Navigation-Stack.md](AutoStory-Navigation-Stack.md): a +shared core (`nav/core`: grid types, a leg planner over a per-game step model, a leg walker +with per-game movers and interrupts, the screen machine) with two children, `frlg/brock-mvp` +and `bdsp/floaroma-mvp`. The sketch below is kept for its reasoning (§5.2 still holds). + ### 5.1 Pieces Console-free. It lives in `SerialPrograms/Source/Pokemon/Navigation/` @@ -728,6 +733,11 @@ Consequences: ### 7.7 PR plan for reviewers +**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 +Elite Four farmer moves onto the walker later, not as part of the pilot. The rest of the table +stands. + Reviewers should know up front what is coming. Phase A is about 10 PRs, touches only FRLG files, and produces something users can run at PR 5. Most PRs are 150–500 changed lines, each does one thing, and each says what From 3c4222f363484ef25e4150e16be748bdd82524ce Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 17:48:36 -0700 Subject: [PATCH 19/24] AutoStory: end the FRLG run with Mew, through the Sevii Ruby and Sapphire Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Navigation-Stack.md | 2 +- docs/design/AutoStory.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/design/AutoStory-Navigation-Stack.md b/docs/design/AutoStory-Navigation-Stack.md index 644aa64ee0..e4096a5c92 100644 --- a/docs/design/AutoStory-Navigation-Stack.md +++ b/docs/design/AutoStory-Navigation-Stack.md @@ -95,7 +95,7 @@ upstream main |---|---|---| | N1 | `Pokemon_Grid.h`, `Pokemon_LegPlanner.h` | a small made-up game: walls, a warp, a one-way tile, grass, open vs wall legs | | N2 | `Pokemon_LegWalker.h` | scripted mover and interrupts: wall leg re-walked, open leg estimate, too many interrupts | -| N3 | `CommonTools/ScreenMachine` + `StepTrace` (from the BDSP lab) | the existing machine tests with fake screens | +| N3 | `CommonTools/ScreenMachine` + `StepTrace` (from the BDSP lab) | none yet: the checks between reads need tests with small fake frames | `frlg/brock-mvp` (on N1–N3): the FRLG overworld code moves onto the core types in its final place (no move PRs of our own code later), then the Brock route. Includes the bag fix diff --git a/docs/design/AutoStory.md b/docs/design/AutoStory.md index 76fffda97e..d14601e42e 100644 --- a/docs/design/AutoStory.md +++ b/docs/design/AutoStory.md @@ -677,6 +677,8 @@ positions; the decomp is the source of truth. | 08 | To Cinnabar (Route 21 by default) → Mansion (Secret Key) → Blaine | Seafoam optional; decline One Island | | 09 | Giovanni (Viridian) → Route 22 rival → Victory Road (Strength boulders) | | | 10 | Elite Four + Champion | reuse `EliteFourFarmer` pieces | +| 11 | Sevii post-game: Ruby (Mt. Ember), Sapphire (Dotted Hole), Network Machine | added 2026-10-29 (§9.2) | +| 12 | Mew | method to settle (§9.2); likely needs the naming typer | | opt | Money top-up, leveling loop, gift Pokémon, fossils | config-driven, outside the main order | Estimate ~90–110 checkpoints. Hardest: 00 (keyboard, intro), 05 (spin @@ -865,6 +867,11 @@ among the agents is recorded outside this doc. after the FRLG pilot runs and people use it. Until then, BDSP gets only the standalone bug comments (phase C). 2. **Scope:** main story to the Champion. No Sevii or post-game. + *Revised 2026-10-29:* the run ends with catching Mew, so it includes the + Sevii Islands post-game for the Ruby and Sapphire (Network Machine). Mew + has no in-game encounter in FRLG, so how it is obtained (e.g. arbitrary + code execution through box names, which needs the FRLG naming typer) is + still to be settled and becomes its own segment. 3. **Shortcuts** (Nugget Bridge money, Retro Mail duplication): available as options. They need planning, e.g. catching the right Pokémon at the right time, so they feed into the requirements plan (§7.6). From 464b01ea314b1ed1cffc2b46ae9ecfe41419f11f Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 18:54:25 -0700 Subject: [PATCH 20/24] AutoStory navigation stack: fork PR numbers Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Navigation-Stack.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/design/AutoStory-Navigation-Stack.md b/docs/design/AutoStory-Navigation-Stack.md index e4096a5c92..370e707e34 100644 --- a/docs/design/AutoStory-Navigation-Stack.md +++ b/docs/design/AutoStory-Navigation-Stack.md @@ -115,6 +115,10 @@ the walker. Brock route work follows §7.4 segments 00 and 01 of [AutoStory.md]( - Risk: moving `walk_route` onto the shared walker changes code that ran unattended. The branch is not done until 00.04 runs on a console again and 01.05 reaches Floaroma. +Fork drafts (2026-10-29): `nav/core` #66, `frlg/brock-mvp` #67, `bdsp/floaroma-mvp` #68 (on +#1717 at `45a206f0d`, branch `base/bdsp-1717`; their segments 02 to 09 kept but not in the +checkpoint list, since they start where #1717's own 01 ends). + Order: N1, then the FRLG child up to its planner tests (it already passes on the core idea), then N2 with the FRLG walker on it (re-run the Mewtwo route), then the BDSP child. N3 can go any time. The lab branches keep everything else and merge these branches in. From 002536ffde2d4707ab6bc731f0f7a9b1ebc2e765 Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 20:45:59 -0700 Subject: [PATCH 21/24] AutoStory: queue the BDSP MVP follow-ups (clock pin, shared walker, resources) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Navigation-Stack.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/design/AutoStory-Navigation-Stack.md b/docs/design/AutoStory-Navigation-Stack.md index 370e707e34..35a3a5a59a 100644 --- a/docs/design/AutoStory-Navigation-Stack.md +++ b/docs/design/AutoStory-Navigation-Stack.md @@ -119,6 +119,20 @@ Fork drafts (2026-10-29): `nav/core` #66, `frlg/brock-mvp` #67, `bdsp/floaroma-m #1717 at `45a206f0d`, branch `base/bdsp-1717`; their segments 02 to 09 kept but not in the checkpoint list, since they start where #1717's own 01 ends). +Follow-ups queued for `bdsp/floaroma-mvp` (2026-10-29), in order: + +1. **Drop the clock pin.** Segment 00 sets the Switch clock (2026-01-01 00:00:50) because #1717's + landmark matchers were captured at that lighting. It is used by 00.01's timed walk from the + bedroom, the starter-grass walk, the Sandgem junction alignment and finding the Poketch man in + Jubilife; segment 01 and the tile-grid walks don't need it. Replace the two landmark + alignments with tile-grid walks anchored on walls (as 00.04 does) and the 00.01 timed moves + with screen-driven walks, then remove `set_time_fast`. It also breaks runs on its own: with + "Synchronize Clock via Internet" on, the date row is disabled and the menu walk lands on Time + Zone (r108, 00.01, six failed attempts). +2. **Move `walk_route` onto the shared leg walker** (N2), then run 00.04 and 01 on the console. +3. **Trim the BDSP resources** to what segments 00 and 01 load (the AutoStory folder is 789 files, + 101 MB, mostly #1717's item icons and later-segment landmarks). + Order: N1, then the FRLG child up to its planner tests (it already passes on the core idea), then N2 with the FRLG walker on it (re-run the Mewtwo route), then the BDSP child. N3 can go any time. The lab branches keep everything else and merge these branches in. From 86787be2aef77113abe2972ef0220e05a4c28593 Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 22:15:14 -0700 Subject: [PATCH 22/24] =?UTF-8?q?AutoStory=20lessons=20=C2=A711:=20Floarom?= =?UTF-8?q?a=20MVP=20runs=20r107=20to=20r109=20and=20the=20lab=20around=20?= =?UTF-8?q?them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 0d8f4264a8..1762e71f4a 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -224,3 +224,28 @@ By hand, after 01.03: | Roark in the mine: A once, then up to 30 s for his first box, B to advance. | Right to wait long and to advance with B. But A does nothing until Barry has been talked to at the gym door, which his route gets from the tour scene's mashed B. | Make the Barry talk an explicit step. | | Gym: up 3, left 4, up 5, right 8, up 11, left 5, up 4, then A at Roark. | That path goes round both gym trainers; straight up meets both. | Worth keeping as a plan for the gym grid; the trainers' experience helps an under-levelled team, though. | | "Barry 1 battle logic can be used here since the moves don't matter this early." | Moves matter against Roark: Pound does almost nothing to rock types, and the first two tries were lost. | Pick Water Gun by name; heal or switch before Cranidos. | + +## 11. Floaroma MVP from a new game, and the lab around it (2026-10-29, r107 to r109) + +The MVP branch (`bdsp/floaroma-mvp`, fork #68) runs segments 00 and 01 from a new game on +the shared navigation core. Half of today's failures were in the lab, not in the game. + +| Run | What happened | Rule / fix | Commit | +|---|---|---|---| +| r107 | Every program refused to start: "requires video feedback". The camera opened without error but delivered no frames. | Launch lab apps through LaunchServices (`open -n`), never by running the binary from a shell: the app then inherits the shell's (the Claude app's) camera permission, which has none. `stage_launch.sh` now checks for video before anything else. | lab scripts | +| r107 | The MVP build stopped at run time on a missing template ("Unable to open file"). | The worktree's `Packages` linked to upstream's resource set (686 files); BDSP AutoStory needs `~/BDSPLab/packages` (1,467). The build copies `Resources` only when it is missing, so delete it after relinking. | r108 deployment | +| r108 | 00.01 "Failed to enter Date Change screen". | The clock pin walks the System Settings menu by position; with "Synchronize Clock via Internet" on, the date row is disabled and the walk lands on Time Zone. Turned the sync off on console B; dropping the pin is queued. | — | +| r108b | 00.04: A beside Mom started nothing. Two d-pad taps north from the door should have put us level with her; one did not move. | Same as section 1, now in the house: counted taps lose tiles. The door fixes the column, so face east and press A one row at a time going north until she answers. | `985de47c1` | +| r109 | Mom answered after 1 step; then entering Sandgem the check read the banner as "andgemltown" and failed. | A check tied to an exact OCR string is too narrow (section 2): the place was right. Match banner names loosely, with a test that a different town still fails. | pending | +| r109a | The run never started: the Start click landed where the button was before the window grew to 1554×1488. `stage_run.sh` would then have clicked Start/Stop "to stop the wrong program" and started an unwatched run. | Never toggle Start/Stop blindly: stop only when the log says RUNNING. Better, don't click at all: the lab app gets a control folder (`LabControl/start`, `stop`, `state`). Clicks also take focus from the user's work. | `lab/control-folder` | + +What this round adds to the design: + +- **Confirm where we are, not just where we planned to be.** The planner plans in tiles and + the walker counts them, but nothing reads the position back; every drift so far (sections + 1, 6, 9, 10 and the Mom row here) was found only when the next action failed. After each + leg, confirm with something the game shows (a wall reached, a landmark, a dialogue + answered, the facing) and replan from the confirmed tile when it differs. +- **Overworld screens belong in the screen machine.** The new-game intro runs on + `ScreenMachine`; walking, dialogue and battle interrupts should be states of the same loop, + so a dropped input shows up as an unexpected screen instead of a later timeout. From 9c1f58bec10ab49a8c10913d1eb1f02632afee85 Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 22:17:48 -0700 Subject: [PATCH 23/24] AutoStory lessons: split into Part 1 for Butters (#1717) and Part 2 for us Sections are renumbered; cross-references updated. Butters' segment 01 table and the two #1717 failures from r108 get their own sections in Part 1. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-Lessons.md | 81 +++++++++++++++++++------------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/docs/design/AutoStory-Lessons.md b/docs/design/AutoStory-Lessons.md index 1762e71f4a..4ae623d20c 100644 --- a/docs/design/AutoStory-Lessons.md +++ b/docs/design/AutoStory-Lessons.md @@ -2,9 +2,16 @@ Each entry is a failure seen on a Switch while running BDSP AutoStory (Developer-Butters' U#1717 plus our intro work, October 2026), the pattern behind it, and the rule we now follow. -Runs are the lab builds r14 to r79 on console B. The patterns repeat, so the rules matter -more than the individual fixes. Sections 6 to 8 cover r40 to r79, which took 00.04 from the -catch to Dawn in Jubilife unattended (r79). +Runs are the lab builds r14 to r109 on console B. The patterns repeat, so the rules matter +more than the individual fixes. + +The lessons fall into two parts. **Part 1 is for Butters**: what his recorded segments in +#1717 (PokemonAutomation/Arduino-Source#1717) need to survive another console, another +starter or another day, with the general rules behind each fix. **Part 2 is for us**: our +own code, our lab and our process. The rules in Part 1 apply to our code too. + + +# Part 1. For Butters: his segments on another console ## 1. Timed movement drifts; stop on what the screen shows @@ -59,16 +66,7 @@ at each checkpoint (`Screenshots/AutoStory/saves/`: play time, badges, party). **Rule:** for a trainer or a scene, the walk can end in any way short of a transition; the dialogue decides. Walk, then wait for the dialogue with its own timeout. -## 5. Our own process - -- Look at the screen, then the code, before rerunning. Every run since r28 that failed in a new - way was explained by one screenshot. -- Put new code in its final module first; no copy-then-move PRs of our own code. -- Keep line endings as they are (CRLF files stay CRLF); compare `git diff --stat` with - `--ignore-cr-at-eol`. -- When a program is stuck or failing, stop it and close the game at once; don't let retries run. - -## 6. Butters' 00.04 and 00.05, checked against the game +## 5. Butters' 00.04 and 00.05, checked against the game What his recorded version does, what went wrong with it on console B, and what replaced it. Our changes are on the fork branch @@ -77,7 +75,7 @@ on top of his segment 00 ([`bdsp/1717-seg00`](https://github.com/dayfine/Arduino | His version | What happened | Now | Our commits | |---|---|---|---| -| Every leg is a stick hold of a recorded length (00.05 alone is ~150 lines of them). | Drift, as in section 1. In r79 the 00.05 legs reached the Trainers' School, then "west 200 ms, A" faced an empty tile: Barry stands up and to the right, at the blackboard. | 00.04 walks map plans whose legs end at walls (design doc, sections 3 to 5). 00.05 is being stepped through (section 8 below). | [`1598fc2c7`](https://github.com/dayfine/Arduino-Source/commit/1598fc2c74e7cccf6356251bf35e21fdbcac5006), [`0a5311175`](https://github.com/dayfine/Arduino-Source/commit/0a5311175ec72feb0fcb326a38d7e2dc7b1ec673) | +| Every leg is a stick hold of a recorded length (00.05 alone is ~150 lines of them). | Drift, as in section 1. In r79 the 00.05 legs reached the Trainers' School, then "west 200 ms, A" faced an empty tile: Barry stands up and to the right, at the blackboard. | 00.04 walks map plans whose legs end at walls (design doc, sections 3 to 5). 00.05 is being stepped through (section 10 below). | [`1598fc2c7`](https://github.com/dayfine/Arduino-Source/commit/1598fc2c74e7cccf6356251bf35e21fdbcac5006), [`0a5311175`](https://github.com/dayfine/Arduino-Source/commit/0a5311175ec72feb0fcb326a38d7e2dc7b1ec673) | | Tristan is fought with move slot 3 (Ember). | Chimchar only; we had Piplup (r28). | The Fight menu is read by OCR and the strongest move picked. | [`c16ee0262`](https://github.com/dayfine/Arduino-Source/commit/c16ee0262772a5519e489fb9ad360d263d07852c), [`97df88c43`](https://github.com/dayfine/Arduino-Source/commit/97df88c439845600a02d0114478bb66d4b158ad5) | | No training, no healing before the Route 202 trainers. | A Lv5 Piplup with Pound fainted to Logan's Shinx (r72). | Three wild battles first (Piplup learns Water Gun), then Potions. | [`08a9fb7e0`](https://github.com/dayfine/Arduino-Source/commit/08a9fb7e01b6be5ee042708b89e32ca2149dca69), [`a95359311`](https://github.com/dayfine/Arduino-Source/commit/a953593111dba3d56b10cf995eb7e9c86455018d) | | The Potion is found in the Bag by a pixel match. | Console B's colours differ; the match failed (r27). | OCR of the item name. | [`50c9d955d`](https://github.com/dayfine/Arduino-Source/commit/50c9d955d44d767d58d45834dc7e8d3a1b0e6c65) | @@ -95,7 +93,36 @@ gives **10 Potions**. With them, healing needs no trip to the Pokémon Center: h after training, and after each trainer read the HP bar in the Bag and use a Potion under half. The run now gets the Potions first and saves on Route 202, (30,19), so later attempts skip her. -## 7. Our own mistakes in this round +## 6. Butters' segment 01, checked against what we found + +| His version | What we found | Rule | +|---|---|---| +| Oreburgh city, mine and gym are timed stick holds and d-pad tap counts. | The same drift as section 5; d-pad taps are one tile each only when the player already faces that way. | Walls and the map, not counts. | +| Roark in the mine: A once, then up to 30 s for his first box, B to advance. | Right to wait long and to advance with B. But A does nothing until Barry has been talked to at the gym door, which his route gets from the tour scene's mashed B. | Make the Barry talk an explicit step. | +| Gym: up 3, left 4, up 5, right 8, up 11, left 5, up 4, then A at Roark. | That path goes round both gym trainers; straight up meets both. | Worth keeping as a plan for the gym grid; the trainers' experience helps an under-levelled team, though. | +| "Barry 1 battle logic can be used here since the moves don't matter this early." | Moves matter against Roark: Pound does almost nothing to rock types, and the first two tries were lost. | Pick Water Gun by name; heal or switch before Cranidos. | + +## 7. Butters' route on console B, 2026-10-29 (r107 to r109) + +Two failures in today's runs came from #1717's own code rather than ours: + +| Run | What happened | Rule / fix | Commit | +|---|---|---|---| +| r108 | 00.01 "Failed to enter Date Change screen". | The clock pin walks the System Settings menu by position; with "Synchronize Clock via Internet" on, the date row is disabled and the walk lands on Time Zone. Turned the sync off on console B; dropping the pin is queued. | — | +| r108b | 00.04: A beside Mom started nothing. Two d-pad taps north from the door should have put us level with her; one did not move. | Same as section 1, now in the house: counted taps lose tiles. The door fixes the column, so face east and press A one row at a time going north until she answers. | `985de47c1` | + +# Part 2. For us: our code, our lab, our process + +## 8. Our own process + +- Look at the screen, then the code, before rerunning. Every run since r28 that failed in a new + way was explained by one screenshot. +- Put new code in its final module first; no copy-then-move PRs of our own code. +- Keep line endings as they are (CRLF files stay CRLF); compare `git diff --stat` with + `--ignore-cr-at-eol`. +- When a program is stuck or failing, stop it and close the game at once; don't let retries run. + +## 9. Our own mistakes in this round - **An optional step kept for two hours.** We spent ~15 runs making the Route 201 detour work before asking whether the story needs it. Rule: before automating an inherited @@ -126,12 +153,12 @@ The run now gets the Potions first and saves on Route 202, (30,19), so later att DP map of Jubilife matches the BDSP layout (school, Center, Mart, TV station, Pokétch Company, fountain park all where DP has them), so towns get a tile grid too, checked against the console, with the story NPCs on it. *Later (r82):* the grid's walls in the open plaza are not - where the game has them, so it is not good enough to plan on there; see section 9. + where the game has them, so it is not good enough to plan on there; see section 11. - **Not saying what we are doing.** The overlay and the log now print each checkpoint's steps, the current one and the next, and every status report starts with the current problem. ([`3cd874125`](https://github.com/dayfine/Arduino-Source/commit/3cd8741250dc03f1c166e15cfc9563f5ac36add9)) -## 8. Step through new ground before automating it +## 10. Step through new ground before automating it After hours of whole-run attempts at the lady, five minutes of stepping found her: the Lab Console takes 5 to 10 commands at a time (walk until stopped, a few presses, a screenshot), @@ -141,7 +168,7 @@ write the automated version from what was seen. 00.05 was done this way on 2026- coupon clowns, the Pokétch and the Center PC, about 60 batches, ending in a save at the PC (segment 0 complete). -## 9. Segment 01 to Oreburgh City (2026-10-28, r81 to r90) +## 11. Segment 01 to Oreburgh City (2026-10-28, r81 to r90) 01.01 (Jubilife Center to Barry) and 01.02 (Route 203, Oreburgh Gate, Oreburgh City) were stepped through by hand once, written from that ([`8dda984d5`](https://github.com/dayfine/Arduino-Source/commit/8dda984d5ca88a1d59b605a3312711162777bba7)), and then run on console B. Ten @@ -176,8 +203,7 @@ Also from these runs: battle), the walk out of the Center to the girls below the door, and Barry from the measured holds plus row search. - -## 10. Oreburgh Mine, Roark's gym and on to Floaroma (2026-10-28/29, r91 to r106, then by hand) +## 12. Oreburgh Mine, Roark's gym and on to Floaroma (2026-10-28/29, r91 to r106, then by hand) 01.03 (city → mine → Roark) was written from the parsed mine map (`devtools/maps/levels.py`) and run r91 to r106. After that the user asked to fight the gym as we were, gaining @@ -216,16 +242,7 @@ By hand, after 01.03: north through the grass to the flower beds, round the twins (a double battle), and north between the beds into Floaroma. The Center is a few tiles east of where we arrive. -### Butters' segment 01, checked against what we found - -| His version | What we found | Rule | -|---|---|---| -| Oreburgh city, mine and gym are timed stick holds and d-pad tap counts. | The same drift as section 6; d-pad taps are one tile each only when the player already faces that way. | Walls and the map, not counts. | -| Roark in the mine: A once, then up to 30 s for his first box, B to advance. | Right to wait long and to advance with B. But A does nothing until Barry has been talked to at the gym door, which his route gets from the tour scene's mashed B. | Make the Barry talk an explicit step. | -| Gym: up 3, left 4, up 5, right 8, up 11, left 5, up 4, then A at Roark. | That path goes round both gym trainers; straight up meets both. | Worth keeping as a plan for the gym grid; the trainers' experience helps an under-levelled team, though. | -| "Barry 1 battle logic can be used here since the moves don't matter this early." | Moves matter against Roark: Pound does almost nothing to rock types, and the first two tries were lost. | Pick Water Gun by name; heal or switch before Cranidos. | - -## 11. Floaroma MVP from a new game, and the lab around it (2026-10-29, r107 to r109) +## 13. Floaroma MVP from a new game, and the lab around it (2026-10-29, r107 to r109) The MVP branch (`bdsp/floaroma-mvp`, fork #68) runs segments 00 and 01 from a new game on the shared navigation core. Half of today's failures were in the lab, not in the game. @@ -234,8 +251,6 @@ the shared navigation core. Half of today's failures were in the lab, not in the |---|---|---|---| | r107 | Every program refused to start: "requires video feedback". The camera opened without error but delivered no frames. | Launch lab apps through LaunchServices (`open -n`), never by running the binary from a shell: the app then inherits the shell's (the Claude app's) camera permission, which has none. `stage_launch.sh` now checks for video before anything else. | lab scripts | | r107 | The MVP build stopped at run time on a missing template ("Unable to open file"). | The worktree's `Packages` linked to upstream's resource set (686 files); BDSP AutoStory needs `~/BDSPLab/packages` (1,467). The build copies `Resources` only when it is missing, so delete it after relinking. | r108 deployment | -| r108 | 00.01 "Failed to enter Date Change screen". | The clock pin walks the System Settings menu by position; with "Synchronize Clock via Internet" on, the date row is disabled and the walk lands on Time Zone. Turned the sync off on console B; dropping the pin is queued. | — | -| r108b | 00.04: A beside Mom started nothing. Two d-pad taps north from the door should have put us level with her; one did not move. | Same as section 1, now in the house: counted taps lose tiles. The door fixes the column, so face east and press A one row at a time going north until she answers. | `985de47c1` | | r109 | Mom answered after 1 step; then entering Sandgem the check read the banner as "andgemltown" and failed. | A check tied to an exact OCR string is too narrow (section 2): the place was right. Match banner names loosely, with a test that a different town still fails. | pending | | r109a | The run never started: the Start click landed where the button was before the window grew to 1554×1488. `stage_run.sh` would then have clicked Start/Stop "to stop the wrong program" and started an unwatched run. | Never toggle Start/Stop blindly: stop only when the log says RUNNING. Better, don't click at all: the lab app gets a control folder (`LabControl/start`, `stop`, `state`). Clicks also take focus from the user's work. | `lab/control-folder` | @@ -243,7 +258,7 @@ What this round adds to the design: - **Confirm where we are, not just where we planned to be.** The planner plans in tiles and the walker counts them, but nothing reads the position back; every drift so far (sections - 1, 6, 9, 10 and the Mom row here) was found only when the next action failed. After each + 1, 5, 11, 12 and the Mom row in section 7) was found only when the next action failed. After each leg, confirm with something the game shows (a wall reached, a landmark, a dialogue answered, the facing) and replan from the confirmed tile when it differs. - **Overworld screens belong in the screen machine.** The new-game intro runs on From 8ae6e69975562196b7f7c87889cfc2764326ec0e Mon Sep 17 00:00:00 2001 From: dayfine Date: Thu, 29 Oct 2026 22:22:56 -0700 Subject: [PATCH 24/24] AutoStory docs: mark the segment plans done or superseded, the #1717 drafts stale; pose status Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E --- docs/design/AutoStory-1717-review-drafts.md | 4 ++++ docs/design/AutoStory-Navigation-Stack.md | 13 +++++++++++++ docs/design/AutoStory-Segment00-Finish.md | 5 +++++ docs/design/AutoStory-Segment01-Plan.md | 4 ++++ 4 files changed, 26 insertions(+) diff --git a/docs/design/AutoStory-1717-review-drafts.md b/docs/design/AutoStory-1717-review-drafts.md index 9d134d7907..fb821023af 100644 --- a/docs/design/AutoStory-1717-review-drafts.md +++ b/docs/design/AutoStory-1717-review-drafts.md @@ -5,6 +5,10 @@ user, who decides whether to post them, and when. Each one stands on its own and makes no request beyond the fix. None of them proposes shared code or asks the BDSP team to restructure anything. +**Stale:** checked against PR head `65094d4cd` (2026-10-25); the head is now `45a206f0d` +(2026-10-29). Recheck every draft before posting. Lessons Part 1 (§1 to §7) holds the newer +findings for Butters. + Checked against PR head `65094d4cd` (2026-10-25). Before posting, check that the head has not moved (`gh pr view 1717 -R PokemonAutomation/Arduino-Source --json headRefOid`), and recheck the line numbers if it has. Paths are under diff --git a/docs/design/AutoStory-Navigation-Stack.md b/docs/design/AutoStory-Navigation-Stack.md index 35a3a5a59a..2493bbc126 100644 --- a/docs/design/AutoStory-Navigation-Stack.md +++ b/docs/design/AutoStory-Navigation-Stack.md @@ -78,6 +78,19 @@ Rule: the screen is read, the pose is tracked. A pose is never inferred from ela alone except for an open leg, and then it is marked inexact until a wall or a landmark fixes it. +**Status 2026-10-29: the pose is planned but not yet corrected.** The planner plans in tiles and +the walker counts them; nothing reads the pose back after a leg, so a dropped tap is found +only when the next action fails (00.04 r108b: two taps to Mom's row moved one tile; see +Lessons §7). Next, in the core: after each leg, confirm the pose with an anchor the game shows +(wall, landmark, dialogue answered, facing) and replan from the confirmed tile. FRLG's +overworld screens (overworld, dialogue, battle interrupt) should also become screen-machine +states, as BDSP's intro already is. + +Review follow-ups on the core (2026-10-29, fork #66/#67): the single-method `LegMover` becomes a +`MoveOnlyFunction` (fork `common/move-only-function`); `ScreenState`'s `matches`/`act` move +from `std::function` to `MoveOnlyFunction` too; `plan_legs` is split under 50 lines; FRLG's +`OverworldMap` (20 public methods) becomes plain data plus free functions. + ## 4. Branches and PRs ``` diff --git a/docs/design/AutoStory-Segment00-Finish.md b/docs/design/AutoStory-Segment00-Finish.md index 23b1168612..7c10810e9d 100644 --- a/docs/design/AutoStory-Segment00-Finish.md +++ b/docs/design/AutoStory-Segment00-Finish.md @@ -1,5 +1,10 @@ # AutoStory segment 00: what is left (scheduled after segment 01's first pass) +**Superseded 2026-10-29:** segment 00 now runs on the MVP branch `bdsp/floaroma-mvp` +(fork #68, on #1717 and the shared core); 00.00 to 00.03 passed unattended from a new game +(r108b) and 00.04 got past Mom (r109). Current results are in +[AutoStory-Lessons.md](AutoStory-Lessons.md) §7 and §13. Kept for the history below. + Status 2026-10-28. Code: fork branch `bdsp/new-game-intro-v2`, worktree `~/Projects/Arduino-Source-bdsp`, latest commit 6dbcc8e10 (00.05 on a Jubilife grid). Testing: the `bdsp-autostory-test` skill. diff --git a/docs/design/AutoStory-Segment01-Plan.md b/docs/design/AutoStory-Segment01-Plan.md index 4c2a7dae4c..a74407d901 100644 --- a/docs/design/AutoStory-Segment01-Plan.md +++ b/docs/design/AutoStory-Segment01-Plan.md @@ -1,5 +1,9 @@ # AutoStory segment 01 plan: Jubilife to the Coal Badge +**Done 2026-10-29:** 01.01 to 01.03 were built from this plan and run on the console +(r81 to r106; Lessons §11 and §12), and Floaroma was reached by hand. The MVP branch +`bdsp/floaroma-mvp` (fork #68) carries the code. Kept as the plan of record. + Status 2026-10-28: research done, nothing built yet. Companion to [AutoStory-Design.md](AutoStory-Design.md) (the pieces) and [AutoStory-Lessons.md](AutoStory-Lessons.md) (what went wrong in segment 00).