Files
gen1recomp/docs/gold-walkthrough/asm-walk/section-27-cinnabar-island-and-seafoam-islands-gym.md
T
bryanthaboi ae6cac89e1 G2 support
2026-08-11 11:53:30 -04:00

36 KiB

Section 27 - Cinnabar Island and Seafoam Islands Gym

Source: ../section-27-cinnabar-island-and-seafoam-islands-gym.txt (the FAQ numbers this chapter "33 > Cinnabar Island and Seafoam Islands Gym"; the file index is 27)

Maps covered: MAP_ROUTE_21, MAP_CINNABAR_ISLAND, MAP_CINNABAR_POKECENTER_1F, MAP_ROUTE_20, MAP_SEAFOAM_GYM

Badges / key milestones in this section:

  • ENGINE_FLYPOINT_CINNABAR (set on first entry to Cinnabar Island)
  • Blue's one-off speech on Cinnabar Island, which is what unlocks him in Viridian Gym (clearevent EVENT_VIRIDIAN_GYM_BLUE)
  • Hidden RARE_CANDY on Cinnabar Island
  • EVENT_CINNABAR_ROCKS_CLEARED (set silently by walking onto Route 20; this is what clears the boulders that seal Route 19 to the east)
  • VOLCANOBADGE from BLAINE in the Seafoam Islands cave (ENGINE_VOLCANOBADGE, EVENT_BEAT_BLAINE)

1. Route order

# Map constant asm file Enter via Leaves via Why (walkthrough beat)
0 PALLET_TOWN - - south connection to ROUTE_21 (data/maps/attributes.asm:270-272) Pallet Town belongs to the previous section; only the hop south is listed here.
1 ROUTE_21 maps/Route21.asm north connection from PALLET_TOWN (data/maps/attributes.asm:274-275) south connection to CINNABAR_ISLAND (attributes.asm:277) Surf south. Three trainers: Nikki, Arnold, Seth
2 CINNABAR_ISLAND maps/CinnabarIsland.asm north connection from ROUTE_21 (attributes.asm:279-280) warp 1 at (11,11) -> CINNABAR_POKECENTER_1F 1; east connection to ROUTE_20 (attributes.asm:281) Sets ENGINE_FLYPOINT_CINNABAR; heal; talk to Blue; hidden RARE_CANDY
3 CINNABAR_POKECENTER_1F maps/CinnabarPokecenter1F.asm Cinnabar warp 1 warps 1/2 at (3,7)/(4,7) back to CINNABAR_ISLAND 1 Heal; the two flavour NPCs the walkthrough quotes ("a year since the volcano erupted", "BLAINE lives alone in the SEAFOAM ISLANDS cave")
4 ROUTE_20 maps/Route20.asm west connection from CINNABAR_ISLAND (attributes.asm:283-284) warp 1 at (38,7) -> SEAFOAM_GYM 1 MAPCALLBACK_NEWMAP sets EVENT_CINNABAR_ROCKS_CLEARED; Swimmer Cameron at (12,13)
5 SEAFOAM_GYM maps/SeafoamGym.asm Route 20 warp 1 warp 1 at (5,5) back to ROUTE_20 1 BLAINE -> VOLCANOBADGE

Spillover: Route 20 continues east past the gym to Swimmer Lori (45,13) and Swimmer Nicole (52,8) and then over the connection east, Route19, ROUTE_19, -9 boundary into Fuchsia territory; the walkthrough does not visit them here and they belong to the following section.


2. Maps

MAP_ROUTE_21

  • Script: maps/Route21.asm
  • Blocks: maps/Route21.blk
  • Header: data/maps/maps.asm:198 -> TILESET_KANTO, ROUTE, LANDMARK_ROUTE_21, MUSIC_ROUTE_3, FALSE (phone calls allowed), PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:182 map_const ROUTE_21, 10, 18 (group CINNABAR = 6, map id 7). 10x18 blocks = 20x36 tile coordinates.
  • Attributes / border: data/maps/attributes.asm:274 map_attributes Route21, ROUTE_21, $43
  • Connections: north PALLET_TOWN (offset 0), south CINNABAR_ISLAND (offset 0)
  • Landmark position: data/maps/landmarks.asm:96 landmark 52, 120, Route21Name

Warps (def_warp_events)

None (def_warp_events at maps/Route21.asm:95 is empty).

Coord events (def_coord_events)

None (maps/Route21.asm:97).

BG events (def_bg_events)

None (maps/Route21.asm:99).

Object events (def_object_events, maps/Route21.asm:101-104)

const sprite x y movement type sight script label event flag
ROUTE21_SWIMMER_GIRL SPRITE_SWIMMER_GIRL 11 16 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 3 TrainerSwimmerfNikki -1 (always)
ROUTE21_SWIMMER_GUY SPRITE_SWIMMER_GUY 2 30 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 4 TrainerSwimmermSeth -1 (always)
ROUTE21_FISHER SPRITE_FISHER 14 22 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 1 TrainerFisherArnold -1 (always)

The walkthrough's order (Nikki, then the fisherman, then "head way left then down") is exactly the y ordering 16 -> 22 -> 30, with Seth in the far south-west corner at x=2.

Scripts of interest

  • TrainerSwimmerfNikki (maps/Route21.asm:22, sym 4e:4803) - trainer SWIMMERF, NIKKI, EVENT_BEAT_SWIMMERF_NIKKI, SwimmerfNikkiSeenText, SwimmerfNikkiBeatenText, 0, .Script. The 0 is the loss-text slot (no whiteout text). .Script is endifjustbattled + one after-battle line; no items, no flags beyond the beat flag.
  • TrainerFisherArnold (maps/Route21.asm:33, sym 4e:4817) - same shape, EVENT_BEAT_FISHER_ARNOLD.
  • TrainerSwimmermSeth (maps/Route21.asm:11, sym 4e:47ef) - same shape, EVENT_BEAT_SWIMMERM_SETH.

There are no scene scripts and no callbacks on this map (def_scene_scripts / def_callbacks at maps/Route21.asm:7-9 are both empty).

Flags and events

constant defined in read/written by meaning for a bot
EVENT_BEAT_SWIMMERF_NIKKI constants/event_flags.asm:490 trainer macro row, maps/Route21.asm:23 set once Nikki is beaten; suppresses re-battle
EVENT_BEAT_FISHER_ARNOLD constants/event_flags.asm:587 maps/Route21.asm:34 as above
EVENT_BEAT_SWIMMERM_SETH constants/event_flags.asm:958 maps/Route21.asm:12 as above

Items

None on this map.

Trainers

const class id party (data/trainers/parties.asm) script label rematch/phone
SWIMMERF, NIKKI SWIMMERF ($27) 17 ; SWIMMERF (17) at parties.asm:1872: L28 SEEL, L28 SEEL, L28 SEEL, L28 DEWGONG (TRAINERTYPE_NORMAL) TrainerSwimmerfNikki no
FISHER, ARNOLD FISHER ($25) 3 ; FISHER (3) at parties.asm:1511: L34 TENTACRUEL TrainerFisherArnold no
SWIMMERM, SETH SWIMMERM ($26) 18 ; SWIMMERM (18) at parties.asm:1754: L29 QUAGSIRE, L29 OCTILLERY, L32 QUAGSIRE TrainerSwimmermSeth no

Payouts (base reward x last-mon level x 4, see section 3 for the citation): Nikki 5 x 28 x 4 = 560, Arnold 10 x 34 x 4 = 1360, Seth 2 x 32 x 4 = 256. All three match the walkthrough exactly. Base rewards: data/trainers/attributes.asm:223 (Fisher, 10), :229 (Swimmerm, 2), :235 (Swimmerf, 5).

Wild encounters

  • Water (data/wild/kanto_water.asm:61-66), 6% rate: L35 TENTACOOL / L30 TENTACOOL / L35 TENTACRUEL.
  • Grass (data/wild/kanto_grass.asm:1005-1031), 6/6/6% morn/day/nite. There is a grass table, on the small land tiles:
    • morn: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 30 TANGELA, 28 MR__MIME, 28 MR__MIME
    • day: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 28 MR__MIME, 30 MR__MIME, 30 MR__MIME
    • nite: 30 TANGELA, 25 TANGELA, 35 TANGELA, 20 TANGELA, 30 TANGELA, 28 MR__MIME, 28 MR__MIME
  • Fishing: FISHGROUP_OCEAN (data/wild/fish.asm:13). Old rod .Ocean_Old (:42) MAGIKARP/MAGIKARP/TENTACOOL L10; Good rod .Ocean_Good (:46) MAGIKARP L20 / TENTACOOL L20 / CHINCHOU L20 / time_group 2 = SHELLDER L20 day and nite (fish.asm:214); Super rod .Ocean_Super (:51) CHINCHOU L40 / time_group 3 = SHELLDER L40 (fish.asm:215) / TENTACRUEL L40 / LANTURN L40.
  • No headbutt tree rows and no rock smash on this map.

MAP_CINNABAR_ISLAND

  • Script: maps/CinnabarIsland.asm
  • Blocks: maps/CinnabarIsland.blk
  • Header: data/maps/maps.asm:199 -> TILESET_KANTO, TOWN, LANDMARK_CINNABAR_ISLAND, MUSIC_VIRIDIAN_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:183 map_const CINNABAR_ISLAND, 10, 9 (group CINNABAR = 6, map id 8). 20x18 tile coordinates.
  • Attributes / border: data/maps/attributes.asm:279 map_attributes CinnabarIsland, CINNABAR_ISLAND, $43
  • Connections: north ROUTE_21 (offset 0), east ROUTE_20 (offset 0)
  • Landmark: data/maps/landmarks.asm:95 landmark 52, 132, CinnabarIslandName
  • Fly / respawn point: data/maps/flypoints.asm:28 db LANDMARK_CINNABAR_ISLAND, SPAWN_CINNABAR; data/maps/spawn_points.asm:24 spawn CINNABAR_ISLAND, 11, 12

Warps (def_warp_events, maps/CinnabarIsland.asm:131-132)

idx x y destination map dest warp
1 11 11 CINNABAR_POKECENTER_1F 1

Coord events (def_coord_events)

None (maps/CinnabarIsland.asm:134). Blue is a talk-to NPC, not a trip-wire.

BG events (def_bg_events, maps/CinnabarIsland.asm:136-140)

x y type script/item
12 11 BGEVENT_READ CinnabarIslandPokecenterSign -> jumpstd PokecenterSignScript
9 11 BGEVENT_READ CinnabarIslandGymSign -> "CINNABAR GYM has relocated to SEAFOAM ISLANDS. BLAINE"
7 7 BGEVENT_READ CinnabarIslandSign -> town sign
9 1 BGEVENT_ITEM CinnabarIslandHiddenRareCandy -> hiddenitem RARE_CANDY, EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY (sym 4e:49a2)

Object events (def_object_events, maps/CinnabarIsland.asm:142-143)

const sprite x y movement type sight script label event flag
CINNABARISLAND_BLUE SPRITE_BLUE 9 6 SPRITEMOVEDATA_SPINRANDOM_SLOW OBJECTTYPE_SCRIPT 0 CinnabarIslandBlue EVENT_BLUE_IN_CINNABAR

Scripts of interest

  • CinnabarIslandFlypointCallback (maps/CinnabarIsland.asm:10, sym 4e:4981), wired as callback MAPCALLBACK_NEWMAP at :8. Body is exactly setflag ENGINE_FLYPOINT_CINNABAR / endcallback. Walking in once is the whole unlock for flying here.
  • CinnabarIslandBlue (maps/CinnabarIsland.asm:14, sym 4e:4985). Control flow, in order: faceplayer, opentext, writetext CinnabarIslandBlueText, waitbutton, closetext, playsound SFX_WARP_TO, applymovement CINNABARISLAND_BLUE, CinnabarIslandBlueTeleport, disappear CINNABARISLAND_BLUE, clearevent EVENT_VIRIDIAN_GYM_BLUE, end.
    • There is no guard flag and no iftrue at the top: the script is one-shot only because disappear sets the object's own EVENT_BLUE_IN_CINNABAR (see Script_disappear at engine/overworld/scripting.asm:887, ld b, 1 ; set).
    • CinnabarIslandBlueTeleport (:38) is a two-byte movement stream: teleport_from ($4c, macros/scripts/movement.asm:148) then step_end. That is the "levitates and flies off" the walkthrough describes.
    • clearevent EVENT_VIRIDIAN_GYM_BLUE is the load-bearing side effect: that flag is set at boot by InitializeEventsScript (engine/events/std_scripts.asm:552) and it hides both VIRIDIANGYM_BLUE and the Viridian gym guide (maps/ViridianGym.asm:183-184). Talking to Blue here is the only thing that puts Blue in Viridian Gym.
  • CinnabarIslandHiddenRareCandy (maps/CinnabarIsland.asm:35) - a hiddenitem operand, not a script body: dwb EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY, RARE_CANDY.

Flags and events

constant defined in read/written by meaning for a bot
ENGINE_FLYPOINT_CINNABAR constants/engine_flags.asm:77 set by CinnabarIslandFlypointCallback Fly destination unlocked; also the wVisitedSpawns bit for respawn
EVENT_BLUE_IN_CINNABAR constants/event_flags.asm:1303 set implicitly by disappear CINNABARISLAND_BLUE; read by maps/ViridianCity.asm:37 and maps/ViridianPokecenter1F.asm:18 for "Blue returned" dialogue clear = Blue is standing on Cinnabar; set = you have heard the speech
EVENT_VIRIDIAN_GYM_BLUE constants/event_flags.asm:1304 set at engine/events/std_scripts.asm:552; cleared by CinnabarIslandBlue while set, Viridian Gym is empty
EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY constants/event_flags.asm:254 the hiddenitem at maps/CinnabarIsland.asm:36 one-shot guard on the hidden candy

Note: EVENT_BLUE_IN_CINNABAR is not in the InitializeEventsScript list, so it starts clear and Blue is visible from the first time you reach the island.

Items

item how obtained source one-time flag
RARE_CANDY face tile (9,1) and press A (or ITEMFINDER) bg_event 9, 1, BGEVENT_ITEM, CinnabarIslandHiddenRareCandy EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY

The walkthrough never mentions this candy.

Trainers

None.

Wild encounters

No def_grass_wildmons/def_water_wildmons row for CINNABAR_ISLAND in data/wild/kanto_grass.asm or data/wild/kanto_water.asm. The surrounding water belongs to Route 20 / Route 21. Fishing on the map's own water uses FISHGROUP_OCEAN (data/maps/maps.asm:199).


MAP_CINNABAR_POKECENTER_1F

  • Script: maps/CinnabarPokecenter1F.asm
  • Header: data/maps/maps.asm:192 -> TILESET_POKECENTER, INDOOR, LANDMARK_CINNABAR_ISLAND, MUSIC_POKEMON_CENTER, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:176 map_const CINNABAR_POKECENTER_1F, 5, 4 (group CINNABAR = 6, map id 1)
  • Attributes: data/maps/attributes.asm:510 map_attributes CinnabarPokecenter1F, CINNABAR_POKECENTER_1F, $00; no connections

Warps (def_warp_events, maps/CinnabarPokecenter1F.asm:38-41)

idx x y destination map dest warp
1 3 7 CINNABAR_ISLAND 1
2 4 7 CINNABAR_ISLAND 1
3 0 7 POKECENTER_2F 1

Coord events / BG events

None (maps/CinnabarPokecenter1F.asm:43, :45).

Object events (maps/CinnabarPokecenter1F.asm:47-50)

const sprite x y movement type script label event flag
CINNABARPOKECENTER1F_NURSE SPRITE_NURSE 3 1 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT CinnabarPokecenter1FNurseScript -> jumpstd PokecenterNurseScript -1
CINNABARPOKECENTER1F_COOLTRAINER_F SPRITE_COOLTRAINER_F 7 6 SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius x 2) OBJECTTYPE_SCRIPT CinnabarPokecenter1FCooltrainerFScript (BLAINE lives in the Seafoam cave) -1
CINNABARPOKECENTER1F_FISHER SPRITE_FISHER 2 4 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT CinnabarPokecenter1FFisherScript ("It's been a year since the volcano erupted.") -1

Both flavour NPCs are unconditional jumptextfaceplayer - no flags, no branches. These are the two people the walkthrough tells you to talk to.


MAP_ROUTE_20

  • Script: maps/Route20.asm
  • Blocks: maps/Route20.blk
  • Header: data/maps/maps.asm:197 -> TILESET_KANTO, ROUTE, LANDMARK_ROUTE_20, MUSIC_ROUTE_3, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:181 map_const ROUTE_20, 30, 9 (group CINNABAR = 6, map id 6). 60x18 tile coordinates.
  • Attributes / border: data/maps/attributes.asm:283 map_attributes Route20, ROUTE_20, $43
  • Connections: west CINNABAR_ISLAND (offset 0), east ROUTE_19 (offset -9)
  • Landmarks in view: data/maps/landmarks.asm:93 Route 20, :94 SeafoamIslandsName

Warps (def_warp_events, maps/Route20.asm:116-117)

idx x y destination map dest warp
1 38 7 SEAFOAM_GYM 1

Coord events

None (maps/Route20.asm:119).

BG events (maps/Route20.asm:121-122)

x y type script/item
37 11 BGEVENT_READ CinnabarGymSign -> "CINNABAR GYM / LEADER: BLAINE"

Object events (maps/Route20.asm:124-127)

const sprite x y movement type sight script label event flag
ROUTE20_SWIMMER_GIRL1 SPRITE_SWIMMER_GIRL 52 8 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 3 TrainerSwimmerfNicole -1
ROUTE20_SWIMMER_GIRL2 SPRITE_SWIMMER_GIRL 45 13 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 3 TrainerSwimmerfLori -1
ROUTE20_SWIMMER_GUY SPRITE_SWIMMER_GUY 12 13 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 3 TrainerSwimmermCameron -1

Cameron at x=12 is the only one west of the gym door at x=38, which is why the walkthrough sees "one trainer" on the way in. Lori (45) and Nicole (52) are east of it.

Scripts of interest

  • Route20ClearRocksCallback (maps/Route20.asm:12, sym 4e:4cfa), wired as callback MAPCALLBACK_NEWMAP at :10. Body is setevent EVENT_CINNABAR_ROCKS_CLEARED / endcallback. It fires silently the first time the map loads. Consumers: Route19ClearRocksCallback (maps/Route19.asm:15, sym 4e:4f09, a MAPCALLBACK_TILES callback) draws six changeblock ... $7a ; rock blocks at (6,6), (8,6), (10,6), (12,8), (4,8), (10,10) while the flag is clear; the officer in maps/Route19FuchsiaGate.asm:12 and the two fishers in maps/Route19.asm:74/:90 swap dialogue on it.
  • TrainerSwimmermCameron (maps/Route20.asm:38, sym 4e:4d26) - plain trainer, EVENT_BEAT_SWIMMERM_CAMERON, endifjustbattled + one line.

Flags and events

constant defined in read/written by meaning for a bot
EVENT_CINNABAR_ROCKS_CLEARED constants/event_flags.asm:214 set by Route20ClearRocksCallback; read by maps/Route19.asm:16, :74, :90 and maps/Route19FuchsiaGate.asm:12 while clear, six rock blocks seal the Route 19 water path from the Fuchsia side
EVENT_BEAT_SWIMMERM_CAMERON constants/event_flags.asm:957 maps/Route20.asm:39 beat flag
EVENT_BEAT_SWIMMERF_NICOLE constants/event_flags.asm:487 maps/Route20.asm:17 beat flag (next section)
EVENT_BEAT_SWIMMERF_LORI constants/event_flags.asm:488 maps/Route20.asm:28 beat flag (next section)

Items

None on this map.

Trainers

const class id party (data/trainers/parties.asm) script label rematch/phone
SWIMMERM, CAMERON SWIMMERM ($26) 17 ; SWIMMERM (17) at parties.asm:1749: L34 MARILL TrainerSwimmermCameron no
SWIMMERF, NICOLE SWIMMERF ($27) 14 ; SWIMMERF (14) at parties.asm:1854: L29 MARILL, L29 MARILL, L32 LAPRAS TrainerSwimmerfNicole no
SWIMMERF, LORI SWIMMERF ($27) 15 ; SWIMMERF (15) at parties.asm:1861: L32 STARMIE, L32 STARMIE TrainerSwimmerfLori no

Cameron pays 2 x 34 x 4 = 272, matching the walkthrough.

Wild encounters

  • Water (data/wild/kanto_water.asm:54-59), 6% rate: L35 TENTACOOL / L30 TENTACOOL / L35 TENTACRUEL.
  • No def_grass_wildmons ROUTE_20 row exists in data/wild/kanto_grass.asm - there is no land grass on this route.
  • Fishing: FISHGROUP_OCEAN, same three rod tables as Route 21 above.

MAP_SEAFOAM_GYM

  • Script: maps/SeafoamGym.asm
  • Blocks: maps/SeafoamGym.blk
  • Header: data/maps/maps.asm:195 -> TILESET_CAVE, INDOOR, LANDMARK_SEAFOAM_ISLANDS, MUSIC_GYM, TRUE (phone calls blocked), PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:179 map_const SEAFOAM_GYM, 5, 4 (group CINNABAR = 6, map id 4). 10x8 tile coordinates - smaller than the 20x18 screen, which is the walkthrough's "this gym doesn't even fit the entire screen".
  • Attributes / border: data/maps/attributes.asm:513 map_attributes SeafoamGym, SEAFOAM_GYM, $09; no connections
  • There is no MAP_SEAFOAM_ISLANDS dungeon in Gen 2 - constants/map_constants.asm has only SEAFOAM_GYM in the whole Seafoam family.

Warps (def_warp_events, maps/SeafoamGym.asm:161-162)

idx x y destination map dest warp
1 5 5 ROUTE_20 1

Coord events

None (maps/SeafoamGym.asm:164). The map does declare one scene script, scene_script SeafoamGymNoopScene (:7), and the asm itself annotates it ; unusable - the body at :11 is a bare end.

BG events

None (maps/SeafoamGym.asm:166).

Object events (maps/SeafoamGym.asm:168-170)

const sprite x y movement type sight script label event flag
SEAFOAMGYM_BLAINE SPRITE_BLAINE 5 2 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 0 SeafoamGymBlaineScript -1 (always present)
SEAFOAMGYM_GYM_GUIDE SPRITE_GYM_GUIDE 6 5 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT 0 SeafoamGymGuideScript EVENT_SEAFOAM_GYM_GYM_GUIDE

Scripts of interest

  • SeafoamGymBlaineScript (maps/SeafoamGym.asm:14, sym 53:516d). Control flow:
    1. faceplayer, opentext
    2. checkflag ENGINE_VOLCANOBADGE / iftrue .FightDone - the entire re-talk guard is the badge engine flag, not an event flag.
    3. writetext BlaineIntroText, waitbutton, closetext
    4. winlosstext BlaineWinLossText, 0 (no loss text)
    5. loadtrainer BLAINE, BLAINE1, startbattle
    6. iftrue .ReturnAfterBattle - i.e. if the battle result is non-zero (you lost / drew) it skips appear SEAFOAMGYM_GYM_GUIDE
    7. appear SEAFOAMGYM_GYM_GUIDE - clears EVENT_SEAFOAM_GYM_GYM_GUIDE, which is how the guide "comes in late"
    8. .ReturnAfterBattle: reloadmapafterbattle, setevent EVENT_BEAT_BLAINE, opentext, writetext ReceivedVolcanoBadgeText, playsound SFX_GET_BADGE, waitsfx, setflag ENGINE_VOLCANOBADGE, writetext BlaineAfterBattleText, waitbutton, closetext, end
    • No verbosegiveitem anywhere: Blaine gives no TM, only the badge.
    • Note the ordering quirk: setevent EVENT_BEAT_BLAINE / setflag ENGINE_VOLCANOBADGE are on the shared .ReturnAfterBattle path, reached whether or not you won, but startbattle does not return to the script on a whiteout, so in practice this is only reached after a win.
  • SeafoamGymGuideScript (maps/SeafoamGym.asm:46, sym 53:51a3) - branches on EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE, first line is the apology ("CINNABAR GYM was gone, so I didn't know where to find you"), then a second line forever after.

Flags and events

constant defined in read/written by meaning for a bot
ENGINE_VOLCANOBADGE constants/engine_flags.asm:53 (Kanto badge 7; wKantoBadges bit 6 per constants/ram_constants.asm:270) checked at maps/SeafoamGym.asm:17, set at :34 the badge itself; also gates the re-talk branch
EVENT_BEAT_BLAINE constants/event_flags.asm:721 set at maps/SeafoamGym.asm:29 not read by any other map in the checkout; it is the record, not the gate
EVENT_SEAFOAM_GYM_GYM_GUIDE constants/event_flags.asm:1305 set at boot (engine/events/std_scripts.asm:553), cleared by appear at maps/SeafoamGym.asm:26 while set, the guide object does not exist
EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE constants/event_flags.asm:212 maps/SeafoamGym.asm:49, :54 first-talk vs repeat text

What VOLCANOBADGE actually does mechanically: data/types/badge_type_boosts.asm:19 db FIRE ; VOLCANOBADGE, consumed by DoBadgeTypeBoosts (engine/battle/misc.asm:146, called from engine/battle/effect_commands.asm:1261) - a +12.5% damage boost on the player's FIRE-type moves. It grants no field move.

Items

None.

Trainers

const class id party (data/trainers/parties.asm) script label rematch/phone
BLAINE, BLAINE1 BLAINE ($2e), constants/trainer_constants.asm:469-470 1 BlaineGroup (sym 0e:6e70) at parties.asm:2303, TRAINERTYPE_MOVES: L45 MAGCARGO (CURSE, SMOG, FLAMETHROWER, ROCK_SLIDE), L45 MAGMAR (THUNDERPUNCH, FIRE_PUNCH, SUNNY_DAY, CONFUSE_RAY), L50 RAPIDASH (QUICK_ATTACK, FIRE_SPIN, FURY_ATTACK, FIRE_BLAST) SeafoamGymBlaineScript no rematch, no phone

Class attributes (data/trainers/attributes.asm:275-279): AI items are MAX_POTION, FULL_HEAL (not two Full Restores); base reward 25; AI mask AI_BASIC | AI_SETUP | AI_SMART | AI_AGGRESSIVE | AI_CAUTIOUS | AI_STATUS | AI_RISKY, CONTEXT_USE | SWITCH_SOMETIMES. Payout 25 x 50 x 4 = 5000, matching the walkthrough. BLAINE is in KantoGymLeaders (data/trainers/leaders.asm), so the battle uses the gym-leader music and awards HAPPINESS_GYMBATTLE.

Wild encounters

None. The map is INDOOR with TILESET_CAVE; its FISHGROUP_SHORE header entry is the default and has no reachable water.


3. Blockers and gates

Gate Enforced by (file:label) Requirement Unlock condition
Everything in this section is across open sea (Pallet -> Route 21 -> Cinnabar -> Route 20 -> gym door) engine/events/overworld.asm:469 TrySurfOW (walk-into-water path): ld de, ENGINE_FOGBADGE / CheckEngineFlag at :490, then ld d, SURF / CheckPartyMove. Menu path is SurfFunction .TrySurf at :340 with the same ENGINE_FOGBADGE. CheckBadge itself is at :50. FOGBADGE + a party mon that knows SURF already held long before Kanto (Johto badge 4)
Fly to Cinnabar Island data/maps/flypoints.asm:28; the flag is ENGINE_FLYPOINT_CINNABAR, set by CinnabarIslandFlypointCallback (maps/CinnabarIsland.asm:10) STORMBADGE + FLY + having stood on Cinnabar Island once walk in once
Blue is not in Viridian Gym maps/ViridianGym.asm:183-184 object rows carry EVENT_VIRIDIAN_GYM_BLUE, set at engine/events/std_scripts.asm:552 - clearevent EVENT_VIRIDIAN_GYM_BLUE at the tail of CinnabarIslandBlue (maps/CinnabarIsland.asm:23) - this section is a hard prerequisite for the Viridian Gym leader
Route 19 (east of Route 20) is sealed by six boulder blocks maps/Route19.asm:15 Route19ClearRocksCallback, a MAPCALLBACK_TILES callback that lays changeblock rock blocks while EVENT_CINNABAR_ROCKS_CLEARED is clear - setevent EVENT_CINNABAR_ROCKS_CLEARED in Route20ClearRocksCallback (maps/Route20.asm:13), i.e. simply loading Route 20 once from the Cinnabar side
Blaine will not re-battle maps/SeafoamGym.asm:17 checkflag ENGINE_VOLCANOBADGE / iftrue .FightDone - none in vanilla; .FightDone is terminal
The gym guide does not exist until Blaine is beaten object row event flag EVENT_SEAFOAM_GYM_GYM_GUIDE (maps/SeafoamGym.asm:170), set at engine/events/std_scripts.asm:553 beat Blaine appear SEAFOAMGYM_GYM_GUIDE (maps/SeafoamGym.asm:26), only on the win branch

Nothing in this section needs CUT, STRENGTH, WHIRLPOOL, WATERFALL, FLASH or a key item.

4. Bot checklist

Ordered, machine-actionable. (g,m) is (map group, map id) from constants/map_constants.asm. All coordinates are the raw asm map-event values.

  1. PALLET_TOWN: SURF south across the connection into ROUTE_21 (6,7). Pre: FOGBADGE + SURF in the party. Post: none.
  2. ROUTE_21: battle TrainerSwimmerfNikki at (11,16) - sight radius 3, so she will trigger on approach. Party L28 SEEL x3 + L28 DEWGONG. Post: EVENT_BEAT_SWIMMERF_NIKKI, +560 money.
  3. ROUTE_21: battle TrainerFisherArnold at (14,22) - sight radius 1, faces up. Party L34 TENTACRUEL. Post: EVENT_BEAT_FISHER_ARNOLD, +1360 money.
  4. ROUTE_21: surf west then south to TrainerSwimmermSeth at (2,30) - sight radius 4, faces right. Party L29 QUAGSIRE / L29 OCTILLERY / L32 QUAGSIRE. Post: EVENT_BEAT_SWIMMERM_SETH, +256 money. (Both trainers are avoidable - all three are OBJECTTYPE_TRAINER with a finite sight radius, none are on a coord event.)
  5. ROUTE_21: continue south across the connection into CINNABAR_ISLAND (6,8). Post: MAPCALLBACK_NEWMAP sets ENGINE_FLYPOINT_CINNABAR; respawn point becomes SPAWN_CINNABAR = (11,12).
  6. CINNABAR_ISLAND: step on warp 1 at (11,11) -> CINNABAR_POKECENTER_1F (6,1). Talk to CINNABARPOKECENTER1F_NURSE at (3,1) to heal. Optional: the two flavour NPCs at (7,6) and (2,4). Exit via warp 1/2 at (3,7)/(4,7).
  7. CINNABAR_ISLAND: optional - face (9,1) and press A for the hidden RARE_CANDY. Pre: EVENT_CINNABAR_ISLAND_HIDDEN_RARE_CANDY clear + a free bag slot. Post: flag set. (Not in the walkthrough.)
  8. CINNABAR_ISLAND: walk to CINNABARISLAND_BLUE at (9,6) and talk. Pre: EVENT_BLUE_IN_CINNABAR clear. Expect a long writetext (about 13 pages of para breaks - budget A presses accordingly), then SFX_WARP_TO + a teleport_from movement, then the object vanishes. Post: EVENT_BLUE_IN_CINNABAR set (via disappear), EVENT_VIRIDIAN_GYM_BLUE cleared. Do not skip this step: it is the only unlock for the Viridian Gym leader.
  9. CINNABAR_ISLAND: optional signs at (12,11), (9,11), (7,7).
  10. CINNABAR_ISLAND: SURF east across the connection into ROUTE_20 (6,6). Post: MAPCALLBACK_NEWMAP sets EVENT_CINNABAR_ROCKS_CLEARED (silent; unseals Route 19 for the next section).
  11. ROUTE_20: battle TrainerSwimmermCameron at (12,13) - sight radius 3. Party L34 MARILL. Post: EVENT_BEAT_SWIMMERM_CAMERON, +272 money.
  12. ROUTE_20: optional sign at (37,11). Then step onto warp 1 at (38,7) -> SEAFOAM_GYM (6,4).
  13. SEAFOAM_GYM: walk to SEAFOAMGYM_BLAINE at (5,2) and talk. Pre: ENGINE_VOLCANOBADGE clear (otherwise you get .FightDone only). Battle: loadtrainer BLAINE, BLAINE1 - L45 MAGCARGO / L45 MAGMAR / L50 RAPIDASH, AI holds MAX_POTION + FULL_HEAL. Post: EVENT_BEAT_BLAINE set, EVENT_SEAFOAM_GYM_GYM_GUIDE cleared (guide appears at (6,5)), ENGINE_VOLCANOBADGE set, +5000 money. No TM, no item.
  14. SEAFOAM_GYM: optional - talk to SEAFOAMGYM_GYM_GUIDE at (6,5). Post: EVENT_TALKED_TO_SEAFOAM_GYM_GUIDE_ONCE.
  15. SEAFOAM_GYM: exit via warp 1 at (5,5) back to ROUTE_20 warp 1.

Follow-up (next section): Route 20 continues east past Lori (45,13) and Nicole (52,8) into ROUTE_19, whose rock blocks are now gone because step 10 set EVENT_CINNABAR_ROCKS_CLEARED.

5. Port coverage

Beat Port file Status
Kanto map headers, dimensions, connections, warp / coord / bg / object tables src/import/RomExtractorGen2.lua (all 26 map groups, MAP_GROUP_COUNT = 26 at :47, MapGroupPointers walk at :728) implemented - fully data-driven, nothing Cinnabar-specific needed
MAPCALLBACK_NEWMAP (CinnabarIslandFlypointCallback, Route20ClearRocksCallback) src/world/gen2/World.lua:5659 self:runMapCallback("MAPCALLBACK_NEWMAP"), in HandleNewMap order (:5646) implemented; asserted end-to-end by tests/drivers/gold_map_callbacks.lua
MAPCALLBACK_TILES + changeblock (the Route 19 rocks that this section unseals) src/world/gen2/World.lua:5662; changeblock opcode at src/script/gen2/Opcodes.lua:127 implemented
setflag ENGINE_FLYPOINT_CINNABAR -> flyable src/world/gen2/FieldMoves.lua:367 (LANDMARK_CINNABAR_ISLAND / SPAWN_CINNABAR / flag 62), World:setEngineFlag at src/world/gen2/World.lua:1326 implemented
checkevent / setevent / clearevent, checkflag / setflag src/script/gen2/Vm.lua:187-229 implemented - id-keyed stores, engineFlags kept separate from wEventFlags
appear / disappear writing the object's event flag (Blue vanishing, the guide arriving) src/script/gen2/Opcodes.lua:115-116, handled in src/script/gen2/Vm.lua implemented
Hidden item BGEVENT_ITEM (Cinnabar RARE_CANDY at 9,1) src/world/gen2/HiddenItems.lua (BGEVENT_ITEM = 7 at :22), extractor branch at src/import/RomExtractorGen2.lua:2986 implemented
loadtrainer / startbattle / winlosstext / reloadmapafterbattle / endifjustbattled (the whole Blaine script) src/script/gen2/Vm.lua:806, :817, :886, :918 implemented, incl. the iftrue on wBattleResult that guards appear SEAFOAMGYM_GYM_GUIDE
Gym-leader battle music / victory music for BLAINE src/battle/gen2/BattleMusic.lua:21, src/battle/gen2/Battle.lua:82 (both list BLAINE = true) implemented
Prize money = base x last-mon level x 4 (560 / 1360 / 256 / 272 / 5000) src/battle/gen2/Prize.lua (header documents ComputeTrainerReward and the ld c, 4 loop; Prize.reward) implemented, incl. the Mom's-savings split
Trainer sight radii (3 / 4 / 1 on Route 21) src/world/gen2/Trainers.lua implemented
SURF gate on FOGBADGE + party move src/world/gen2/FieldMoves.lua:106 (SURF = "FOG"), :481 surfFromMenu, :678 overworld path implemented; driven by tests/drivers/gold_water_moves.lua
Ocean wild/fish tables for Routes 20/21 extracted by src/import/RomExtractorGen2.lua, consumed by src/battle/gen2/Encounter.lua implemented - correct by construction from the ROM
Radio "Place & Name" un-hiding BLAINE after the Kanto badge sweep src/ui/gen2/Pokegear.lua:172 (PNP_HIDDEN), :178 PNP_HIDDEN_BEAT_KANTO, :1265 implemented
setflag ENGINE_VOLCANOBADGE reaching the trainer card / VAR_BADGES count src/script/gen2/Vm.lua:208-229 writes save.engineFlags[53]; but VAR_BADGES (src/world/gen2/World.lua:1243-1244) counts save.player.badges + save.player.kantoBadges, and src/ui/gen2/TrainerCard.lua:395 reads player.badges. Nothing in src/ ever writes player.kantoBadges (only initialised at src/core/gen2/Save.lua:119). partial - Blaine's own re-talk guard works (same engineFlags id is read back by checkflag), but the badge does not show on the trainer card and does not increment VAR_BADGES
BadgeTypeBoosts (VOLCANOBADGE = +12.5% FIRE damage) no Gen 2 implementation - grep -rn "badge" src/battle/gen2/ returns nothing; the only badge-boost code is the Gen 1 src/battle/Damage.lua:35 missing
teleport_from ($4c) movement for Blue's exit src/script/gen2/Movement.lua:22 decodeByte - $4c matches no family branch and falls through to { kind = "nop" } partial - Blue disappears with the sound but without the rise-and-vanish animation
End-to-end driver coverage for this stretch tests/drivers/gold_*.lua (25 drivers, all Johto: boot, walk, warp, trainer, ice path, roamers, ...) missing - no Cinnabar / Route 20 / Route 21 / Seafoam Gym driver exists

6. Unresolved / verify by hand

  • Blaine's movesets in the walkthrough are not the pokegold movesets. The FAQ describes Magcargo with Yawn / Recover / Overheat, Magmar with Confuse Ray, and Rapidash with Flare Blitz / Bounce. data/trainers/parties.asm:2303-2308 gives MAGCARGO (CURSE, SMOG, FLAMETHROWER, ROCK_SLIDE), MAGMAR (THUNDERPUNCH, FIRE_PUNCH, SUNNY_DAY, CONFUSE_RAY) and RAPIDASH (QUICK_ATTACK, FIRE_SPIN, FURY_ATTACK, FIRE_BLAST). Only CONFUSE_RAY overlaps; Overheat, Flare Blitz, Bounce and Yawn do not exist in constants/move_constants.asm at all for this generation. Species and levels match exactly (L45 / L45 / L50), so treat the strategy prose as written against a different (modernised) build and the asm as authoritative.
  • "Blaine will have two Full Restores available." data/trainers/attributes.asm:276 is db MAX_POTION, FULL_HEAL. Two different items, neither of them a Full Restore. The count of uses is AI-driven, not a fixed two.
  • "You now have 15 badges!" Nothing in the asm counts badges as an ordinal; Kanto gyms have no enforced order (ENGINE_VOLCANOBADGE is one bit, constants/engine_flags.asm:53). The 15 is walkthrough prose that assumes a specific visiting order.
  • Route 21 wild list is abridged in the walkthrough. The FAQ lists Tentacool and Tangela. data/wild/kanto_grass.asm:1005 also has MR__MIME in all three time slots, and data/wild/kanto_water.asm:61 also has TENTACRUEL. Route 20's list is likewise incomplete (TENTACRUEL is there too).
  • "Surf south on Route 21 ... head way left then down." The trainer coordinates confirm the shape of the route (16 -> 22 -> 30, then far west), but the actual walkable water path is block data in maps/Route21.blk and was not decoded here.
  • "You should see a small cave at the Seafoam Islands." The only asm anchor is warp_event 38, 7 on maps/Route20.asm:117 plus bg_event 37, 11 for the gym sign. The cave mouth graphic itself is block data in maps/Route20.blk; there is no Seafoam Islands dungeon map in Gen 2 (constants/map_constants.asm has only SEAFOAM_GYM), so the walkthrough's "Seafoam Islands" is a landmark name (data/maps/landmarks.asm:94 LANDMARK_SEAFOAM_ISLANDS) rather than a walkable dungeon.
  • EXP figures. The per-mon EXP numbers in the FAQ (600 for a L28 Seel, 1056 for a L28 Dewgong, 1492 for a L34 Tentacruel) are consistent with the vanilla base_exp * level / 7 times the 1.5x trainer-battle bonus, but nothing in data/trainers/parties.asm stores them and they still vary with participation, so they are not reproducible from the asm as written. The money figures all reproduce exactly and are recorded above.
  • EVENT_BEAT_BLAINE has no reader. Grepping maps/, data/, engine/, home/ and constants/ finds it only at its definition (constants/event_flags.asm:721) and its single setevent (maps/SeafoamGym.asm:29). If the port needs a "Blaine beaten" predicate for anything, ENGINE_VOLCANOBADGE is the flag the cart actually branches on.