Repository navigation
Conversation
The red arrow drawn over the bag's top frame once the pocket list is scrolled down made the check fail, so open_bag_from_overworld() never saw the bag open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Per-tile collision, elevation and the behaviours that matter for walking, plus warps, objects and map connections, generated from the pret/pokefirered decompilation (Cerulean City, its Pokemon Center, Route 24 and Cerulean Cave for now). OverworldMap's step checks follow the game's collision rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
FRLG's step rules (doors, cave mouths, ladders, exit mats, map edges, Surf, elevation) as a step model for Pokemon::plan_legs(). Tests plan from Cerulean City to Mewtwo and check the steps replay on the maps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Compares the centre of the screen, where the camera keeps the player, with the standing sprites from pokefirered, on the sprite's own pixels only. Tested on LeafGreen captures on Route 24 and in Cerulean Cave. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
A D-pad mover and FRLG's interrupts for Pokemon::walk_leg(): a wild battle seen by its opening flashes (or, late, by its screen), and a message, optionally followed by another Max Repel. Warps are waited out by their fade; Surf goes through its dialog. The facing at the start is read from the screen when not given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Brings in the callable leg mover and the split leg planner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The leg walker now takes its mover as a callable, so DpadMover becomes hold_dpad(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
OverworldMap had 20 public methods, all reads of its tiles. It is now a struct of the checked map, and make_overworld_map() and the tile queries are free functions. The checks in the constructor are split into known_terrain(), elevation_level() and add_row(). The tile rules are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
all_maps() held every map's data in one 500-line function. Each map is now a MapText constant, and all_maps() lists them. The map data is unchanged apart from its indentation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
plan_overworld_route() was 59 lines. Converting the costs and each leg now has a function of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Picks up the MoveOnlyFunction test fix for MSVC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Brings in fork main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
frlg_maps.py reads maps from pret/pokefirered at a pinned commit and writes one JSON file per map for Packages' Resources/PokemonFRLG/Maps. For the six Cerulean maps its output matches the map data compiled in so far, field for field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The map data moves out of the source into Packages, one file per map at Resources/PokemonFRLG/Maps/<name>.json. MapData is the map as the file holds it, and the tile queries work on it directly; load_map() reads a file once and names the map and field when one is wrong. Objects' name becomes kind, as in the files. Upstream Packages doesn't have the maps yet, so the route tests on the Cerulean maps skip when the files are missing. A new route test plans across two small maps given as JSON in the test, and parser tests cover a valid map, a missing field, a field of the wrong type, a short row, an unknown tile and broken JSON. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
| // 's' can't be entered moving north or left moving south | ||
| // 'e' can't be entered moving west or left moving east | ||
| // 'w' can't be entered moving east or left moving west | ||
| std::vector<std::string> tiles; |
There was a problem hiding this comment.
we should define a type for this
There was a problem hiding this comment.
Added a Tile enum and a small Grid<T> (width, height, at(pos)); tiles and elevation are parsed into them once (c8eab23).
| // What decides where the player's next step can go. | ||
| struct PlayerState{ | ||
| TilePos position; | ||
| uint8_t elevation = 3; |
There was a problem hiding this comment.
Named it ELEVATION_GROUND with a comment on what elevation 3 means in pokefirered (3731be9).
| // way to Cerulean Cave: its guard, the rival and the Rocket in Cerulean City. | ||
| const std::set<std::string>& post_game_flags(); | ||
|
|
||
| // Where the player stands after entering Cerulean Cave from Cerulean City (1F). |
There was a problem hiding this comment.
should these be part of the map data?
There was a problem hiding this comment.
Yes: the Cerulean Cave points and the post-game flag set now live in the map JSON as named points and flag sets, read with map_point() / map_flag_set() (e90d70b).
|
|
||
|
|
||
| enum class RouteAction{ | ||
| WALK, // hold `direction` for `tiles` tiles |
There was a problem hiding this comment.
Not yet. Biking needs a movement mode on PlayerState/RouteStep, its own tile time in the walker, and a per-tile cost; it comes with the Brock route if we bike there.
| std::optional<Direction> facing; | ||
| }; | ||
|
|
||
| struct RouteCosts{ |
There was a problem hiding this comment.
should this be a map keyed by an enum? feels like it should not be a struct (type) but just a data strcuture
There was a problem hiding this comment.
Now data: std::map<RouteCost, int> keyed by a cost-kind enum, with defaults (2835948).
| // west mirrored. | ||
|
|
||
| // Standing, facing south. | ||
| const char* const SOUTH[] = { |
There was a problem hiding this comment.
The sprite now loads from the decomp PNG as a resource (PlayerSprites/red_normal.png); tests use a small embedded fixture (362699b).
Review: the tile rows were strings of legend characters. The loader now reads them once into a Grid<Tile> and a Grid<uint8_t> of elevations, naming the row and tile it can't read, and the tile queries compare Tile values. The one-way tiles become CLOSED_NORTH and so on, after the edge they close. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Review: PlayerState's elevation defaulted to a bare 3. The game's elevation constants move into the map header with what each means, and the default is ELEVATION_GROUND. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Review: the cave entrance, Mewtwo's tile, the PC tile and the Hall of Fame flags were constants in code. They are now points and flag sets in the map files, written by the generator from a short table, and map_point() and map_flag_set() look them up by name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Review: RouteCosts was a struct of one int per kind of cost. It is now a std::map from a RouteCost enum, with the defaults in default_route_costs(); a map that leaves a kind out gets its default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Review: the standing frames were hex strings in the source. The reader now loads red_normal.png from Packages once and compares its opaque pixels, as before. match_player_facing() takes the sprites, so a new test checks the matching with made-up sprites when the sheet isn't there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The generator also writes Pallet Town through Pewter City, with side stairs as exit mats (they warp the same way) and the story's named points. overworld_maps() loads them, and new route tests plan from the bedroom to Oak's Lab and from the Viridian Mart counter through Viridian Forest to Pewter Gym. Like the Cerulean ones, they skip when Packages doesn't have the maps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
GCC 14 warned that the array read_array() returns for a temporary "flags" string might dangle, which the Ubuntu build treats as an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The screenshots and the sprite sheet aren't in CI's resources yet, so those tests now skip instead of failing; the made-up sprites test still checks the matching there. 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
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
LegMover was an alias for a MoveOnlyFunction; a class with one virtual hold() (as the BDSP copy has) needs no callable wrapper, so the walker can leave the shared core and come along with FRLG without #72. FRLG's D-pad mover becomes DpadMover. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
The core now holds only Grid and the leg planner. The leg walker, with its tests and build lines, stays here as FRLG's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E
Depends on #66. Includes #65's commit.
FRLG overworld navigation on the shared core: maps generated from pokefirered (the Cerulean area for now), routes planned with the shared leg planner on FRLG's step rules (doors, ladders, exit mats, map edges, Surf, elevation), the leg walker (moved here from #66 as FRLG's own, with
LegMovera small abstract class instead of aMoveOnlyFunctionalias, so nothing here needs #72) holding the D-pad with wild-battle, message and Max Repel interrupts, and a reader for which way the player faces. Route tests, walker tests and facing-reader tests pass; the six facing images are local only and still need to go into CommandLineTests. The same walker walked Route 24 to Mewtwo on console B before it moved onto the core, and needs that run again. This is the base for the Brock MVP, a new game to the Boulder Badge.🤖 Generated with Claude Code
https://claude.ai/code/session_01AKYzhrMnPK61XHWEch4a6E