Skip to content

FRLG walker: encounters and obstacles (wild steps across maps, late battles, warp fades vs battles, signs and ledges) - #118

Draft
dayfine wants to merge 40 commits into
frlg/mvpfrom
frlg/walk-wild-legs
Draft

dayfine wants to merge 40 commits into
frlg/mvpfrom
frlg/walk-wild-legs

Conversation

@dayfine

@dayfine dayfine commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Depends on #117.

#117's routes need something that walks them on the console and copes with whatever stops the player. This adds the FRLG overworld walker: it walks a route leg by leg with #114's leg walker, checks that no menu or message is open before each step, waits out warps and tells a warp's fade from a wild battle's, starts Surf, and clears wild battles and messages on the way, watching for battles only on steps that can start one; the battle flash watcher and the battle screen detector it needs come with it. Its timings and step helpers are declared in OverworldWalkSteps so #119 builds on them instead of copying them. It has no unit tests beyond the shared LegWalker's; fork CI builds it on Mac, Windows Clang and Ubuntu, and it walked every route from a new game to Viridian Forest on console B on 2026-11-01.

The walker also runs: walk_overworld_route() takes a MoveSpeed (WALK by default), and RUN holds B with the D-pad at 133 ms a tile, logging [Speed] run <dir>: N tiles in T ms, held H ms for each leg to a wall (tested in the new OverworldWalk suite).

🤖 Generated with Claude Code

https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E

dayfine and others added 2 commits November 1, 2026 00:27
Each route step says whether it crosses tall grass or water. The walker
watches for a wild battle's flash only there; elsewhere it watches for
messages alone. On console B the walk east to the bedroom's wall stopped
on a false battle: the screen darkened at the edge of the small room like
a battle's flash, and fleeing failed five times.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
FireRed shows a sign's message to a player who walks into it moving north
or south (TrySetUpWalkIntoSignpostScript() in pokefirered). The maps now
mark signs ('S': signposts with a sign event, Center, Mart and Indigo
Plateau signs), and the planner no longer counts on one to stop a leg. On
console B, the walk north to the bedroom's wall read the poster above it,
and walking to the wall again read it again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Brings in nav/shared (#114) through #117.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
…count

Brings in nav/shared (#114) through #117 and #118, including the planner's wild-step weighting (7008f8c), which moved there from this branch's b4d1976.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
…-mvp

#119 now has nav/shared (#114) through #117 and #118, so this PR's diff shows only its own files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
LegPlanner's wild-step weighting moved from #119 to #114 (7008f8c) and merged down #117 → #118 → #119 → #120; #120's diff is PokemonFRLG only. Adds #119, #120, #121 to the tree and a file-ownership table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits November 1, 2026 09:30
CI has no map files in Packages, so the route tests on real maps were
skipped there. PokemonFRLG_OverworldMapsTestData.cpp holds the 25 maps of
Resources/PokemonFRLG/Maps as frlg_maps.py --cpp writes them, the same text
as the Packages files, and test_overworld_maps() reads them as
overworld_maps() reads the files. The route tests use it and no longer skip
on a missing file. `frlg_maps.py --cpp <file> --check` checks the file
against a fresh generation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
The re-anchor tests and the ledge route test planned on overworld_maps(),
so CI, which has no Packages maps, skipped them. They now use
test_overworld_maps() (#118), the same maps compiled into the program.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 1, 2026
The route and chain tests planned on story_maps(), read from Packages, so CI
skipped them; the gym test had its own trimmed copies of three Pewter maps.
All of them now plan on test_overworld_maps() (#118) with the Hall of Fame
flags story_maps() uses: one copy of each map, the generator's, checked
against it by frlg_maps.py --check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 4 commits November 1, 2026 09:34
A leg's wild flag was worked out from the tiles on its start map only, so
"north 22" from Pallet Town, through Route 1's grass beyond the map's
edge, was walked without watching for battles (console B, 2026-11-01).
It now comes from the planner's per-step wild flag (#114), set on tall
grass and water. The wild-steps route test checks that leg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
A leg to a wall is held two tiles longer than it takes, so a ledge the plan
took for a wall was hopped: in Viridian City "south 2 (to wall)" from the
Pokemon Center ended on (26, 31), below the ledge, not on (26, 29), and
every later leg was off (console B, 2026-11-01). The maps don't record
which way a ledge faces, so a leg now never ends held into any ledge; it
counts its tiles instead. Tested on a small yard and on Viridian City.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Run 7 on console B (2026-11-01, Route 1) lost a whole leg twice. A battle
on a leg's last grass step had its flashes missed; its "Wild ...
appeared!" showed 3.7s after that press, by which time the next leg,
off the grass and so not watched for battles, had been walked into the
battle without moving the player. After a leg through grass the walker
now watches 3.5s, not 0.5s, for a battle before the next leg, and a battle
seen only by its dialog is placed 3.7s back, as measured, not 2s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
In run 7 (console B, 2026-11-01) the player had drifted onto Route 1's
grass, and the step meant for Oak's Lab's door set off a wild battle. Its
flashes and wipe passed for the warp's fade, and the route went on as if
inside. After a warp's fade the walker now watches 5s for a battle screen;
if one shows, it flees and fails with "a wild battle, not the warp to
...: the player is off the route", for the caller to re-plan.

A battle screen is BattleScreenDetector: the battle menu, or the battle
text box together with an HP box. The text box alone also reads on the
black below a small indoor map (Oak's Lab's mat, Viridian Forest's north
gate), where the walker tried to flee battles that weren't there. The
late-battle and trainer-battle watches use it too. The detector is moved
here unchanged from #120 (ac1873b), where it was added for the story's
battles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
@dayfine dayfine changed the title FRLG walker: watch for wild battles only on wild steps; never hold into a sign FRLG walker: encounters and obstacles (wild steps across maps, late battles, warp fades vs battles, signs and ledges) Nov 1, 2026
dayfine and others added 5 commits November 1, 2026 09:38
…rogram

Overworld/Maps holds the 25 maps as frlg_maps.py writes them, the same
files as Resources/PokemonFRLG/Maps in Packages (check them with
`frlg_maps.py --out <Maps folder> --check`). CMake builds their text into
the program (pa_embed_text_files()), as overworld_map_json(), so tests can
plan on them without Packages.

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

test_overworld_maps() now parses overworld_map_json(), the Maps/*.json files
CMake builds in, so PokemonFRLG_OverworldMapsTestData.{h,cpp}, the copy
frlg_maps.py --cpp wrote, goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Until the maps go to Packages, overworld_maps() reads them from
overworld_map_json(), the Maps/*.json files CMake builds in, instead of
Resources/PokemonFRLG/Maps. The program and its tests read one copy, a
deploy needs no map files, and the tests call overworld_maps() again, so
test_overworld_maps() and PokemonFRLG_OverworldTestMaps.{h,cpp} go. TODOs at
overworld_map_json() and in frlg_maps.py: move the maps to Packages when
ready.

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

Conflicts: #118 now has the fixes this branch carried (conservative
ledges, cross-map wild steps, the late-battle wait, the warp-vs-battle
check on BattleScreenDetector); its versions are taken, and this branch
keeps its route loop.
dayfine added a commit that referenced this pull request Nov 1, 2026
plan_reanchor() widened the tiles the player may be on to 4 either side of
the stopped leg, and when no holds found them from all of those it tried
3, 2, 1 and 0. Failing to find holds is no reason to think the player is
closer to the line, so the set is now fixed.

It is the leg's own tiles. Measured on the compiled-in maps, with even one
tile to either side Route 1's people and ledges cut some hold for some
tile, and no open leg through its grass could be recovered; on the leg's
line every one of them can (both route tests). Sideways drift, as in run 16
on console B, is not recovered: there, a hold that meets a sign at once,
again and again, now fails the route instead of guessing (next commit).
The sign lookup that went with the wider set is removed.

Recovery holds take a ledge to stop a player moving north: FRLG's ledges
face south, east or west on every map loaded (pokefirered has no
MB_JUMP_NORTH there), and Route 1 has no other walls on most of its legs.
Planned routes still never hold into a ledge (#118). The maps don't
record which way a ledge faces; recording it would let this go.

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

The maps are now built into the program; the re-anchor tests read them
with overworld_maps().
dayfine added a commit that referenced this pull request Nov 1, 2026
…-mvp

OverworldWalk.cpp: #119 no longer needs BattlePokemonDetector.h; its
battle watchers are BattleScreenWatcher now. AutoStory_Tests plan on
story_maps() again: overworld_maps() reads the maps built in from
Overworld/Maps (#118), so test_story_maps() and the TestData include go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits November 1, 2026 10:01
12 of the 25 maps drop their elevation grid (#117): 104 KB to 89 KB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 3 commits November 1, 2026 14:17
The shared LegMover is now a callable (#114): the D-pad hold is a plain
function. Reading the player's facing at the start of a route moves into
read_facing(), keeping walk_overworld_route() under the function size
limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
@dayfine dayfine added autostory AutoStory programs game:frlg FireRed/LeafGreen navigation Maps, planner, walker labels Nov 1, 2026
…hema) into frlg/walk-wild-legs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 2, 2026
…emon::MapData schema) into frlg/walk-interrupt-recount

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 2 commits November 2, 2026 01:41
…k-wild-legs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Visibility only: the timings and the step helpers (turn, hold, warp,
Surf, the overworld and warp checks) move out of the unnamed namespace
into OverworldWalkSteps, declared in the header, so a walker that runs a
route its own way (#119's position recovery) reuses them instead of
copying them. No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 2, 2026
…lk with recovery in its own file

#118's walk_overworld_route() is left as it is: the route walk that finds
the player again moves out of PokemonFRLG_OverworldWalk.cpp/.h, which
#118 owns, into walk_overworld_route_with_recovery() in the new
PokemonFRLG_OverworldRecoveryWalk.cpp/.h, built on #118's
OverworldWalkSteps. The route wall holds this PR added to
PokemonFRLG_OverworldRoute.cpp/.h now come from #117. The code is the
same; the conflict in OverworldWalk.cpp is resolved to #118's version.

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

#119 moved the route walk that finds the player again out of #118's
walk_overworld_route() into its own function; the story's ROUTE and LEGS
steps call it with the same planning as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine and others added 3 commits November 2, 2026 07:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
walk_overworld_route() takes a MoveSpeed (WALK by default). RUN holds B
with the D-pad for each leg's whole hold and times it at 133ms a tile
(8 frames); turn taps stay without B. Each leg to a wall logs
"[Speed] <walk|run> <dir>: N tiles in T ms, held H ms" so a console run
can check the pace. Unit tests for the hold times and that line.

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

# Conflicts:
#	SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Tests.cpp
dayfine added a commit that referenced this pull request Nov 2, 2026
dayfine and others added 6 commits November 2, 2026 12:58
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
A trainer who saw the player can speak after the leg's watch has ended
(console B, 2026-11-02, Route 3's Lass Robin), and check_overworld() then
failed the walk at once. clear_open_message() gives what shows to the
leg's interrupts once (StoryMessage fights the trainer); check_overworld()
still fails if the overworld isn't back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
…into frlg/walk-wild-legs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
dayfine added a commit that referenced this pull request Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autostory AutoStory programs game:frlg FireRed/LeafGreen navigation Maps, planner, walker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant