Files
gen1recomp/docs/gold-walkthrough/asm-walk/section-19-s-s-aqua-and-vermilion-city-gym.md
T
bryanthaboi ae6cac89e1 G2 support
2026-08-11 11:53:30 -04:00

67 KiB

Section 19 - S.S. Aqua and Vermilion City Gym

Source: ../section-19-s-s-aqua-and-vermilion-city-gym.txt Maps covered: NEW_BARK_TOWN, ELMS_LAB, OLIVINE_PORT_PASSAGE, OLIVINE_PORT, FAST_SHIP_1F, FAST_SHIP_CABINS_NNW_NNE_NE, FAST_SHIP_CABINS_SW_SSW_NW, FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN, FAST_SHIP_B1F, VERMILION_PORT, VERMILION_PORT_PASSAGE, VERMILION_CITY, POKEMON_FAN_CLUB, VERMILION_GYM Badges / key milestones in this section: S.S. TICKET from Prof. Elm, first Kanto crossing on the Fast Ship, METAL COAT from the grandpa on the S.S. Aqua, ENGINE_FLYPOINT_VERMILION, RARE CANDY from the Fan Club Chairman, THUNDERBADGE (ENGINE_THUNDERBADGE) from Lt. Surge.

This section begins immediately after the Hall of Fame. maps/HallOfFame.asm HallOfFameEnterScript is what arms it: it sets EVENT_BEAT_ELITE_FOUR, sets EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME (hiding the "no entry" sailor pair), clears EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME (revealing the boarding sailor), and, if EVENT_GOT_SS_TICKET_FROM_ELM is still clear, queues specialphonecall SPECIALCALL_SSTICKET (the Elm call the walkthrough mentions).


1. Route order

# Map constant asm file Enter via Leaves via Why (walkthrough beat)
1 NEW_BARK_TOWN maps/NewBarkTown.asm post-credits respawn warp 1 (6,3) -> ELMS_LAB 1 Elm phones you to come back
2 ELMS_LAB maps/ElmsLab.asm warp 1/2 (4,11)/(5,11) same warps back to NEW_BARK_TOWN 1 talk to ProfElmScript -> ElmGiveTicketScript -> S.S. TICKET
3 OLIVINE_CITY maps/OlivineCity.asm Fly (ENGINE_FLYPOINT_OLIVINE) warp 10 (19,27) / warp 11 (20,27) -> OLIVINE_PORT_PASSAGE 1/2 "go south from the Pokemon Center" to the port entrance
4 OLIVINE_PORT_PASSAGE maps/OlivinePortPassage.asm warps 1/2 (15,0)/(16,0) warp 3 (15,4) -> warp 4 (3,2), then warp 5 (3,14) -> OLIVINE_PORT 1 "take the stairs down twice"
5 OLIVINE_PORT maps/OlivinePort.asm warp 1 (11,7) coord_event (7,15) -> OlivinePortWalkUpToShipScript -> warp FAST_SHIP_1F, 25, 1 show the S.S. TICKET, board
6 FAST_SHIP_1F maps/FastShip1F.asm scripted warp to (25,1) 12 warps (see below) ship deck hub; grandpa bumps you at (24,6)/(25,6)
7 FAST_SHIP_CABINS_NNW_NNE_NE maps/FastShipCabins_NNW_NNE_NE.asm 1F warps 2/3/4 ((27,8), (23,8), (19,8)) same Hiker Noland; later the lazy Sailor Stanly
8 FAST_SHIP_CABINS_SW_SSW_NW maps/FastShipCabins_SW_SSW_NW.asm 1F warps 5/6/7 ((15,8), (15,15), (19,15)) same your cabin + healing bed; Firebreather Lyle
9 FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN maps/FastShipCabins_SE_SSE_CaptainsCabin.asm 1F warps 8/9/10 ((23,15), (27,15), (3,13)) same PoKeFan Colin + Twins; grandpa; captain's cabin + granddaughter
10 FAST_SHIP_B1F maps/FastShipB1F.asm 1F warps 11/12 ((6,12), (30,14)) same on-duty sailor blocks; Fritz, Jeff, Debra
11 VERMILION_PORT maps/VermilionPort.asm FastShip1FSailor1Script -> warp VERMILION_PORT, 7, 17 warp 1 (9,5) -> VERMILION_PORT_PASSAGE 5 ship docks in Kanto
12 VERMILION_PORT_PASSAGE maps/VermilionPortPassage.asm warp 5 (3,14) warp 4 (3,2) -> warp 3 (15,4), then warps 1/2 (15,0)/(16,0) -> VERMILION_CITY 8/9 "down the stairs, then up the stairs and out the door"
13 VERMILION_CITY maps/VermilionCity.asm warps 8/9 (19,31)/(20,31) warp 3 (7,13), warp 7 (10,19) first look at Kanto
14 POKEMON_FAN_CLUB maps/PokemonFanClub.asm warp 1/2 (2,7)/(3,7) same Chairman's speech -> RARE CANDY
15 VERMILION_GYM maps/VermilionGym.asm warps 1/2 (4,17)/(5,17) same Vincent, Horton, Gregory, then Lt. Surge -> THUNDERBADGE

Spill-over note: the walkthrough's closing line ("Congrats on your first badge in Kanto") ends the section; Saffron City / Route 6 are handled by the next section's agent. VERMILION_CITY connects north Route6 (+5) and east Route11 (0) (data/maps/attributes.asm:342-344), and warp 10 (34,7) to DIGLETTS_CAVE sits behind the sleeping Snorlax; none of those are used here.


2. Maps

MAP_ELMS_LAB

  • Script: maps/ElmsLab.asm
  • Blocks: maps/ElmsLab.blk
  • Header: data/maps/maps.asm:476 -> map ElmsLab, TILESET_LAB, INDOOR, LANDMARK_NEW_BARK_TOWN, MUSIC_PROF_ELM, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:441 map_const ELMS_LAB, 5, 6 (10 x 12 cells)
  • Connections: none (indoor)

Only the S.S. TICKET beat is in scope. Full warp/object tables for the early-game scenes belong to section 1; the rows below are the ones this section touches.

Warps (def_warp_events)

idx x y destination map dest warp
1 4 11 NEW_BARK_TOWN 1
2 5 11 NEW_BARK_TOWN 1

Object events (def_object_events) - relevant row only

const sprite x y movement type script label event flag
ELMSLAB_ELM SPRITE_ELM 5 2 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT ProfElmScript -1

Scripts of interest

  • ProfElmScript (maps/ElmsLab.asm:50, sym 60:427b for ElmGiveTicketScript). First two opcodes after faceplayer/opentext are the ticket gate: checkevent EVENT_GOT_SS_TICKET_FROM_ELM / iftrue ElmCheckMasterBall, then checkevent EVENT_BEAT_ELITE_FOUR / iftrue ElmGiveTicketScript. So the ticket is handed out on the first post-Hall-of-Fame conversation and never again.
  • ElmGiveTicketScript: writetext ElmGiveTicketText1 -> verbosegiveitem S_S_TICKET -> setevent EVENT_GOT_SS_TICKET_FROM_ELM -> writetext ElmGiveTicketText2 -> closetext / end. Note there is no iffalse bag-full guard on this verbosegiveitem, unlike every other Elm gift in the same file - the flag is set unconditionally.
  • engine/phone/scripts/elm.asm:69 ElmPhoneCallerScript routes SPECIALCALL_SSTICKET to .gift, which prints ElmPhoneGiftText and clears the pending call with specialphonecall SPECIALCALL_NONE. The call is only the nudge; it does not give the item.

Flags and events

constant defined in read/written by meaning for a bot
EVENT_BEAT_ELITE_FOUR constants/event_flags.asm:77 set by maps/HallOfFame.asm:33; read by ProfElmScript precondition for the ticket
EVENT_GOT_SS_TICKET_FROM_ELM constants/event_flags.asm:45 set by ElmGiveTicketScript; read by ProfElmScript and HallOfFame.asm:41 one-time ticket guard
SPECIALCALL_SSTICKET constants/phone_constants.asm:49 queued by HallOfFame.asm:43, consumed in engine/phone/scripts/elm.asm the phone nudge; ignorable

Items

item how obtained source (label / bg_event / hidden) one-time flag
S_S_TICKET talk to Elm ElmGiveTicketScript verbosegiveitem S_S_TICKET EVENT_GOT_SS_TICKET_FROM_ELM

MAP_OLIVINE_PORT_PASSAGE

  • Script: maps/OlivinePortPassage.asm
  • Blocks: maps/PortPassage.blk (shared with VermilionPortPassage; there is no OlivinePortPassage.blk)
  • Header: data/maps/maps.asm:340 -> map OlivinePortPassage, TILESET_UNDERGROUND, INDOOR, LANDMARK_OLIVINE_CITY, MUSIC_VIOLET_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:314 map_const OLIVINE_PORT_PASSAGE, 10, 9 (20 x 18 cells)
  • Connections: none

Warps (def_warp_events)

idx x y destination map dest warp
1 15 0 OLIVINE_CITY 10
2 16 0 OLIVINE_CITY 11
3 15 4 OLIVINE_PORT_PASSAGE 4
4 3 2 OLIVINE_PORT_PASSAGE 3
5 3 14 OLIVINE_PORT 1

Coord events - none.

BG events - none.

Object events (def_object_events)

const sprite x y movement type script label event flag
OLIVINEPORTPASSAGE_POKEFAN_M SPRITE_POKEFAN_M 17 1 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_SCRIPT OlivinePortPassagePokefanMScript EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M

The Pokefan is hidden at new game (InitializeEventsScript, engine/events/std_scripts.asm:530 sets the flag) and revealed by VermilionPortLeaveShipScript (clearevent EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M) once you have made the crossing once. His text is the Monday/Friday schedule.

MAP_OLIVINE_PORT

  • Script: maps/OlivinePort.asm
  • Blocks: maps/OlivinePort.blk
  • Header: data/maps/maps.asm:333 -> map OlivinePort, TILESET_PORT, ROUTE, LANDMARK_OLIVINE_CITY, MUSIC_VIOLET_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:307 map_const OLIVINE_PORT, 10, 18 (20 x 36 cells)
  • Attributes: data/maps/attributes.asm:586 map_attributes OlivinePort, OLIVINE_PORT, $0a - no connections

Warps (def_warp_events)

idx x y destination map dest warp
1 11 7 OLIVINE_PORT_PASSAGE 5
2 7 23 FAST_SHIP_1F 1

Coord events (def_coord_events)

scene x y script label effect
SCENE_OLIVINEPORT_ASK_ENTER_SHIP (0) 7 15 OlivinePortWalkUpToShipScript (sym 5b:407d) boarding prompt + ticket check

BG events (def_bg_events)

x y type script/item
1 22 BGEVENT_ITEM OlivinePortHiddenProtein -> hiddenitem PROTEIN, EVENT_OLIVINE_PORT_HIDDEN_PROTEIN

Object events (def_object_events)

const sprite x y movement type script label event flag
OLIVINEPORT_SAILOR1 SPRITE_SAILOR 7 23 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT OlivinePortSailorAtGangwayScript EVENT_OLIVINE_PORT_SAILOR_AT_GANGWAY
OLIVINEPORT_SAILOR2 SPRITE_SAILOR 7 15 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT OlivinePortSailorBeforeHOFScript EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME
OLIVINEPORT_SAILOR3 SPRITE_SAILOR 6 15 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT OlivinePortSailorAfterHOFScript EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME
OLIVINEPORT_FISHING_GURU1 SPRITE_FISHING_GURU 4 14 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT OlivinePortFishingGuru1Script EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME
OLIVINEPORT_FISHING_GURU2 SPRITE_FISHING_GURU 13 14 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT OlivinePortFishingGuru2Script EVENT_OLIVINE_PORT_SPRITES_BEFORE_HALL_OF_FAME
OLIVINEPORT_YOUNGSTER SPRITE_YOUNGSTER 4 15 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT OlivinePortYoungsterScript EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME
OLIVINEPORT_COOLTRAINER_F SPRITE_COOLTRAINER_F 11 15 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT OlivinePortCooltrainerFScript EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME

Object event flags hide when set. Post-Hall-of-Fame, SAILOR2 and the two fishing gurus are gone and SAILOR3 / youngster / cooltrainer are present.

Scripts of interest

  • OlivinePortWalkUpToShipScript (coord event at (7,15)): turns SAILOR3 right, bails via .skip if either EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1 or _2 is set, else asks OlivinePortAskBoardText with yesorno. If EVENT_FAST_SHIP_FIRST_TIME is clear it jumps straight past the weekday gate (.FirstTime) - the maiden voyage sails any day. Otherwise readvar VAR_WEEKDAY: SUNDAY/SATURDAY -> .NextShipMonday, TUESDAY/WEDNESDAY/THURSDAY -> .NextShipFriday. So from Olivine the ship sails Monday and Friday. Then checkitem S_S_TICKET; iffalse .NoTicket. On success it sets EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2, walks the player 7 steps down (OlivinePortApproachFastShipFirstTimeMovement) and sjumps into OlivinePortSailorAtGangwayScript.
  • OlivinePortSailorAtGangwayScript: disappear OLIVINEPORT_SAILOR1, one step down, special FadeOutToWhite, then the passenger-roster bookkeeping. On repeat trips only (checkevent EVENT_FAST_SHIP_FIRST_TIME / iffalse .FirstTime) it does clearevent EVENT_FAST_SHIP_PASSENGERS_EASTBOUND, setevent EVENT_FAST_SHIP_PASSENGERS_WESTBOUND and clears the eight eastbound EVENT_BEAT_* rematch flags. Always: clearevent EVENT_FAST_SHIP_DESTINATION_OLIVINE, appear OLIVINEPORT_SAILOR1, setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_ENTER_SHIP, warp FAST_SHIP_1F, 25, 1.
  • OlivinePortLeaveShipScript (scene SCENE_OLIVINEPORT_LEAVE_SHIP, 1): the arrival cutscene for the return trip - one step up, appear the sailor, setscene SCENE_OLIVINEPORT_ASK_ENTER_SHIP, setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1, blackoutmod OLIVINE_CITY.

Wild encounters

data/wild/johto_water.asm:278 def_water_wildmons OLIVINE_PORT, encounter rate 2 percent: 20 TENTACOOL / 15 TENTACOOL / 20 TENTACRUEL. Fishing group FISHGROUP_OCEAN (data/wild/fish.asm:13, .Ocean_* at lines 42-55). No grass, no headbutt table.

MAP_FAST_SHIP_1F

  • Script: maps/FastShip1F.asm
  • Blocks: maps/FastShip1F.blk
  • Header: data/maps/maps.asm:335 -> map FastShip1F, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:309 map_const FAST_SHIP_1F, 16, 9 (32 x 18 cells)
  • Connections: none

Scene ids are declared inline by scene_script (macros/scripts/maps.asm:25): SCENE_FASTSHIP1F_NOOP = 0, SCENE_FASTSHIP1F_ENTER_SHIP = 1, SCENE_FASTSHIP1F_MEET_GRANDPA = 2.

Warps (def_warp_events)

idx x y destination map dest warp
1 25 1 FAST_SHIP_1F -1 (arrival tile only)
2 27 8 FAST_SHIP_CABINS_NNW_NNE_NE 1
3 23 8 FAST_SHIP_CABINS_NNW_NNE_NE 2
4 19 8 FAST_SHIP_CABINS_NNW_NNE_NE 3
5 15 8 FAST_SHIP_CABINS_SW_SSW_NW 1
6 15 15 FAST_SHIP_CABINS_SW_SSW_NW 2
7 19 15 FAST_SHIP_CABINS_SW_SSW_NW 4
8 23 15 FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN 1
9 27 15 FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN 3
10 3 13 FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN 5
11 6 12 FAST_SHIP_B1F 1
12 30 14 FAST_SHIP_B1F 2

Warp 5 (15,8) is "your cabin" (the one with the healing bed). Warp 10 (3,13) is the staircase to the captain's cabin.

Coord events (def_coord_events)

scene x y script label effect
SCENE_FASTSHIP1F_MEET_GRANDPA (2) 24 6 WorriedGrandpaSceneLeft (sym 5b:495d) grandpa runs in and bumps you
SCENE_FASTSHIP1F_MEET_GRANDPA (2) 25 6 WorriedGrandpaSceneRight moveobject FASTSHIP1F_GENTLEMAN, 20, 6 then falls through into WorriedGrandpaSceneLeft

BG events - none.

Object events (def_object_events)

const sprite x y movement type script label event flag
FASTSHIP1F_SAILOR1 SPRITE_SAILOR 25 2 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT FastShip1FSailor1Script -1
FASTSHIP1F_SAILOR2 SPRITE_SAILOR 14 7 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT FastShip1FSailor2Script -1
FASTSHIP1F_SAILOR3 SPRITE_SAILOR 22 17 SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius 2,0) OBJECTTYPE_SCRIPT FastShip1FSailor3Script -1
FASTSHIP1F_GENTLEMAN SPRITE_GENTLEMAN 19 6 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT ObjectEvent EVENT_FAST_SHIP_1F_GENTLEMAN

Scripts of interest

  • FastShip1FEnterShipScript (sym 5b:48ad, scene 1, run via sdefer): sailor steps aside, player walks 2 down, sailor steps back and blocks the door, playsound SFX_BOAT, earthquake 30, blackoutmod FAST_SHIP_CABINS_SW_SSW_NW (your blackout respawn becomes your cabin), clearevent EVENT_FAST_SHIP_HAS_ARRIVED. Then checkevent EVENT_FAST_SHIP_FIRST_TIME / iftrue .SkipGrandpa: on the first crossing it sets SCENE_FASTSHIP1F_MEET_GRANDPA, otherwise SCENE_FASTSHIP1F_NOOP.
  • WorriedGrandpaSceneLeft: appear FASTSHIP1F_GENTLEMAN, four big_step RIGHT, playsound SFX_TACKLE, knocks the player one step right, writetext FastShip1FGrandpaText ("My granddaughter is missing!"), then the gentleman runs off, disappears and the scene is reset to SCENE_FASTSHIP1F_NOOP. Purely informational - it sets no quest flag.
  • FastShip1FSailor1Script (the door guard at (25,2)): if EVENT_FAST_SHIP_HAS_ARRIVED is clear it just says "en route", branching on EVENT_FAST_SHIP_DESTINATION_OLIVINE for the destination name. Once arrived it runs .LetThePlayerOut (readvar VAR_FACING, two step-up variants), then setevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY (note: set hides that object), setmapscene VERMILION_PORT, SCENE_VERMILIONPORT_LEAVE_SHIP and warp VERMILION_PORT, 7, 17. The Olivine-bound mirror is ._Olivine -> warp OLIVINE_PORT, 7, 23.

Flags and events

constant defined in read/written by meaning for a bot
EVENT_FAST_SHIP_FIRST_TIME constants/event_flags.asm:57 set by VermilionPortLeaveShipScript; read by both port scripts, FastShip1FEnterShipScript, FastShip1FSailor2Script, SSAquaCaptain, FastShipBed, FastShipB1FSailorScript "the maiden crossing is finished"; gates the weekday schedule and the grandpa quest
EVENT_FAST_SHIP_HAS_ARRIVED constants/event_flags.asm:58 cleared on boarding, set by SSAquaMetalCoatAndDocking / FastShipBed.CanArrive; read by FastShip1FSailor1Script the door guard will only let you off once this is set
EVENT_FAST_SHIP_DESTINATION_OLIVINE constants/event_flags.asm:56 cleared at Olivine, set at Vermilion which port the ship is heading for
EVENT_FAST_SHIP_1F_GENTLEMAN constants/event_flags.asm:1230 set at new game (std_scripts.asm:497), appear/disappear in WorriedGrandpaSceneLeft grandpa sprite visibility

MAP_FAST_SHIP_CABINS_NNW_NNE_NE

  • Script: maps/FastShipCabins_NNW_NNE_NE.asm
  • Blocks: maps/FastShipCabins_NNW_NNE_NE.blk
  • Header: data/maps/maps.asm:336 -> map FastShipCabins_NNW_NNE_NE, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:310 map_const FAST_SHIP_CABINS_NNW_NNE_NE, 4, 16 (8 x 32 cells)
  • Layout: three stacked sub-rooms, y 0-11, 12-23, 24-31.

Warps (def_warp_events)

idx x y destination map dest warp
1 2 0 FAST_SHIP_1F 2
2 2 12 FAST_SHIP_1F 3
3 2 24 FAST_SHIP_1F 4

Coord events - none.

BG events (def_bg_events)

x y type script/item
6 13 BGEVENT_READ FastShipCabins_NNW_NNE_NETrashcan (jumpstd TrashCanScript)
7 19 BGEVENT_READ FastShipCabins_NNW_NNE_NETrashcan
7 31 BGEVENT_READ FastShipCabins_NNW_NNE_NETrashcan

Object events (def_object_events)

const sprite x y movement type sight script label event flag
..._COOLTRAINER_M SPRITE_COOLTRAINER_M 4 3 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 2 TrainerCooltrainermSean EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
..._COOLTRAINER_F SPRITE_COOLTRAINER_F 1 5 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerCooltrainerfCarol EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
..._SUPER_NERD SPRITE_SUPER_NERD 1 5 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerPokemaniacEthan EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
..._POKEFAN_M SPRITE_POKEFAN_M 4 17 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerHikerNoland EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
..._SAILOR SPRITE_SAILOR 4 26 SPRITEMOVEDATA_SPINRANDOM_SLOW OBJECTTYPE_SCRIPT 0 FastShipLazySailorScript EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR
..._GENTLEMAN SPRITE_GENTLEMAN 7 30 SPRITEMOVEDATA_SPINRANDOM_SLOW OBJECTTYPE_TRAINER 1 TrainerGentlemanEdward EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
..._PHARMACIST SPRITE_PHARMACIST 2 30 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 4 TrainerBurglarCorey EVENT_FAST_SHIP_PASSENGERS_WESTBOUND

On the maiden voyage only EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP is clear, so Hiker Noland is the only trainer visible on this map - exactly what the walkthrough describes.

Scripts of interest

  • FastShipLazySailorScript (sym 5b:4d68): not a trainer object, a scripted battle. playmusic MUSIC_HIKER_ENCOUNTER -> SailorStanlySeenText -> winlosstext SailorStanlyBeatenText, 0 -> loadtrainer SAILOR, STANLY -> startbattle -> reloadmap -> special HealParty -> setevent EVENT_BEAT_SAILOR_STANLY -> after-battle text -> setevent EVENT_FAST_SHIP_LAZY_SAILOR -> setmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP (this is what unblocks B1F) -> readvar VAR_FACING, walk him out, disappear. Note special HealParty fires unconditionally after the fight.

Trainers

const class id party (data/trainers/parties.asm) script label notes
HIKER, NOLAND HIKER ($2c) 14 ; HIKER (14) db "NOLAND@", TRAINERTYPE_NORMAL -> L31 SANDSLASH, L33 GOLEM TrainerHikerNoland flag EVENT_BEAT_HIKER_NOLAND
SAILOR, STANLY SAILOR ($28) 9 ; SAILOR (9) db "STANLY@", TRAINERTYPE_NORMAL -> L31 MACHOP, L33 MACHOKE, L26 PSYDUCK FastShipLazySailorScript scripted loadtrainer, not an OBJECTTYPE_TRAINER

MAP_FAST_SHIP_CABINS_SW_SSW_NW

  • Script: maps/FastShipCabins_SW_SSW_NW.asm
  • Blocks: maps/FastShipCabins_SW_SSW_NW.blk
  • Header: data/maps/maps.asm:337 -> map FastShipCabins_SW_SSW_NW, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:311 map_const FAST_SHIP_CABINS_SW_SSW_NW, 4, 16 (8 x 32 cells)

Warps (def_warp_events)

idx x y destination map dest warp
1 2 0 FAST_SHIP_1F 5
2 2 19 FAST_SHIP_1F 6
3 3 19 FAST_SHIP_1F 6
4 2 31 FAST_SHIP_1F 7
5 3 31 FAST_SHIP_1F 7

Coord events - none.

BG events (def_bg_events)

x y type script/item
7 1 BGEVENT_READ FastShipBed (sym 5b:521b)
7 2 BGEVENT_READ FastShipBed
7 7 BGEVENT_READ FastShipCabinsNorthwestCabinTrashcan

Object events (def_object_events)

const sprite x y movement type sight script label event flag
..._FISHER SPRITE_FISHER 1 15 SPRITEMOVEDATA_SPINCOUNTERCLOCKWISE OBJECTTYPE_TRAINER 2 TrainerFirebreatherLyle EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
..._BUG_CATCHER SPRITE_BUG_CATCHER 6 15 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 2 TrainerBugCatcherKen EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
..._BEAUTY SPRITE_BEAUTY 1 26 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 3 TrainerBeautyCassie EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
..._ROCKER SPRITE_ROCKER 3 28 SPRITEMOVEDATA_SPINCOUNTERCLOCKWISE OBJECTTYPE_TRAINER 2 TrainerGuitaristClyde EVENT_FAST_SHIP_PASSENGERS_WESTBOUND

Scripts of interest

  • FastShipBed (bg_event at (7,1) / (7,2), warp-1 sub-room = your cabin): text, FadeOutToBlack, ReloadSpritesNoPalettes, special HealParty, playmusic MUSIC_HEAL, pause 60, RestartMapMusic, FadeInFromBlack. Then a docking check: skip if EVENT_FAST_SHIP_HAS_ARRIVED; otherwise checkevent EVENT_FAST_SHIP_FOUND_GIRL or checkevent EVENT_FAST_SHIP_FIRST_TIME -> .CanArrive, which plays SFX_ELEVATOR_END, prints the arrival text and setevent EVENT_FAST_SHIP_HAS_ARRIVED. Bot-relevant: on the maiden voyage, sleeping in the bed does not dock the ship, because both EVENT_FAST_SHIP_FOUND_GIRL and EVENT_FAST_SHIP_FIRST_TIME are still clear. You must finish the granddaughter errand.

Trainers

const class id party script label notes
FIREBREATHER, LYLE FIREBREATHER ($30) 8 ; FIREBREATHER (8) db "LYLE@", TRAINERTYPE_NORMAL -> L28 KOFFING, L31 FLAREON, L28 KOFFING TrainerFirebreatherLyle flag EVENT_BEAT_FIREBREATHER_LYLE

MAP_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN

  • Script: maps/FastShipCabins_SE_SSE_CaptainsCabin.asm
  • Blocks: maps/FastShipCabins_SE_SSE_CaptainsCabin.blk
  • Header: data/maps/maps.asm:338 -> map FastShipCabins_SE_SSE_CaptainsCabin, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:312 map_const FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN, 5, 17 (10 x 34 cells)
  • Layout: sub-room 1 y 0-11 (Colin + Twins), sub-room 2 y 12-23 (grandpa), sub-room 3 y 24-33 (captain's cabin).

Warps (def_warp_events)

idx x y destination map dest warp
1 2 7 FAST_SHIP_1F 8
2 3 7 FAST_SHIP_1F 8
3 2 19 FAST_SHIP_1F 9
4 3 19 FAST_SHIP_1F 9
5 2 33 FAST_SHIP_1F 10
6 3 33 FAST_SHIP_1F 10

Coord events - none.

BG events (def_bg_events)

x y type script/item
4 25 BGEVENT_READ FastShipCaptainsCabinTrashcan

Object events (def_object_events)

const sprite x y movement type sight script label event flag
..._CAPTAIN SPRITE_CAPTAIN 3 25 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 0 SSAquaCaptain -1
..._GENTLEMAN SPRITE_GENTLEMAN 2 17 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT 0 SSAquaGrandpa (sym 5b:561b) EVENT_FAST_SHIP_CABINS_SE_SSE_GENTLEMAN
..._TWIN1 SPRITE_TWIN 3 17 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_SCRIPT 0 SSAquaGranddaughterAfter EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_1
..._TWIN2 SPRITE_TWIN 2 25 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_SCRIPT 0 SSAquaGranddaughterBefore EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2
..._POKEFAN_M1 SPRITE_POKEFAN_M 5 6 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_TRAINER 5 TrainerPokefanmColin EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
..._TWIN3 SPRITE_TWIN 2 4 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_TRAINER 1 TrainerTwinsMegandpeg1 EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
..._TWIN4 SPRITE_TWIN 3 4 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_TRAINER 1 TrainerTwinsMegandpeg2 EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
..._SUPER_NERD1 SPRITE_SUPER_NERD 5 5 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_TRAINER 5 TrainerPsychicRodney EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
..._POKEFAN_M2 SPRITE_POKEFAN_M 2 3 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_TRAINER 3 TrainerPokefanmJeremy EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
..._POKEFAN_F SPRITE_POKEFAN_F 5 5 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 1 TrainerPokefanfGeorgia EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
..._SUPER_NERD2 SPRITE_SUPER_NERD 1 15 SPRITEMOVEDATA_SPINRANDOM_SLOW OBJECTTYPE_TRAINER 2 TrainerSupernerdShawn EVENT_FAST_SHIP_PASSENGERS_EASTBOUND

Scripts of interest

  • SSAquaGrandpa (talk to ..._GENTLEMAN at (2,17)): checkevent EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA -> SSAquaGotMetalCoat; checkevent EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2 (i.e. the granddaughter object is hidden = already found) -> SSAquaFoundGranddaughter; otherwise the "I can't find my granddaughter" text plus setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP.
  • SSAquaGranddaughterBefore (talk to ..._TWIN2 at (2,25) in the captain's cabin) - the payoff scene: FadeOutToBlack, disappear TWIN2, teleport the player with SSAquaCaptainsCabinWarpsToGrandpasCabinMovement (big_step RIGHT + six big_step UP), moveobject TWIN1, 3, 19 + appear, showemote EMOTE_SHOCK on the gentleman, dialogue, then setevent EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY, setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP, sjump SSAquaMetalCoatAndDocking.
  • SSAquaMetalCoatAndDocking (sym 5b:5633): verbosegiveitem METAL_COAT, iffalse .NoRoom, setevent EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA, then playsound SFX_ELEVATOR_END, pause 30, arrival text, setevent EVENT_FAST_SHIP_HAS_ARRIVED, setevent EVENT_FAST_SHIP_FOUND_GIRL. This is the docking trigger for the maiden voyage. A full bag skips the item but still docks the ship.

Items

item how obtained source (label / bg_event / hidden) one-time flag
METAL_COAT finish the granddaughter errand SSAquaMetalCoatAndDocking / SSAquaFoundGranddaughter verbosegiveitem METAL_COAT EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA

Trainers

const class id party script label notes
POKEFANM, COLIN POKEFANM ($3b) 9 ; POKEFANM (9) db "COLIN@", TRAINERTYPE_ITEM -> L32 DELIBIRD holding BERRY TrainerPokefanmColin EVENT_BEAT_POKEFANM_COLIN
TWINS, MEGANDPEG1 TWINS ($3d) 7 ; TWINS (7) db "MEG & PEG@", TRAINERTYPE_NORMAL -> L31 TEDDIURSA, L31 PHANPY TrainerTwinsMegandpeg1 shares flag EVENT_BEAT_TWINS_MEG_AND_PEG
TWINS, MEGANDPEG2 TWINS ($3d) 8 ; TWINS (8) -> L31 PHANPY, L31 TEDDIURSA TrainerTwinsMegandpeg2 same flag - beating either removes both

MAP_FAST_SHIP_B1F

  • Script: maps/FastShipB1F.asm
  • Blocks: maps/FastShipB1F.blk
  • Header: data/maps/maps.asm:339 -> map FastShipB1F, TILESET_LIGHTHOUSE, INDOOR, LANDMARK_FAST_SHIP, MUSIC_SS_AQUA, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:313 map_const FAST_SHIP_B1F, 16, 8 (32 x 16 cells)

Scene ids: SCENE_FASTSHIPB1F_SAILOR_BLOCKS = 0, SCENE_FASTSHIPB1F_NOOP = 1.

Warps (def_warp_events)

idx x y destination map dest warp
1 5 11 FAST_SHIP_1F 11
2 31 13 FAST_SHIP_1F 12

Coord events (def_coord_events)

scene x y script label effect
SCENE_FASTSHIPB1F_SAILOR_BLOCKS (0) 30 7 FastShipB1FSailorBlocksLeft if EVENT_FAST_SHIP_B1F_SAILOR_RIGHT set -> no-op; else move sailor2 left, moveobject FASTSHIPB1F_SAILOR1, 30, 6 + appear, disappear sailor2
SCENE_FASTSHIPB1F_SAILOR_BLOCKS (0) 31 7 FastShipB1FSailorBlocksRight mirror: moveobject FASTSHIPB1F_SAILOR2, 31, 6 + appear, disappear sailor1

BG events (def_bg_events)

x y type script/item
27 9 BGEVENT_READ FastShipB1FTrashcan

Object events (def_object_events)

const sprite x y movement type sight script label event flag
FASTSHIPB1F_SAILOR1 SPRITE_SAILOR 30 6 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 0 FastShipB1FSailorScript EVENT_FAST_SHIP_B1F_SAILOR_LEFT
FASTSHIPB1F_SAILOR2 SPRITE_SAILOR 31 6 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 0 FastShipB1FSailorScript EVENT_FAST_SHIP_B1F_SAILOR_RIGHT
FASTSHIPB1F_SAILOR3 SPRITE_SAILOR 9 11 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerSailorJeff EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
FASTSHIPB1F_LASS SPRITE_LASS 6 4 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 1 TrainerPicnickerDebra EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
FASTSHIPB1F_SUPER_NERD SPRITE_SUPER_NERD 26 9 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 1 TrainerJugglerFritz EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP
FASTSHIPB1F_SAILOR4 SPRITE_SAILOR 17 4 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 4 TrainerSailorGarrett EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
FASTSHIPB1F_FISHER SPRITE_FISHER 25 8 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerFisherJonah EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
FASTSHIPB1F_BLACK_BELT SPRITE_BLACK_BELT 15 11 SPRITEMOVEDATA_SPINCLOCKWISE OBJECTTYPE_TRAINER 3 TrainerBlackbeltWai EVENT_FAST_SHIP_PASSENGERS_EASTBOUND
FASTSHIPB1F_SAILOR5 SPRITE_SAILOR 23 4 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 4 TrainerSailorKenneth EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
FASTSHIPB1F_TEACHER SPRITE_TEACHER 9 11 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_TRAINER 3 TrainerTeacherShirley EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
FASTSHIPB1F_YOUNGSTER1 SPRITE_YOUNGSTER 14 9 SPRITEMOVEDATA_SPINRANDOM_SLOW OBJECTTYPE_TRAINER 1 TrainerSchoolboyNate EVENT_FAST_SHIP_PASSENGERS_WESTBOUND
FASTSHIPB1F_YOUNGSTER2 SPRITE_YOUNGSTER 14 11 SPRITEMOVEDATA_SPINRANDOM_FAST OBJECTTYPE_TRAINER 1 TrainerSchoolboyRicky EVENT_FAST_SHIP_PASSENGERS_WESTBOUND

Scripts of interest

  • FastShipB1FSailorScript (sym 5b:5e37), shared by both blocking sailors:
    • checkevent EVENT_FAST_SHIP_FIRST_TIME / iftrue .FirstTime -> on repeat trips he just gives directions and does not block the story.
    • checkevent EVENT_FAST_SHIP_LAZY_SAILOR / iftrue .LazySailor -> thanks you; if EVENT_FAST_SHIP_FOUND_GIRL is still clear he also prints FastShipB1FOnDutySailorSawLittleGirlText (the "a little girl went by" hint).
    • checkevent EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILOR / iftrue .AlreadyInformed.
    • First talk: prints the request, setevent EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILOR and clearevent EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR - this is what spawns the lazy sailor in the NNW/NNE/NE cabins map.
  • The physical block is the sailor object standing on (30,6) or (31,6); the coord events at (30,7)/(31,7) shuffle whichever sailor is active onto the tile you approached. Once FastShipLazySailorScript runs setmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP, the coord events stop firing and only one of the two tiles stays occupied.

Trainers

const class id party script label notes
SAILOR, JEFF SAILOR ($28) 6 ; SAILOR (6) db "JEFF@", TRAINERTYPE_NORMAL -> L32 RATICATE, L32 RATICATE TrainerSailorJeff EVENT_BEAT_SAILOR_JEFF
PICNICKER, DEBRA PICNICKER ($35) 8 ; PICNICKER (8) db "DEBRA@", TRAINERTYPE_NORMAL -> L33 SEAKING TrainerPicnickerDebra EVENT_BEAT_PICNICKER_DEBRA
JUGGLER, FRITZ JUGGLER ($31) 2 ; JUGGLER (2) db "FRITZ@", TRAINERTYPE_NORMAL -> L29 MR__MIME, L29 MAGMAR, L29 MACHOKE TrainerJugglerFritz EVENT_BEAT_JUGGLER_FRITZ

Note the party order in the asm is Mr. Mime, Magmar, Machoke - the walkthrough lists Mr. Mime, Machoke, Magmar.

MAP_VERMILION_PORT

  • Script: maps/VermilionPort.asm
  • Blocks: maps/VermilionPort.blk
  • Header: data/maps/maps.asm:334 -> map VermilionPort, TILESET_PORT, ROUTE, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:308 map_const VERMILION_PORT, 10, 18 (20 x 36 cells)
  • Attributes: data/maps/attributes.asm:587 map_attributes VermilionPort, VERMILION_PORT, $0a - no connections
  • Callback: callback MAPCALLBACK_NEWMAP, VermilionPortFlypointCallback -> setflag ENGINE_FLYPOINT_VERMILION

Scene ids: SCENE_VERMILIONPORT_ASK_ENTER_SHIP = 0, SCENE_VERMILIONPORT_LEAVE_SHIP = 1.

Warps (def_warp_events)

idx x y destination map dest warp
1 9 5 VERMILION_PORT_PASSAGE 5
2 7 17 FAST_SHIP_1F 1

Coord events (def_coord_events)

scene x y script label effect
SCENE_VERMILIONPORT_ASK_ENTER_SHIP (0) 7 11 VermilionPortWalkUpToShipScript boarding prompt on the way back to Johto

BG events (def_bg_events)

x y type script/item
16 13 BGEVENT_ITEM VermilionPortHiddenIron -> hiddenitem IRON, EVENT_VERMILION_PORT_HIDDEN_IRON

Object events (def_object_events)

const sprite x y movement type script label event flag
VERMILIONPORT_SAILOR1 SPRITE_SAILOR 7 17 SPRITEMOVEDATA_STANDING_UP OBJECTTYPE_SCRIPT VermilionPortSailorAtGangwayScript EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY
VERMILIONPORT_SAILOR2 SPRITE_SAILOR 6 11 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT VermilionPortSailorScript -1
VERMILIONPORT_SUPER_NERD SPRITE_SUPER_NERD 11 11 SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius 2,0) OBJECTTYPE_SCRIPT VermilionPortSuperNerdScript -1

Scripts of interest

  • VermilionPortLeaveShipScript (sym 5b:450e, scene 1, sdefer): the arrival cutscene. One step UP, appear VERMILIONPORT_SAILOR1, setscene SCENE_VERMILIONPORT_ASK_ENTER_SHIP, then the end-of-voyage bookkeeping: setevent EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_1, setevent EVENT_FAST_SHIP_CABINS_SE_SSE_GENTLEMAN (grandpa and granddaughter vanish from the ship for good), setevent EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP (the eight maiden-voyage trainers never appear again), clearevent EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M, setevent EVENT_FAST_SHIP_FIRST_TIME, setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1, blackoutmod VERMILION_CITY.
  • VermilionPortWalkUpToShipScript / VermilionPortSailorScript: readvar VAR_WEEKDAY; MONDAY/TUESDAY -> .NextShipWednesday, THURSDAY/FRIDAY/SATURDAY -> .NextShipSunday. So from Vermilion the ship sails Wednesday and Sunday, matching the walkthrough. There is no first-time bypass on this side. Boarding sets EVENT_FAST_SHIP_PASSENGERS_EASTBOUND, clears ..._WESTBOUND, clears the ten westbound EVENT_BEAT_* flags, sets EVENT_FAST_SHIP_DESTINATION_OLIVINE, setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_ENTER_SHIP, warp FAST_SHIP_1F, 25, 1.

Items

item how obtained source one-time flag
IRON hidden, face (16,13) VermilionPortHiddenIron EVENT_VERMILION_PORT_HIDDEN_IRON

Wild encounters

data/wild/kanto_water.asm:166 def_water_wildmons VERMILION_PORT, rate 2 percent: 35 TENTACOOL / 30 TENTACOOL / 35 TENTACRUEL. Fishing FISHGROUP_OCEAN.

MAP_VERMILION_PORT_PASSAGE

  • Script: maps/VermilionPortPassage.asm
  • Blocks: maps/PortPassage.blk (shared)
  • Header: data/maps/maps.asm:341 -> map VermilionPortPassage, TILESET_UNDERGROUND, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:315 map_const VERMILION_PORT_PASSAGE, 10, 9 (20 x 18 cells)

Warps (def_warp_events)

idx x y destination map dest warp
1 15 0 VERMILION_CITY 8
2 16 0 VERMILION_CITY 9
3 15 4 VERMILION_PORT_PASSAGE 4
4 3 2 VERMILION_PORT_PASSAGE 3
5 3 14 VERMILION_PORT 1

Coord events - none. BG events - none.

Object events (def_object_events)

const sprite x y movement type script label event flag
VERMILIONPORTPASSAGE_TEACHER SPRITE_TEACHER 17 1 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_SCRIPT VermilionPortPassageTeacherScript -1

MAP_VERMILION_CITY

  • Script: maps/VermilionCity.asm
  • Blocks: maps/VermilionCity.blk
  • Header: data/maps/maps.asm:296 -> map VermilionCity, TILESET_KANTO, TOWN, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN
  • Dimensions: constants/map_constants.asm:273 map_const VERMILION_CITY, 20, 18 (40 x 36 cells)
  • Attributes: data/maps/attributes.asm:342 map_attributes VermilionCity, VERMILION_CITY, $43
  • Connections: connection north, Route6, ROUTE_6, 5; connection east, Route11, ROUTE_11, 0
  • Callback: callback MAPCALLBACK_NEWMAP, VermilionCityFlypointCallback -> setflag ENGINE_FLYPOINT_VERMILION

Warps (def_warp_events)

idx x y destination map dest warp
1 5 5 VERMILION_FISHING_SPEECH_HOUSE 1
2 9 5 VERMILION_POKECENTER_1F 1
3 7 13 POKEMON_FAN_CLUB 1
4 13 13 VERMILION_MAGNET_TRAIN_SPEECH_HOUSE 1
5 21 13 VERMILION_MART 2
6 21 17 VERMILION_DIGLETTS_CAVE_SPEECH_HOUSE 1
7 10 19 VERMILION_GYM 1
8 19 31 VERMILION_PORT_PASSAGE 1
9 20 31 VERMILION_PORT_PASSAGE 2
10 34 7 DIGLETTS_CAVE 1

Coord events - none.

BG events (def_bg_events)

x y type script/item
25 3 BGEVENT_READ VermilionCitySign
5 19 BGEVENT_READ VermilionGymSign
5 13 BGEVENT_READ PokemonFanClubSign
33 9 BGEVENT_READ VermilionCityDiglettsCaveSign
27 15 BGEVENT_READ VermilionCityPortSign
10 5 BGEVENT_READ VermilionCityPokecenterSign (jumpstd PokecenterSignScript)
22 13 BGEVENT_READ VermilionCityMartSign (jumpstd MartSignScript)
12 19 BGEVENT_ITEM VermilionCityHiddenFullHeal -> hiddenitem FULL_HEAL, EVENT_VERMILION_CITY_HIDDEN_FULL_HEAL

Object events (def_object_events)

const sprite x y movement type script label event flag
VERMILIONCITY_TEACHER SPRITE_TEACHER 18 9 SPRITEMOVEDATA_WANDER (radius 1,1) OBJECTTYPE_SCRIPT VermilionCityTeacherScript -1
VERMILIONCITY_GRAMPS SPRITE_GRAMPS 23 6 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT VermilionMachopOwner -1
VERMILIONCITY_MACHOP SPRITE_MACHOP 26 7 SPRITEMOVEDATA_POKEMON OBJECTTYPE_SCRIPT VermilionMachop -1
VERMILIONCITY_SUPER_NERD SPRITE_SUPER_NERD 14 16 SPRITEMOVEDATA_WANDER (radius 1,1) OBJECTTYPE_SCRIPT VermilionCitySuperNerdScript -1
VERMILIONCITY_BIG_SNORLAX SPRITE_BIG_SNORLAX 34 8 SPRITEMOVEDATA_BIGDOLLSYM OBJECTTYPE_SCRIPT VermilionSnorlax EVENT_VERMILION_CITY_SNORLAX
VERMILIONCITY_POKEFAN_M SPRITE_POKEFAN_M 31 12 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT VermilionGymBadgeGuy -1

Scripts of interest

  • VermilionGymBadgeGuy at (31,12): readvar VAR_BADGES, ifequal NUM_BADGES, .AllBadges (16 badges -> verbosegiveitem HP_UP, EVENT_GOT_HP_UP_FROM_VERMILION_GUY), ifgreater 13, ifgreater 9 for the intermediate lines. Not reachable this section.
  • VermilionSnorlax at (34,8): special SnorlaxAwake; asleep unless the Poke Flute radio channel is playing. Awake -> loadvar VAR_BATTLETYPE, BATTLETYPE_FORCEITEM, loadwildmon SNORLAX, 50, startbattle, setevent EVENT_FOUGHT_SNORLAX. Gates warp 10 to DIGLETTS_CAVE; out of scope here but it is the reason the east side is closed.
  • The cut tree: maps/VermilionCity.blk block index (6,9) holds TILESET_KANTO block $35, whose collision quad is tilecoll FLOOR, CUT_TREE, WALL, FLOOR (data/tilesets/kanto_collision.asm row $35). That puts the cuttable tile at cell (13,18), replacement block $4c, animation 0 (data/collision/field_move_blocks.asm:31). It is the only cut tree on the map. The hidden Full Heal bg_event at (12,19) is the WALL quadrant of the same block.

Items

item how obtained source one-time flag
FULL_HEAL hidden, face (12,19) VermilionCityHiddenFullHeal EVENT_VERMILION_CITY_HIDDEN_FULL_HEAL
HP_UP all 16 badges (not this section) VermilionGymBadgeGuy .AllBadges EVENT_GOT_HP_UP_FROM_VERMILION_GUY

Wild encounters

data/wild/kanto_water.asm:138 def_water_wildmons VERMILION_CITY, rate 6 percent: 35 TENTACOOL / 30 TENTACOOL / 35 TENTACRUEL. Fishing FISHGROUP_OCEAN (data/wild/fish.asm .Ocean_Old/Good/Super, lines 42-55). No entry in kanto_grass.asm and no treemons.asm row.

MAP_POKEMON_FAN_CLUB

  • Script: maps/PokemonFanClub.asm
  • Blocks: maps/PokemonFanClub.blk
  • Header: data/maps/maps.asm:300 -> map PokemonFanClub, TILESET_HOUSE, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_VERMILION_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:277 map_const POKEMON_FAN_CLUB, 5, 4 (10 x 8 cells)

Warps (def_warp_events)

idx x y destination map dest warp
1 2 7 VERMILION_CITY 3
2 3 7 VERMILION_CITY 3

Coord events - none.

BG events (def_bg_events)

x y type script/item
7 0 BGEVENT_READ PokemonFanClubListenSign
9 0 BGEVENT_READ PokemonFanClubBraggingSign

Object events (def_object_events)

const sprite x y movement type script label event flag
POKEMONFANCLUB_CHAIRMAN SPRITE_GENTLEMAN 3 1 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT PokemonFanClubChairmanScript (sym 59:4340) -1
POKEMONFANCLUB_RECEPTIONIST SPRITE_RECEPTIONIST 4 1 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT PokemonFanClubReceptionistScript -1
POKEMONFANCLUB_CLEFAIRY_GUY SPRITE_FISHER 2 3 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_SCRIPT PokemonFanClubClefairyGuyScript -1
POKEMONFANCLUB_TEACHER SPRITE_TEACHER 7 2 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_SCRIPT PokemonFanClubTeacherScript -1
POKEMONFANCLUB_FAIRY SPRITE_FAIRY 2 4 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT PokemonFanClubClefairyDollScript EVENT_VERMILION_FAN_CLUB_DOLL
POKEMONFANCLUB_ODDISH SPRITE_ODDISH 7 3 SPRITEMOVEDATA_POKEMON OBJECTTYPE_SCRIPT PokemonFanClubBayleefScript -1

Scripts of interest

  • PokemonFanClubChairmanScript: checkevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT -> .HeardSpeech; checkevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL -> .HeardSpeechButBagFull (skips the speech, retries the gift). Otherwise yesorno on ...DidYouVisitToHearAboutMyMonText; answering No goes to .NotListening and gives nothing. Yes -> the Rapidash speech -> verbosegiveitem RARE_CANDY, iffalse .BagFull, setevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT. (Nothing in this file ever sets EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL; it is only read.)
  • PokemonFanClubClefairyGuyScript handles the LOST_ITEM / Copycat doll chain (EVENT_RETURNED_MACHINE_PART, EVENT_MET_COPYCAT_FOUND_OUT_ABOUT_LOST_ITEM, EVENT_GOT_LOST_ITEM_FROM_FAN_CLUB) - a later section.

Items

item how obtained source one-time flag
RARE_CANDY answer "Yes" and sit through the speech PokemonFanClubChairmanScript verbosegiveitem RARE_CANDY EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT

MAP_VERMILION_GYM

  • Script: maps/VermilionGym.asm
  • Blocks: maps/VermilionGym.blk
  • Header: data/maps/maps.asm:304 -> map VermilionGym, TILESET_GAME_CORNER, INDOOR, LANDMARK_VERMILION_CITY, MUSIC_GYM, TRUE, PALETTE_DAY, FISHGROUP_SHORE
  • Dimensions: constants/map_constants.asm:281 map_const VERMILION_GYM, 5, 9 (10 x 18 cells)
  • No scene scripts, no callbacks, no coord events.

Warps (def_warp_events)

idx x y destination map dest warp
1 4 17 VERMILION_CITY 7
2 5 17 VERMILION_CITY 7

Coord events - none. (The Gen 1 trash-can/switch puzzle is gone - the guide NPC even lampshades it in VermilionGymGuideText.)

BG events (def_bg_events)

x y type script/item
1 7 BGEVENT_READ VermilionGymTrashCan
3 7 BGEVENT_READ VermilionGymTrashCan
5 7 BGEVENT_READ VermilionGymTrashCan
7 7 BGEVENT_READ VermilionGymTrashCan
9 7 BGEVENT_READ VermilionGymTrashCan
1 9 BGEVENT_READ VermilionGymTrashCan
3 9 BGEVENT_READ VermilionGymTrashCan
5 9 BGEVENT_READ VermilionGymTrashCan
7 9 BGEVENT_READ VermilionGymTrashCan
9 9 BGEVENT_READ VermilionGymTrashCan
1 11 BGEVENT_READ VermilionGymTrashCan
3 11 BGEVENT_READ VermilionGymTrashCan
5 11 BGEVENT_READ VermilionGymTrashCan
7 11 BGEVENT_READ VermilionGymTrashCan
9 11 BGEVENT_READ VermilionGymTrashCan
3 15 BGEVENT_READ VermilionGymStatue
6 15 BGEVENT_READ VermilionGymStatue

VermilionGymStatue: checkflag ENGINE_THUNDERBADGE -> if set, gettrainername STRING_BUFFER_4, LT_SURGE, LT_SURGE1 + jumpstd GymStatue2Script, else jumpstd GymStatue1Script.

Object events (def_object_events)

const sprite x y movement type sight script label event flag
VERMILIONGYM_SURGE SPRITE_SURGE 5 2 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 0 VermilionGymSurgeScript (sym 59:4bfc) -1
VERMILIONGYM_GENTLEMAN SPRITE_GENTLEMAN 8 8 SPRITEMOVEDATA_STANDING_LEFT OBJECTTYPE_TRAINER 4 TrainerGentlemanGregory -1
VERMILIONGYM_ROCKER SPRITE_ROCKER 4 7 SPRITEMOVEDATA_STANDING_DOWN (radius x 3) OBJECTTYPE_TRAINER 3 TrainerGuitaristVincent -1
VERMILIONGYM_SUPER_NERD SPRITE_SUPER_NERD 0 10 SPRITEMOVEDATA_STANDING_RIGHT OBJECTTYPE_TRAINER 4 TrainerJugglerHorton -1
VERMILIONGYM_GYM_GUIDE SPRITE_GYM_GUIDE 7 15 SPRITEMOVEDATA_STANDING_DOWN OBJECTTYPE_SCRIPT 1 VermilionGymGuideScript -1

Scripts of interest

  • VermilionGymSurgeScript: checkflag ENGINE_THUNDERBADGE / iftrue .FightDone; else LtSurgeIntroText, winlosstext LtSurgeWinLossText, 0, loadtrainer LT_SURGE, LT_SURGE1, startbattle, reloadmapafterbattle, then setevent EVENT_BEAT_LTSURGE and setevent EVENT_BEAT_GENTLEMAN_GREGORY, setevent EVENT_BEAT_GUITARIST_VINCENT, setevent EVENT_BEAT_JUGGLER_HORTON - beating Surge retroactively clears the three gym trainers, so a bot may legally skip them. Then ReceivedThunderBadgeText, playsound SFX_GET_BADGE, waitsfx, setflag ENGINE_THUNDERBADGE, LtSurgeThunderBadgeText. There is no TM award in this gym script.
  • VermilionGymGuideScript branches on EVENT_BEAT_LTSURGE.

Flags and events

constant defined in read/written by meaning for a bot
ENGINE_THUNDERBADGE constants/engine_flags.asm:49 set by VermilionGymSurgeScript; read there and by VermilionGymStatue the section's terminal milestone
EVENT_BEAT_LTSURGE constants/event_flags.asm:717 set by VermilionGymSurgeScript; read by VermilionGymGuideScript post-win dialogue switch
EVENT_BEAT_GUITARIST_VINCENT / EVENT_BEAT_JUGGLER_HORTON / EVENT_BEAT_GENTLEMAN_GREGORY constants/event_flags.asm set by each trainer macro and also by Surge's script trainer already-beaten guards

Trainers

const class id party (data/trainers/parties.asm) script label rematch/phone
GUITARIST, VINCENT GUITARIST ($2b) 2 ; GUITARIST (2) db "VINCENT@", TRAINERTYPE_NORMAL -> L27 MAGNEMITE, L33 VOLTORB, L32 MAGNEMITE, L32 MAGNEMITE TrainerGuitaristVincent none
JUGGLER, HORTON JUGGLER ($31) 3 ; JUGGLER (3) db "HORTON@", TRAINERTYPE_NORMAL -> 4x L33 ELECTRODE TrainerJugglerHorton none
GENTLEMAN, GREGORY GENTLEMAN ($20) 3 ; GENTLEMAN (3) db "GREGORY@", TRAINERTYPE_NORMAL -> L37 PIKACHU, L33 FLAAFFY TrainerGentlemanGregory none
LT_SURGE, LT_SURGE1 LT_SURGE ($13) 1 data/trainers/parties.asm:289-296, TRAINERTYPE_MOVES: L44 RAICHU (Thunder Wave / Quick Attack / Thunderbolt / Thunder); L40 ELECTRODE (Screech / Double Team / Swift / Explosion); L40 MAGNETON (Lock-On / Double Team / Swift / Zap Cannon); L40 ELECTRODE (same set); L46 ELECTABUZZ (Quick Attack / ThunderPunch / Light Screen / Thunder) VermilionGymSurgeScript none

Party order is Raichu, Electrode, Magneton, Electrode, Electabuzz - the walkthrough lists Raichu, Magneton, Electabuzz, Electrode, Electrode.

Wild encounters - none (indoor).


3. Blockers and gates

Gate Enforced by (file:label) Requirement Unlock condition
Elm will not hand over the ticket maps/ElmsLab.asm ProfElmScript checkevent EVENT_BEAT_ELITE_FOUR Hall of Fame done maps/HallOfFame.asm:33 setevent EVENT_BEAT_ELITE_FOUR
Cannot board the Fast Ship maps/OlivinePort.asm OlivinePortWalkUpToShipScript / OlivinePortSailorAfterHOFScript checkitem S_S_TICKET, iffalse .NoTicket S_S_TICKET in the bag ElmGiveTicketScript
Boarding sailor absent before HOF maps/OlivinePort.asm object rows with EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME; the pre-HOF sailor's OlivinePortSailorBeforeHOFScript says "you're not allowed in" Hall of Fame done HallOfFame.asm:38 clearevent EVENT_OLIVINE_PORT_SPRITES_AFTER_HALL_OF_FAME
Ship only sails on certain days (repeat trips) OlivinePortWalkUpToShipScript readvar VAR_WEEKDAY (Mon/Fri from Olivine); VermilionPortWalkUpToShipScript (Wed/Sun from Vermilion) correct weekday maiden voyage bypasses via checkevent EVENT_FAST_SHIP_FIRST_TIME / iffalse .FirstTime
Sailor blocks the B1F corridor maps/FastShipB1F.asm coord events (30,7)/(31,7) -> FastShipB1FSailorBlocksLeft/Right plus the physical object at (30,6)/(31,6); FastShipB1FSailorScript find and beat the lazy sailor FastShipLazySailorScript -> setevent EVENT_FAST_SHIP_LAZY_SAILOR + setmapscene FAST_SHIP_B1F, SCENE_FASTSHIPB1F_NOOP
Lazy sailor does not exist yet object flag EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR, set at new game (engine/events/std_scripts.asm:499) talk to the on-duty sailor first FastShipB1FSailorScript clearevent EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR
Ship will not dock (maiden voyage) maps/FastShip1F.asm FastShip1FSailor1Script checkevent EVENT_FAST_SHIP_HAS_ARRIVED; FastShipBed .CanArrive needs EVENT_FAST_SHIP_FOUND_GIRL or EVENT_FAST_SHIP_FIRST_TIME finish the granddaughter errand SSAquaMetalCoatAndDocking setevent EVENT_FAST_SHIP_HAS_ARRIVED / EVENT_FAST_SHIP_FOUND_GIRL
Chairman's Rare Candy maps/PokemonFanClub.asm PokemonFanClubChairmanScript yesorno -> .NotListening answer Yes setevent EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT
Cut tree in Vermilion City tile collision CUT_TREE at cell (13,18) + data/collision/field_move_blocks.asm:31 db $35, $4c, 0; engine/events/overworld.asm:133 CheckAble requires ENGINE_HIVEBADGE, :169 CheckMapForSomethingToCut HM01 CUT + HIVEBADGE already held long before Kanto. Does not gate the gym - see section 6
Snorlax blocks DIGLETTS_CAVE (warp 10, (34,7)) maps/VermilionCity.asm VermilionSnorlax special SnorlaxAwake Poke Flute radio channel out of scope for this section
Lt. Surge re-battle refused VermilionGymSurgeScript checkflag ENGINE_THUNDERBADGE -> .FightDone - one-shot badge

4. Bot checklist

  1. NEW_BARK_TOWN -> walk to (6,3), warp 1, enter ELMS_LAB. Pre: EVENT_BEAT_ELITE_FOUR set. (An SPECIALCALL_SSTICKET phone call may fire on the way; answering it is optional.)
  2. ELMS_LAB -> walk to (5,3) and face up to talk to ELMSLAB_ELM at (5,2). Intent: talk. Pre: EVENT_BEAT_ELITE_FOUR, !EVENT_GOT_SS_TICKET_FROM_ELM. Post: EVENT_GOT_SS_TICKET_FROM_ELM, bag holds S_S_TICKET.
  3. Fly to OLIVINE_CITY; walk to warp 10 (19,27) -> OLIVINE_PORT_PASSAGE.
  4. OLIVINE_PORT_PASSAGE: warp 3 (15,4) -> lands at warp 4 (3,2); then walk to warp 5 (3,14) -> OLIVINE_PORT warp 1 at (11,7).
  5. OLIVINE_PORT: walk onto (7,15). Intent: walk (coord event). Post: yes/no prompt -> answer Yes; checkitem S_S_TICKET passes; the script auto-walks you 7 south and warps you to FAST_SHIP_1F (25,1). Post-flags: EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2, !EVENT_FAST_SHIP_DESTINATION_OLIVINE, scene FAST_SHIP_1F = 1. (Alternative: talk to OLIVINEPORT_SAILOR3 at (6,15) for the same flow.)
  6. FAST_SHIP_1F: the boarding cutscene runs on entry (scene 1). Then walk south to (24,6) or (25,6). Intent: walk (coord event WorriedGrandpaSceneLeft). Post: scene -> SCENE_FASTSHIP1F_NOOP; nothing else changes.
  7. FAST_SHIP_1F warp 3 at (23,8) -> FAST_SHIP_CABINS_NNW_NNE_NE (2,12). Battle TrainerHikerNoland at (4,17) (sight 3, faces up). Post: EVENT_BEAT_HIKER_NOLAND.
  8. Back to 1F; warp 5 at (15,8) -> FAST_SHIP_CABINS_SW_SSW_NW (2,0); face the bed bg_event at (7,1)/(7,2) to heal (FastShipBed -> special HealParty). Do not expect the ship to dock yet.
  9. 1F warp 6 at (15,15) -> ..._SW_SSW_NW (2,19). Battle TrainerFirebreatherLyle at (1,15). Post: EVENT_BEAT_FIREBREATHER_LYLE.
  10. 1F warp 8 at (23,15) -> ..._SE_SSE (2,7). Battle TrainerPokefanmColin at (5,6) and the twins at (2,4)/(3,4). Post: EVENT_BEAT_POKEFANM_COLIN, EVENT_BEAT_TWINS_MEG_AND_PEG.
  11. 1F warp 9 at (27,15) -> ..._SE_SSE (2,19). Talk to SSAquaGrandpa at (2,17). Post: setmapscene FAST_SHIP_1F, SCENE_FASTSHIP1F_NOOP (flavour only; the errand is not flagged here).
  12. 1F warp 12 at (30,14) -> FAST_SHIP_B1F (31,13). Walk north onto (31,7) (or (30,7)). Intent: walk (coord event) -> a sailor moves in front of you. Talk to him. Post: EVENT_FAST_SHIP_INFORMED_ABOUT_LAZY_SAILOR set, EVENT_FAST_SHIP_CABINS_NNW_NNE_NE_SAILOR cleared.
  13. Back to 1F; warp 4 at (19,8) -> ..._NNW_NNE_NE (2,24). Talk to the sailor at (4,26). Intent: talk -> forced battle SAILOR STANLY. Post: EVENT_BEAT_SAILOR_STANLY, EVENT_FAST_SHIP_LAZY_SAILOR, FAST_SHIP_B1F scene -> SCENE_FASTSHIPB1F_NOOP, party healed.
  14. FAST_SHIP_B1F again (1F warp 12 -> (31,13)): the corridor is now passable. Battle TrainerJugglerFritz at (26,9), TrainerSailorJeff at (9,11), TrainerPicnickerDebra at (6,4).
  15. FAST_SHIP_B1F warp 1 at (5,11) -> FAST_SHIP_1F (6,12); then 1F warp 10 at (3,13) -> ..._SE_SSE (2,33), the captain's cabin.
  16. Talk to the granddaughter (..._TWIN2) at (2,25). Intent: talk. Pre: !EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_2. Post: teleport cutscene, verbosegiveitem METAL_COAT, EVENT_GOT_METAL_COAT_FROM_GRANDPA_ON_SS_AQUA, EVENT_FAST_SHIP_HAS_ARRIVED, EVENT_FAST_SHIP_FOUND_GIRL, EVENT_VERMILION_PORT_SAILOR_AT_GANGWAY, 1F scene -> NOOP. You end up standing in the grandpa's sub-room; leave via warp 3/4 (2,19)/(3,19).
  17. FAST_SHIP_1F: walk to (25,3) and talk to FASTSHIP1F_SAILOR1 at (25,2). Pre: EVENT_FAST_SHIP_HAS_ARRIVED. Post: warp VERMILION_PORT, 7, 17, VERMILION_PORT scene -> SCENE_VERMILIONPORT_LEAVE_SHIP.
  18. VERMILION_PORT: the arrival scene runs (one step up). Post-flags include EVENT_FAST_SHIP_FIRST_TIME, EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP, blackoutmod VERMILION_CITY, ENGINE_FLYPOINT_VERMILION (map callback). Optional: face (16,13) for the hidden IRON.
  19. Walk to warp 1 (9,5) -> VERMILION_PORT_PASSAGE (3,14); warp 4 (3,2) -> warp 3 (15,4); walk to warps 1/2 (15,0)/(16,0) -> VERMILION_CITY (19,31)/(20,31).
  20. VERMILION_CITY -> warp 3 at (7,13) -> POKEMON_FAN_CLUB (2,7). Talk to the chairman at (3,1); answer Yes. Post: EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT, bag holds RARE_CANDY.
  21. Optional: VERMILION_POKECENTER_1F via warp 2 (9,5) to heal.
  22. Optional: face cell (13,18) and use CUT (needs ENGINE_HIVEBADGE), then face (12,19) for the hidden FULL_HEAL.
  23. VERMILION_CITY warp 7 at (10,19) -> VERMILION_GYM (4,17).
  24. Gym: TrainerGuitaristVincent at (4,7) (sight 3, faces down), TrainerJugglerHorton at (0,10) (sight 4, faces right), TrainerGentlemanGregory at (8,8) (sight 4, faces left). All three are optional - Surge's win script sets their flags.
  25. Walk to (5,3) and talk to VERMILIONGYM_SURGE at (5,2). Pre: !ENGINE_THUNDERBADGE. Intent: talk -> battle LT_SURGE, LT_SURGE1. Post: EVENT_BEAT_LTSURGE, EVENT_BEAT_GENTLEMAN_GREGORY, EVENT_BEAT_GUITARIST_VINCENT, EVENT_BEAT_JUGGLER_HORTON, ENGINE_THUNDERBADGE. Section complete.

5. Port coverage

Everything in this section is data-driven: the Gen 2 side of this repo extracts map headers, blocks, warps, coord/bg/object events and scene scripts generically (src/import/RomExtractorGen2.lua:804-977) and runs the scripts through src/script/gen2/Vm.lua. There is no per-map hand-port for any of these maps, so "implemented" below means the generic mechanism exists and the ROM data drives it, not that the beat has been played through.

Beat Port file Status
Map load: blocks, collision quads, warps by cell src/world/gen2/Map.lua implemented (generic)
Warp / coord / bg event dispatch src/world/gen2/World.lua:5013 (coord), :5148 (bg), :1183 + :5026 (scene scripts) implemented (generic)
verbosegiveitem (S.S. TICKET, METAL COAT, RARE CANDY) src/script/gen2/Vm.lua:490-522 implemented
checkitem S_S_TICKET boarding gate src/script/gen2/Vm.lua:523 implemented
loadtrainer / startbattle (Stanly, Lt. Surge) src/script/gen2/Vm.lua:806, :918 (winlosstext) implemented
OBJECTTYPE_TRAINER sight lines (ship + gym trainers) src/world/gen2/Trainers.lua:98 Trainers.sees implemented
TRAINERTYPE_MOVES parties (Lt. Surge) and TRAINERTYPE_ITEM (Colin) src/import/RomExtractorGen2.lua:3900-3968 implemented
setmapscene / sdefer scene plumbing (ports, ship, B1F) src/script/gen2/Vm.lua:92, :279 implemented
moveobject + appear sailor-shuffle on B1F src/script/gen2/Vm.lua:337-350 (the comment calls out exactly this pattern) implemented
showemote (grandpa's !) and earthquake (boarding) src/script/gen2/Vm.lua:961, :1799 implemented
blackoutmod (cabin / Vermilion respawn) src/script/gen2/Vm.lua:1136 implemented
special HealParty (bed, post-Stanly), FadeOutToWhite/Black, ReloadSpritesNoPalettes, RestartMapMusic src/script/gen2/Specials.lua:450, :998, :1025, :1059 implemented
specialphonecall SPECIALCALL_SSTICKET src/script/gen2/Vm.lua:1364; roster entry src/core/gen2/Phone.lua:395 ([5] = SPECIALCALL_SSTICKET, condition anywhere) implemented
CUT on the Vermilion tree (TILESET_KANTO $35 -> $4c, anim 0) src/world/gen2/FieldMoves.lua:191-208, :242 implemented
Hidden items (PROTEIN, IRON, FULL_HEAL) src/world/gen2/HiddenItems.lua:64, :112 implemented
ENGINE_FLYPOINT_VERMILION from the map callback src/world/gen2/FieldMoves.lua:361 (LANDMARK_VERMILION_CITY -> SPAWN_VERMILION, flag 57) implemented
readvar VAR_BADGES (Vermilion badge guy) src/world/gen2/World.lua:117, :1240 implemented
special SnorlaxAwake src/script/gen2/Specials.lua:1562 implemented
Water encounters / FISHGROUP_OCEAN at the ports src/battle/gen2/Encounter.lua not verified in this pass - no port-specific check was run
A driver that exercises the crossing end to end tests/drivers/gold_*.lua missing - no gold_fastship_*, gold_vermilion_* or gold_surge_* driver exists
Any hand-ported script for these 14 maps - missing by design; all behaviour comes from the extracted ROM script bytes

Note: the many Vermilion* hits under src/world/OverworldController.lua and src/world/FieldDefaults.lua are the Gen 1 (pokered) Vermilion Gym trash-can puzzle. That puzzle does not exist in Gold, and none of that code is on the Gen 2 path.


6. Unresolved / verify by hand

  • "cut down the tree blocking the gym" is wrong. maps/VermilionCity.blk has exactly one cuttable block, $35 at block (6,9), whose CUT_TREE quadrant is cell (13,18). The gym door is the DOOR quadrant of block $12 at (5,9) = cell (10,19), and the tiles south of it ((10,20), (11,20), (12,20)) are all FLOOR. Walking a straight path from the port entrance to the gym door never touches the tree. Cutting it only opens cell (13,18), which is beside the hidden FULL_HEAL at (12,19). Verified against data/tilesets/kanto_collision.asm rows $12, $35, $4c, $31.
  • "Meal Coat" in the walkthrough's item list is a typo for METAL_COAT (SSAquaMetalCoatAndDocking). No MEAL_* item exists.
  • Lt. Surge's party order in the walkthrough (Raichu, Magneton, Electabuzz, Electrode, Electrode) does not match data/trainers/parties.asm:289-296 (Raichu, Electrode, Magneton, Electrode, Electabuzz).
  • Juggler Fritz's party order: asm is Mr. Mime / Magmar / Machoke; the walkthrough says Mr. Mime / Machoke / Magmar.
  • "Lt. Surge has a Full Restore" - the party entry is TRAINERTYPE_MOVES, which carries no held item. Gym-leader item use is AI behaviour (data/trainers/attributes.asm / the trainer-class AI item list), which was not opened in this pass. Verify before relying on it.
  • Prize money figures ("You get: 1056G", "4600G", "???G" for Colin) are not stored anywhere in the asm as literals - Gen 2 computes them from base money x level. Not reproduced here.
  • EXP values quoted per Pokemon are party- and level-dependent runtime calculations, not table data. Not reproduced here.
  • EVENT_LISTENED_TO_FAN_CLUB_PRESIDENT_BUT_BAG_WAS_FULL is read by PokemonFanClubChairmanScript but is never setevent'd anywhere in maps/PokemonFanClub.asm. Either it is set elsewhere (nothing found by grep) or it is dead in this revision; a full-bag player appears to have to sit through the Rapidash speech again.
  • "Note the new Pokemon music for Kanto": the Vermilion maps use MUSIC_VERMILION_CITY (data/maps/maps.asm:296). Whether that is the "Kanto remix" the walkthrough means was not checked against the audio engine.
  • The walkthrough's cabin-by-cabin narration ("two cabins to the right", "the cabin next to yours") was reconciled against the 1F warp x positions (north row x = 27/23/19/15, south row x = 15/19/23/27) and is consistent, but the prose ordering of trainers within FAST_SHIP_B1F ("head left, then down") was not re-walked tile by tile.