From a38973420116b32d3f8afa547b74cb7fe9915370 Mon Sep 17 00:00:00 2001 From: acamilo Date: Tue, 22 Sep 2026 12:43:52 +0000 Subject: [PATCH] geography: the Pewter museum is two rows on the map graph Rung 10 spent five and a half hours in Pewter City with the objective two doors away, and the fly kept ending up inside the museum, where GO OBJECTIVE, GO SHOP and GO HEAL were all off the pad: a map with no row in the graph has no neighbours, so next_hop answers nothing and area_of answers nothing. Named as a residual by the previous review and worked here. Both ids come from the cartridge's own warp table, surveyed from the rung-10 checkpoint rather than counted: Pewter City names 0x34 at (14, 7) and at (19, 5), which are the museum's two doors, and 0x34 names 0x35 at (7, 7), which is the staircase. The upper floor has no area, for the same reason a bedroom has none -- no front door of its own -- and the road out of it is the staircase, which is what the fly needs there. --- .../src/pokemon_red/macros/geography.rs | 42 +++++++++++++++++++ .../flybrain-gb/src/pokemon_red/maps.rs | 9 ++++ 2 files changed, 51 insertions(+) diff --git a/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs b/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs index f32c354..8abc285 100644 --- a/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs +++ b/services/flysim/crates/flybrain-gb/src/pokemon_red/macros/geography.rs @@ -112,6 +112,14 @@ const LINKS: &[(u8, u8)] = &[ (maps::VIRIDIAN_FOREST_NORTH_GATE, maps::ROUTE_2), (maps::VIRIDIAN_FOREST_NORTH_GATE, maps::VIRIDIAN_FOREST), (maps::PEWTER_GYM, maps::PEWTER_CITY), + // The museum, both floors. It is on the graph for the same reason the gym is: the rung-10 + // loop of 2026-09-22 spent its hours on these two maps with `GO OBJECTIVE` off the pad + // entirely, because a map with no row here has no neighbours, so `next_hop` answers nothing + // and `area_of` answers nothing -- no road to the gym from indoors, and no errand either. + // Both rows are the cartridge's own warp table, surveyed from the rung-10 checkpoint: Pewter + // City names `$34` at (14, 7) and (19, 5), and `$34` names `$35` at (7, 7). + (maps::PEWTER_MUSEUM_1F, maps::PEWTER_CITY), + (maps::PEWTER_MUSEUM_2F, maps::PEWTER_MUSEUM_1F), (maps::PEWTER_MART, maps::PEWTER_CITY), (maps::PEWTER_POKECENTER, maps::PEWTER_CITY), (maps::MT_MOON_1F, maps::ROUTE_3), @@ -551,6 +559,40 @@ mod tests { ); } + #[test] + fn the_museums_two_floors_know_the_road_to_the_gym() { + // The rung-10 loop of 2026-09-22: five and a half hours on `PEWTER_CITY` with the + // objective two doors away, and inside the museum `GO OBJECTIVE` was off the pad because + // the map had no row here at all. Both floors, because the fly spent the run on both. + let at = |map: u8| Region::whole(map); + assert_eq!( + next_hop(at(maps::PEWTER_MUSEUM_1F), maps::PEWTER_GYM), + Some(maps::PEWTER_CITY), + "the way to the gym from the museum's ground floor is out of its front door" + ); + assert_eq!( + next_hop(at(maps::PEWTER_MUSEUM_2F), maps::PEWTER_GYM), + Some(maps::PEWTER_MUSEUM_1F), + "and from the upper floor it is the staircase" + ); + assert_eq!(next_hop(at(maps::PEWTER_CITY), maps::PEWTER_GYM), Some(maps::PEWTER_GYM)); + // The other direction, which is what `GO OBJECTIVE` asks when the errand is the museum's + // own town: the museum is one hop from Pewter City and two from its upper floor. + assert_eq!( + next_hop(at(maps::PEWTER_CITY), maps::PEWTER_MUSEUM_2F), + Some(maps::PEWTER_MUSEUM_1F) + ); + // And the area, which is what puts the town's errands on the pad indoors. The upper + // floor has no area, exactly as `REDS_HOUSE_2F` has none: a floor with no front door of + // its own is not "in" anywhere, so it offers no errand -- and the road out is still the + // staircase above, which is what the fly needs there. + assert_eq!(area_of(maps::PEWTER_MUSEUM_1F), Some(maps::PEWTER_CITY)); + assert_eq!(area_of(maps::PEWTER_MUSEUM_2F), None); + // The museum is neither a mart nor a centre, so it is nobody's errand. + assert_eq!(amenity_at(maps::PEWTER_MUSEUM_1F), None); + assert_eq!(amenity_at(maps::PEWTER_MUSEUM_2F), None); + } + #[test] fn a_maps_area_is_its_town_indoors_and_out() { // Outdoors a map is its own area, including a route -- which has no amenity row, so it diff --git a/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs b/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs index 986b6f4..fd1b4e8 100644 --- a/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs +++ b/services/flysim/crates/flybrain-gb/src/pokemon_red/maps.rs @@ -18,6 +18,13 @@ //! `PEWTER_MART` `$38` and `PEWTER_POKECENTER` `$3a` sit in the five ids between `PEWTER_GYM` //! `$36` and `MT_MOON_1F` `$3b`; `CERULEAN_POKECENTER` `$40` and `CERULEAN_MART` `$43` sit around //! `CERULEAN_GYM` `$41`. [`super::tests`] pins each against its neighbour rather than on its own. +//! +//! **2026-09-22, the rung-10 museum.** `PEWTER_MUSEUM_1F` `$34` and `PEWTER_MUSEUM_2F` `$35` are +//! the two ids between `VIRIDIAN_FOREST` `$33` and `PEWTER_GYM` `$36`, and both are confirmed by +//! the cartridge rather than by counting: Pewter City's warp table names `$34` at (14, 7) and at +//! (19, 5) -- the museum's two doors -- and `$34`'s own warp at (7, 7) names `$35`, which is the +//! staircase. Surveyed from the release container's rung-10 checkpoint +//! (`infra/docs/macros-traps.md`, 2026-09-22). // Outdoors: `$00`..`$24`. pub const PALLET_TOWN: u8 = 0x00; @@ -68,6 +75,8 @@ pub const VIRIDIAN_GYM: u8 = 0x2d; pub const VIRIDIAN_FOREST_NORTH_GATE: u8 = 0x2f; pub const VIRIDIAN_FOREST_SOUTH_GATE: u8 = 0x32; pub const VIRIDIAN_FOREST: u8 = 0x33; +pub const PEWTER_MUSEUM_1F: u8 = 0x34; +pub const PEWTER_MUSEUM_2F: u8 = 0x35; pub const PEWTER_GYM: u8 = 0x36; pub const PEWTER_MART: u8 = 0x38; pub const PEWTER_POKECENTER: u8 = 0x3a;