65 KiB
Section 01 - Cherrygrove City and Routes 29-31
Source: ../section-01-cherrygrove-city-and-routes-29-31.txt
Maps covered: MAP_ROUTE_29, MAP_ROUTE_29_ROUTE_46_GATE, MAP_ROUTE_46,
MAP_CHERRYGROVE_CITY, MAP_CHERRYGROVE_POKECENTER_1F, MAP_CHERRYGROVE_MART,
MAP_GUIDE_GENTS_HOUSE, MAP_CHERRYGROVE_GYM_SPEECH_HOUSE,
MAP_CHERRYGROVE_EVOLUTION_SPEECH_HOUSE, MAP_ROUTE_30,
MAP_ROUTE_30_BERRY_HOUSE, MAP_MR_POKEMONS_HOUSE, MAP_ROUTE_31,
MAP_ROUTE_31_VIOLET_GATE, plus the return leg through MAP_NEW_BARK_TOWN,
MAP_ELMS_LAB and MAP_PLAYERS_HOUSE_1F (those three are first visited in the
previous section; only the beats this section's text drives are transcribed
here).
Badges / key milestones in this section:
- No badge. The section ends at the Violet City gate.
ENGINE_MAP_CARD(Pokegear MAP card, Guide Gent tour).ENGINE_POKEDEX(Prof. Oak, Mr. Pokemon's House).MYSTERY_EGGobtained, then handed to Elm (EVENT_GAVE_MYSTERY_EGG_TO_ELM, the single biggest content switch in the section - it opens Poke Ball sales, the Route 29 catch tutorial, the Route 30 trainers and the Bank of Mom).- Rival battle 1 in Cherrygrove City (
RIVAL1, level 5 starter). ENGINE_FLYPOINT_CHERRYGROVE, andblackoutmod CHERRYGROVE_CITY.
Coordinate convention: every warp_event / coord_event / bg_event /
object_event row below is copied verbatim from the map asm. Those x/y are map
cell coordinates starting at 0 (macros/scripts/maps.asm adds the +4 border
offset when it assembles the row, so the asm number is the one a bot wants).
Map width/height in constants/map_constants.asm is in blocks, i.e. half
the cell count in each axis - ROUTE_29 at 30, 9 is 60x18 cells, which is why
its object x values run up to 53.
1. Route order
| # | Map constant | asm file | Enter via | Leaves via | Why (walkthrough beat) |
|---|---|---|---|---|---|
| 1 | MAP_ELMS_LAB |
maps/ElmsLab.asm |
(already inside, previous section) | warps 1/2 at (4,11)/(5,11) -> NEW_BARK_TOWN warp 1 |
Aide's SCENE_ELMSLAB_AIDE_GIVES_POTION coord event hands over a POTION on the way out |
| 2 | MAP_NEW_BARK_TOWN |
maps/NewBarkTown.asm |
lab door | west edge connection | "Head west onto Route 29" |
| 3 | MAP_ROUTE_29 |
maps/Route29.asm |
east connection from New Bark | west connection to Cherrygrove | grinding, BERRY tree, POTION ball |
| 4 | MAP_ROUTE_29_ROUTE_46_GATE |
maps/Route29Route46Gate.asm |
Route 29 warp 1 at (27,1) | gate warps 1/2 -> Route 46 | optional detour "to the north is Route 46" |
| 5 | MAP_ROUTE_46 |
maps/Route46.asm |
gate warps 1/2 at (7,33)/(8,33) | back through the gate | optional Rattata / Geodude hunting |
| 6 | MAP_CHERRYGROVE_CITY |
maps/CherrygroveCity.asm |
east connection from Route 29 | north connection to Route 30 | Guide Gent tour -> MAP CARD; Pokemon Center heal |
| 7 | MAP_CHERRYGROVE_POKECENTER_1F |
maps/CherrygrovePokecenter1F.asm |
city warp 2 at (29,3) | pokecenter warps 1/2 | heal |
| 8 | MAP_ROUTE_30 |
maps/Route30.asm |
south connection from Cherrygrove | warp 2 at (17,5) | north to Mr. Pokemon; berry house; hidden POTION |
| 9 | MAP_ROUTE_30_BERRY_HOUSE |
maps/Route30BerryHouse.asm |
Route 30 warp 1 at (7,39) | house warps 1/2 | free BERRY from the Pokefan |
| 10 | MAP_MR_POKEMONS_HOUSE |
maps/MrPokemonsHouse.asm |
Route 30 warp 2 at (17,5) | house warps 1/2 | MYSTERY EGG + POKEDEX + Elm's panic call |
| 11 | MAP_CHERRYGROVE_CITY (2nd) |
maps/CherrygroveCity.asm |
south connection from Route 30 | east side, past (33,6)/(33,7) | rival battle trip-wire on the way out |
| 12 | MAP_ROUTE_29 (2nd) |
maps/Route29.asm |
west connection | east connection | walk back to New Bark |
| 13 | MAP_ELMS_LAB (2nd) |
maps/ElmsLab.asm |
New Bark warp 1 at (6,3) | lab warps 1/2 | cop names the rival; give Elm the egg; aide gives 5 POKE BALLs |
| 14 | MAP_PLAYERS_HOUSE_1F |
maps/PlayersHouse1F.asm |
New Bark warp 2 at (13,5) | house warps 1/2 | Mom starts saving money (special BankOfMom) |
| 15 | MAP_ROUTE_29 (3rd) |
maps/Route29.asm |
east connection | west connection | catch tutorial fires at (53,8)/(53,9) |
| 16 | MAP_ROUTE_46 (2nd, optional) |
maps/Route46.asm |
via the gate | via the gate | catch a Rattata |
| 17 | MAP_CHERRYGROVE_CITY (3rd) |
maps/CherrygroveCity.asm |
east connection | north connection | heal, buy POKE BALLs (mart list now MART_CHERRYGROVE_DEX) |
| 18 | MAP_ROUTE_30 (2nd) |
maps/Route30.asm |
south connection | north connection | Joey, Mikey, Don on the west fork |
| 19 | MAP_ROUTE_31 |
maps/Route31.asm |
south connection from Route 30 | warps 1/2 at (4,6)/(4,7) | Wade, ANTIDOTE, POKE BALL, BITTER BERRY, Dark Cave mouth |
| 20 | MAP_ROUTE_31_VIOLET_GATE |
maps/Route31VioletGate.asm |
Route 31 warps 1/2 | gate warps 1/2 -> VIOLET_CITY warps 8/9 |
"through the house-ish entry, and into Violet City" |
Spill-over: the text's last paragraph enters MAP_VIOLET_CITY
(maps/VioletCity.asm, header data/maps/maps.asm, connection
connection east, Route31, ROUTE_31, 9 in data/maps/attributes.asm) and points
at Sprout Tower. Violet City belongs to the next section and is not transcribed
here. MAP_DARK_CAVE_VIOLET_ENTRANCE is likewise only touched at its mouth (see
the Route 31 block and section 3).
2. Maps
MAP_ROUTE_29
- Script:
maps/Route29.asm - Blocks:
maps/Route29.blk - Header:
data/maps/maps.asm->map Route29, TILESET_JOHTO, ROUTE, LANDMARK_ROUTE_29, MUSIC_ROUTE_29, FALSE, PALETTE_AUTO, FISHGROUP_SHORE - Dimensions:
constants/map_constants.asm->map_const ROUTE_29, 30, 9(60x18 cells) - Connections (
data/maps/attributes.asm,map_attributes Route29, ROUTE_29, $05): northRoute46(offset 10), westCherrygroveCity(0), eastNewBarkTown(0) - Scenes (implicit ordinals from
def_scene_scripts):SCENE_ROUTE29_NOOP= 0,SCENE_ROUTE29_CATCH_TUTORIAL= 1
Warps (def_warp_events)
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 27 | 1 | ROUTE_29_ROUTE_46_GATE |
3 |
Coord events (def_coord_events)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_ROUTE29_CATCH_TUTORIAL |
53 | 8 | Route29Tutorial1 (4a:4d98) |
DUDE catch demo, north lane |
SCENE_ROUTE29_CATCH_TUTORIAL |
53 | 9 | Route29Tutorial2 (4a:4dce) |
DUDE catch demo, south lane |
BG events (def_bg_events)
| x | y | type | script/item |
|---|---|---|---|
| 51 | 7 | BGEVENT_READ |
Route29Sign1 |
| 3 | 5 | BGEVENT_READ |
Route29Sign2 |
Object events (def_object_events)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE29_COOLTRAINER_M1 |
SPRITE_COOLTRAINER_M |
50 | 12 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
CatchingTutorialDudeScript (4a:4e1c) |
-1 |
ROUTE29_YOUNGSTER |
SPRITE_YOUNGSTER |
27 | 16 | SPRITEMOVEDATA_WALK_UP_DOWN (radius y 1) |
OBJECTTYPE_SCRIPT |
Route29YoungsterScript |
-1 |
ROUTE29_TEACHER1 |
SPRITE_TEACHER |
15 | 11 | SPRITEMOVEDATA_WALK_LEFT_RIGHT (radius x 1) |
OBJECTTYPE_SCRIPT |
Route29TeacherScript |
-1 |
ROUTE29_FRUIT_TREE |
SPRITE_FRUIT_TREE |
12 | 2 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route29FruitTree (4a:4eb4) |
-1 |
ROUTE29_FISHER |
SPRITE_FISHER |
25 | 3 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
Route29FisherScript |
-1 |
ROUTE29_COOLTRAINER_M2 |
SPRITE_COOLTRAINER_M |
13 | 4 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
Route29CooltrainerMScript |
-1 |
ROUTE29_TUSCANY |
SPRITE_TEACHER |
29 | 12 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
TuscanyScript (4a:4e74) |
EVENT_ROUTE_29_TUSCANY_OF_TUESDAY |
ROUTE29_POKE_BALL |
SPRITE_POKE_BALL |
48 | 2 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_ITEMBALL |
Route29Potion (4a:4eb6) |
EVENT_ROUTE_29_POTION |
Scripts of interest
Route29TuscanyCallback(MAPCALLBACK_OBJECTS):checkflag ENGINE_ZEPHYRBADGE; without the badge itdisappear ROUTE29_TUSCANYunconditionally. With the badge itreadvar VAR_WEEKDAYand onlyappears her onTUESDAY. So the walkthrough's "Pink Bow" is not obtainable in this section - it needs ZEPHYRBADGE first.Route29Tutorial1/Route29Tutorial2:turnobject,showemote EMOTE_SHOCK,applymovement DudeMovementData1a/2a,setevent EVENT_DUDE_TALKED_TO_YOU,yesorno. On yes:follow ROUTE29_COOLTRAINER_M1, PLAYER,applymovement DudeMovementData1b/2b,stopfollow,loadwildmon RATTATA, 5,catchtutorial BATTLETYPE_TUTORIAL, thensetscene SCENE_ROUTE29_NOOPandsetevent EVENT_LEARNED_TO_CATCH_POKEMON. On no (Script_RefusedTutorial1/2) the scene is still cleared, so a bot that declines does not get stuck.CatchingTutorialDudeScript: repeatable demo. RequiresVAR_BOXSPACE != 0,EVENT_LEARNED_TO_CATCH_POKEMONclear andEVENT_GAVE_MYSTERY_EGG_TO_ELMset.Route29Potion:itemball POTION, one-shot onEVENT_ROUTE_29_POTION.Route29FruitTree:fruittree FRUITTREE_ROUTE_29->BERRY(data/items/fruit_trees.asm, first row).
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
SCENE_ROUTE29_CATCH_TUTORIAL |
implicit ordinal 1, maps/Route29.asm |
set by ElmAfterTheftScript (setmapscene ROUTE_29, ...) |
tutorial trip-wire armed only after the egg is delivered |
EVENT_DUDE_TALKED_TO_YOU |
constants/event_flags.asm:74 |
Route29Tutorial1/2 |
demo started |
EVENT_LEARNED_TO_CATCH_POKEMON |
constants/event_flags.asm:75 |
Route29Tutorial1/2, CatchingTutorialDudeScript |
demo finished |
EVENT_ROUTE_29_POTION |
constants/event_flags.asm:1102 |
itemball |
ball taken (object hidden when set) |
EVENT_ROUTE_29_TUSCANY_OF_TUESDAY |
constants/event_flags.asm:1275 |
Route29TuscanyCallback |
Tuscany visible when clear |
EVENT_MET_TUSCANY_OF_TUESDAY / EVENT_GOT_PINK_BOW_FROM_TUSCANY |
constants/event_flags.asm:109,110 |
TuscanyScript |
one-shot PINK BOW |
ENGINE_ZEPHYRBADGE |
constants/engine_flags.asm:38 |
Route29TuscanyCallback |
gate on Tuscany appearing at all |
Items
| item | how obtained | source (label / bg_event / hidden) | one-time flag |
|---|---|---|---|
POTION |
item ball at (48,2) | Route29Potion |
EVENT_ROUTE_29_POTION |
BERRY |
fruit tree at (12,2) | Route29FruitTree / FRUITTREE_ROUTE_29 |
daily, not an event flag |
PINK_BOW |
Tuscany at (29,12) | TuscanyScript, verbosegiveitem PINK_BOW |
EVENT_GOT_PINK_BOW_FROM_TUSCANY; needs ZEPHYRBADGE and VAR_WEEKDAY == TUESDAY |
Trainers
None (the DUDE is OBJECTTYPE_SCRIPT; his battle is catchtutorial, not a trainer).
Wild encounters
data/wild/johto_grass.asm, def_grass_wildmons ROUTE_29, rates
10 percent, 10 percent, 10 percent:
- morn / day (identical): 2 PIDGEY, 3 SENTRET, 3 PIDGEY, 2 SENTRET, 4 RATTATA, 4 PIDGEY, 4 PIDGEY
- nite: 2 HOOTHOOT, 3 HOOTHOOT, 3 HOOTHOOT, 2 RATTATA, 4 RATTATA, 4 HOOTHOOT, 4 HOOTHOOT
No def_water_wildmons ROUTE_29. Fishing group FISHGROUP_SHORE
(data/wild/fish.asm .Shore_Old/Good/Super: MAGIKARP/KRABBY).
MAP_ROUTE_29_ROUTE_46_GATE
- Script:
maps/Route29Route46Gate.asm - Blocks: shared
maps/NorthSouthGate.blk(data/maps/blocks.asm:213) - Header:
map Route29Route46Gate, TILESET_GATE, GATE, LANDMARK_ROUTE_29, MUSIC_ROUTE_29, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const ROUTE_29_ROUTE_46_GATE, 5, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 4 | 0 | ROUTE_46 |
1 |
| 2 | 5 | 0 | ROUTE_46 |
2 |
| 3 | 4 | 7 | ROUTE_29 |
1 |
| 4 | 5 | 7 | ROUTE_29 |
1 |
Coord events / BG events: none.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE29ROUTE46GATE_OFFICER |
SPRITE_OFFICER |
0 | 4 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
Route29Route46GateOfficerScript |
-1 |
ROUTE29ROUTE46GATE_YOUNGSTER |
SPRITE_YOUNGSTER |
6 | 4 | SPRITEMOVEDATA_WALK_UP_DOWN |
OBJECTTYPE_SCRIPT |
Route29Route46GateYoungsterScript |
-1 |
Both are jumptextfaceplayer only - nothing blocks.
MAP_ROUTE_46
- Script:
maps/Route46.asm - Blocks:
maps/Route46.blk - Header:
map Route46, TILESET_JOHTO, ROUTE, LANDMARK_ROUTE_46, MUSIC_ROUTE_36, FALSE, PALETTE_AUTO, FISHGROUP_SHORE - Dimensions:
map_const ROUTE_46, 10, 18(20x36 cells) - Connections: south
Route29(offset -10), eastRoute45(-36)
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 7 | 33 | ROUTE_29_ROUTE_46_GATE |
1 |
| 2 | 8 | 33 | ROUTE_29_ROUTE_46_GATE |
2 |
| 3 | 14 | 5 | DARK_CAVE_VIOLET_ENTRANCE |
3 |
Coord events: none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 9 | 27 | BGEVENT_READ |
Route46Sign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE46_POKEFAN_M |
SPRITE_POKEFAN_M |
12 | 18 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_TRAINER (sight 2) |
TrainerHikerBailey |
-1 |
ROUTE46_YOUNGSTER |
SPRITE_YOUNGSTER |
3 | 13 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER (sight 4) |
TrainerCamperTed |
-1 |
ROUTE46_LASS |
SPRITE_LASS |
1 | 15 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_TRAINER (sight 4) |
TrainerPicnickerErin1 |
-1 |
ROUTE46_FRUIT_TREE1 |
SPRITE_FRUIT_TREE |
7 | 5 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route46FruitTree1 |
-1 |
ROUTE46_FRUIT_TREE2 |
SPRITE_FRUIT_TREE |
8 | 6 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route46FruitTree2 |
-1 |
ROUTE46_POKE_BALL |
SPRITE_POKE_BALL |
0 | 12 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_ITEMBALL |
Route46DireHit |
EVENT_ROUTE_46_DIRE_HIT |
Trainers (all three are far above the walkthrough's level range at this point, and all three stand at y <= 18, i.e. past the ledges at the north end of the map)
| const | class | id | party (data/trainers/parties.asm) |
script label | rematch/phone |
|---|---|---|---|---|---|
BAILEY |
HIKER ($2c) |
11th in class | HikerGroup "BAILEY": 5x L13 GEODUDE |
TrainerHikerBailey |
no |
TED |
CAMPER ($36) |
11th in class | CamperGroup "TED": L17 MANKEY |
TrainerCamperTed |
no |
ERIN1 |
PICNICKER ($35) |
10th in class | PicnickerGroup "ERIN": L16 PONYTA, L16 PONYTA |
TrainerPicnickerErin1 |
phone PHONE_PICNICKER_ERIN, rematch gated on EVENT_BEAT_ELITE_FOUR / EVENT_RESTORED_POWER_TO_KANTO |
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
DIRE_HIT |
item ball at (0,12) | Route46DireHit |
EVENT_ROUTE_46_DIRE_HIT |
BERRY |
tree at (7,5) | FRUITTREE_ROUTE_46_1 |
daily |
PRZCUREBERRY |
tree at (8,6) | FRUITTREE_ROUTE_46_2 |
daily |
Wild encounters (def_grass_wildmons ROUTE_46, 10/10/10 percent)
- morn / day: 3 GEODUDE, 2 SPEAROW, 2 RATTATA, 2 GEODUDE, 3 SPEAROW, 3 JIGGLYPUFF, 5 JIGGLYPUFF
- nite: 3 GEODUDE, 3 RATTATA, 2 RATTATA, 2 GEODUDE, 4 GEODUDE, 3 JIGGLYPUFF, 5 JIGGLYPUFF
The walkthrough's "better chance of finding a Rattata" is true only at night (2 of 7 slots vs 1 of 7 by day); by day the slot is a single level-2 RATTATA.
MAP_CHERRYGROVE_CITY
- Script:
maps/CherrygroveCity.asm - Blocks:
maps/CherrygroveCity.blk - Header:
map CherrygroveCity, TILESET_JOHTO, TOWN, LANDMARK_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_AUTO, FISHGROUP_SHORE - Dimensions:
map_const CHERRYGROVE_CITY, 20, 9(40x18 cells) - Connections (
map_attributes CherrygroveCity, CHERRYGROVE_CITY, $35): northRoute30(offset 5), eastRoute29(0) - Spawn:
data/maps/spawn_points.asm->spawn CHERRYGROVE_CITY, 29, 4; fly pointdata/maps/flypoints.asm->db LANDMARK_CHERRYGROVE_CITY, SPAWN_CHERRYGROVE - Scenes:
SCENE_CHERRYGROVECITY_NOOP= 0,SCENE_CHERRYGROVECITY_MEET_RIVAL= 1
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 23 | 3 | CHERRYGROVE_MART |
2 |
| 2 | 29 | 3 | CHERRYGROVE_POKECENTER_1F |
1 |
| 3 | 17 | 7 | CHERRYGROVE_GYM_SPEECH_HOUSE |
1 |
| 4 | 25 | 9 | GUIDE_GENTS_HOUSE |
1 |
| 5 | 31 | 11 | CHERRYGROVE_EVOLUTION_SPEECH_HOUSE |
1 |
Coord events
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_CHERRYGROVECITY_MEET_RIVAL |
33 | 6 | CherrygroveRivalSceneNorth (48:4479) |
rival walks in and battles |
SCENE_CHERRYGROVECITY_MEET_RIVAL |
33 | 7 | CherrygroveRivalSceneSouth (48:4475) |
same, after moveobject CHERRYGROVECITY_RIVAL, 39, 7 |
BG events
| x | y | type | script/item |
|---|---|---|---|
| 30 | 8 | BGEVENT_READ |
CherrygroveCitySign |
| 23 | 9 | BGEVENT_READ |
GuideGentsHouseSign |
| 24 | 3 | BGEVENT_READ |
CherrygroveCityMartSign |
| 30 | 3 | BGEVENT_READ |
CherrygroveCityPokecenterSign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
CHERRYGROVECITY_GRAMPS |
SPRITE_GRAMPS |
32 | 6 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
CherrygroveCityGuideGent (48:43de) |
EVENT_GUIDE_GENT_IN_HIS_HOUSE |
CHERRYGROVECITY_RIVAL |
SPRITE_RIVAL |
39 | 6 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
ObjectEvent |
EVENT_RIVAL_CHERRYGROVE_CITY |
CHERRYGROVECITY_TEACHER |
SPRITE_TEACHER |
27 | 12 | SPRITEMOVEDATA_WALK_LEFT_RIGHT |
OBJECTTYPE_SCRIPT |
CherrygroveTeacherScript |
-1 |
CHERRYGROVECITY_YOUNGSTER |
SPRITE_YOUNGSTER |
23 | 7 | SPRITEMOVEDATA_WALK_LEFT_RIGHT |
OBJECTTYPE_SCRIPT |
CherrygroveYoungsterScript |
-1 |
CHERRYGROVECITY_FISHER |
SPRITE_FISHER |
7 | 12 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
MysticWaterGuy |
-1 |
Object visibility rule (verified in engine/overworld/map_objects_2.asm
CheckObjectFlag and engine/overworld/scripting.asm
ApplyEventActionAppearDisappear): an object is masked when its event flag is
SET. appear clears the flag, disappear sets it.
Scripts of interest
CherrygroveCityFlypointCallback(MAPCALLBACK_NEWMAP):setflag ENGINE_FLYPOINT_CHERRYGROVE. Entering the map once is enough.CherrygroveCityGuideGent(48:43de):yesorno. On yes itplaymusic MUSIC_SHOW_ME_AROUND,follow CHERRYGROVECITY_GRAMPS, PLAYER, then fiveapplymovement GuideGentMovement1..5legs (Pokecenter -> Mart -> Route 30 -> sea -> his house),getstring STRING_BUFFER_4, "MAP CARD",jumpstd ReceiveItemScript,setflag ENGINE_MAP_CARD,stopfollow,applymovement GuideGentMovement6,disappear CHERRYGROVECITY_GRAMPS(-> setsEVENT_GUIDE_GENT_IN_HIS_HOUSE) andclearevent EVENT_GUIDE_GENT_VISIBLE_IN_CHERRYGROVE(-> makes the indoor gramps inGuideGentsHouse.asmappear). Declining leaves everything unchanged and he can be re-asked.CherrygroveRivalSceneNorth/...South(48:4479/48:4475):special FadeOutMusic,appear CHERRYGROVECITY_RIVAL,applymovement CherrygroveCity_RivalWalksToYou(5xstep LEFT),playmusic MUSIC_RIVAL_ENCOUNTER, then the starter fork -checkevent EVENT_GOT_TOTODILE_FROM_ELM->RIVAL1_1_CHIKORITA,checkevent EVENT_GOT_CHIKORITA_FROM_ELM->RIVAL1_1_CYNDAQUIL, otherwiseRIVAL1_1_TOTODILE. Alwaysloadvar VAR_BATTLETYPE, BATTLETYPE_CANLOSE, so losing does not black you out. After either outcome:applymovement PLAYER, CherrygroveCity_RivalPushesYouOutOfTheWay(big_step DOWN),applymovement CHERRYGROVECITY_RIVAL, CherrygroveCity_RivalExitsStageLeft,disappear CHERRYGROVECITY_RIVAL,setscene SCENE_CHERRYGROVECITY_NOOP,special HealParty.MysticWaterGuyat (7,12): freeMYSTIC_WATERviaverbosegiveitem, one-shot onEVENT_GOT_MYSTIC_WATER_IN_CHERRYGROVE. The walkthrough never mentions it.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
ENGINE_MAP_CARD |
constants/engine_flags.asm:5 |
CherrygroveCityGuideGent |
Pokegear MAP card; CherrygroveTeacherScript reads it |
ENGINE_FLYPOINT_CHERRYGROVE |
constants/engine_flags.asm:80 |
map callback | Fly destination unlocked on first entry |
ENGINE_POKEDEX |
constants/engine_flags.asm:20 |
set in MrPokemonsHouse_OakScript, read by CherrygroveYoungsterScript |
dex owned |
EVENT_GUIDE_GENT_IN_HIS_HOUSE |
constants/event_flags.asm:1184 |
disappear at end of tour |
outdoor gramps hidden when set |
EVENT_GUIDE_GENT_VISIBLE_IN_CHERRYGROVE |
constants/event_flags.asm:1185 |
set at new game by InitializeEventsScript, cleared at end of tour |
indoor gramps hidden while set |
EVENT_RIVAL_CHERRYGROVE_CITY |
constants/event_flags.asm:1120 |
set by InitializeEventsScript and ElmDirectionsScript; cleared by appear in the scene |
rival object hidden until the scene runs |
SCENE_CHERRYGROVECITY_MEET_RIVAL |
ordinal 1, maps/CherrygroveCity.asm |
armed by MrPokemonsHouse_OakScript (setmapscene CHERRYGROVE_CITY, ...) |
rival trip-wire only after the Pokedex |
EVENT_GOT_MYSTIC_WATER_IN_CHERRYGROVE |
constants/event_flags.asm:86 |
MysticWaterGuy |
one-shot |
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
MAP CARD (ENGINE_MAP_CARD, not a bag item) |
finish the Guide Gent tour | CherrygroveCityGuideGent |
engine flag, not an event |
MYSTIC_WATER |
talk to the fisher at (7,12) | MysticWaterGuy |
EVENT_GOT_MYSTIC_WATER_IN_CHERRYGROVE |
Trainers
| const | class | id | party | script label | rematch/phone |
|---|---|---|---|---|---|
RIVAL1_1_CHIKORITA / RIVAL1_1_CYNDAQUIL / RIVAL1_1_TOTODILE |
RIVAL1 (class 9) |
1 / 2 / 3 | Rival1Group entries 1-3: a single level 5 starter |
CherrygroveRivalSceneNorth / ...South |
one-off |
Prize money: data/trainers/attributes.asm "Rival1" db 15 ; base reward;
ComputeTrainerReward (engine/battle/read_trainer_party.asm:300) is
base * level of the last mon, and engine/battle/core.asm:2340-2361 pays that
amount four times (ld c, 4 loop across Mom's account and the wallet).
15 * 5 * 4 = 300, which is exactly the walkthrough's "You get: 300G".
Wild encounters
No def_grass_wildmons CHERRYGROVE_CITY and no water table. Surf/fish only via
FISHGROUP_SHORE.
MAP_CHERRYGROVE_POKECENTER_1F
- Script:
maps/CherrygrovePokecenter1F.asm - Blocks: shared
maps/Pokecenter1F.blk(data/maps/blocks.asm:363) - Header:
map CherrygrovePokecenter1F, TILESET_POKECENTER, INDOOR, LANDMARK_CHERRYGROVE_CITY, MUSIC_POKEMON_CENTER, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const CHERRYGROVE_POKECENTER_1F, 5, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 3 | 7 | CHERRYGROVE_CITY |
2 |
| 2 | 4 | 7 | CHERRYGROVE_CITY |
2 |
| 3 | 0 | 7 | POKECENTER_2F |
1 |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
CHERRYGROVEPOKECENTER1F_NURSE |
SPRITE_NURSE |
3 | 1 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
CherrygrovePokecenter1FNurseScript (jumpstd PokecenterNurseScript) |
-1 |
CHERRYGROVEPOKECENTER1F_FISHER |
SPRITE_FISHER |
2 | 3 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
CherrygrovePokecenter1FFisherScript |
-1 |
CHERRYGROVEPOKECENTER1F_GENTLEMAN |
SPRITE_GENTLEMAN |
8 | 6 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
CherrygrovePokecenter1FGentlemanScript |
-1 |
CHERRYGROVEPOKECENTER1F_TEACHER |
SPRITE_TEACHER |
1 | 6 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
CherrygrovePokecenter1FTeacherScript |
-1 |
No coord or bg events. Heal = talk to the nurse at (3,1) from (3,2).
MAP_CHERRYGROVE_MART
- Script:
maps/CherrygroveMart.asm - Blocks: shared
maps/Mart.blk(data/maps/blocks.asm:334) - Header:
map CherrygroveMart, TILESET_MART, INDOOR, LANDMARK_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const CHERRYGROVE_MART, 6, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 7 | CHERRYGROVE_CITY |
1 |
| 2 | 3 | 7 | CHERRYGROVE_CITY |
1 |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
CHERRYGROVEMART_CLERK |
SPRITE_CLERK |
1 | 3 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
CherrygroveMartClerkScript |
-1 |
CHERRYGROVEMART_COOLTRAINER_M |
SPRITE_COOLTRAINER_M |
7 | 6 | SPRITEMOVEDATA_WALK_LEFT_RIGHT |
OBJECTTYPE_SCRIPT |
CherrygroveMartCooltrainerMScript |
-1 |
CHERRYGROVEMART_YOUNGSTER |
SPRITE_YOUNGSTER |
2 | 5 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
CherrygroveMartYoungsterScript |
-1 |
Scripts of interest
CherrygroveMartClerkScript: checkevent EVENT_GAVE_MYSTERY_EGG_TO_ELM.
False -> pokemart MARTTYPE_STANDARD, MART_CHERRYGROVE; true ->
pokemart MARTTYPE_STANDARD, MART_CHERRYGROVE_DEX.
data/items/marts.asm:
MartCherrygrove: POTION, ANTIDOTE, PARLYZ_HEAL, AWAKENINGMartCherrygroveDex: POKE_BALL, POTION, ANTIDOTE, PARLYZ_HEAL, AWAKENING
This is the asm behind the walkthrough's "Don't bother trying to get Pokeballs because they aren't being sold just yet."
MAP_GUIDE_GENTS_HOUSE
- Script:
maps/GuideGentsHouse.asm - Blocks: shared
maps/House1.blk(data/maps/blocks.asm:198-201) - Header:
map GuideGentsHouse, TILESET_HOUSE, INDOOR, LANDMARK_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const GUIDE_GENTS_HOUSE, 4, 4
Warps: 1 (2,7) and 2 (3,7), both -> CHERRYGROVE_CITY warp 4.
BG events: (0,1) and (1,1) BGEVENT_READ GuideGentsHouseBookshelf.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
GUIDEGENTSHOUSE_GRAMPS |
SPRITE_GRAMPS |
2 | 3 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
GuideGentsHouseGuideGent |
EVENT_GUIDE_GENT_VISIBLE_IN_CHERRYGROVE |
MAP_CHERRYGROVE_GYM_SPEECH_HOUSE
- Script:
maps/CherrygroveGymSpeechHouse.asm; blocks sharedmaps/House1.blk - Header:
map CherrygroveGymSpeechHouse, TILESET_HOUSE, INDOOR, LANDMARK_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const CHERRYGROVE_GYM_SPEECH_HOUSE, 4, 4 - Warps: 1 (2,7), 2 (3,7) ->
CHERRYGROVE_CITYwarp 3 - BG: (0,1), (1,1)
PictureBookshelfScript - Objects:
CHERRYGROVEGYMSPEECHHOUSE_POKEFAN_Mat (2,3),..._BUG_CATCHERat (5,5); both plainjumptextfaceplayer, no flags
MAP_CHERRYGROVE_EVOLUTION_SPEECH_HOUSE
- Script:
maps/CherrygroveEvolutionSpeechHouse.asm; blocks sharedmaps/House1.blk - Header:
map CherrygroveEvolutionSpeechHouse, TILESET_HOUSE, INDOOR, LANDMARK_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const CHERRYGROVE_EVOLUTION_SPEECH_HOUSE, 4, 4 - Warps: 1 (2,7), 2 (3,7) ->
CHERRYGROVE_CITYwarp 5 - BG: (0,1), (1,1)
MagazineBookshelfScript - Objects:
..._LASSat (3,5),..._YOUNGSTERat (2,5); bothopentext/writetextonly (note: nofaceplayer, so they must be talked to from the side they face)
MAP_ROUTE_30
- Script:
maps/Route30.asm - Blocks:
maps/Route30.blk - Header:
map Route30, TILESET_JOHTO, ROUTE, LANDMARK_ROUTE_30, MUSIC_ROUTE_30, FALSE, PALETTE_AUTO, FISHGROUP_POND - Dimensions:
map_const ROUTE_30, 10, 27(20x54 cells; y grows southward, so Cherrygrove is at high y and Route 31 at y=0) - Connections (
map_attributes Route30, ROUTE_30, $05): northRoute31(-10), southCherrygroveCity(-5) - Scenes: none (
def_scene_scriptsis empty). No callbacks.
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 7 | 39 | ROUTE_30_BERRY_HOUSE |
1 |
| 2 | 17 | 5 | MR_POKEMONS_HOUSE |
1 |
Coord events: none. The "you can't pass that area just yet" block is done with objects, not a coord event (see gates).
BG events
| x | y | type | script/item |
|---|---|---|---|
| 9 | 43 | BGEVENT_READ |
Route30Sign |
| 13 | 29 | BGEVENT_READ |
MrPokemonsHouseDirectionsSign |
| 15 | 5 | BGEVENT_READ |
MrPokemonsHouseSign |
| 3 | 21 | BGEVENT_READ |
Route30TrainerTips |
| 14 | 9 | BGEVENT_ITEM |
Route30HiddenPotion (4a:55a2) = hiddenitem POTION, EVENT_ROUTE_30_HIDDEN_POTION |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE30_YOUNGSTER1 |
SPRITE_YOUNGSTER |
5 | 26 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
YoungsterJoey_ImportantBattleScript |
EVENT_ROUTE_30_BATTLE |
ROUTE30_YOUNGSTER2 |
SPRITE_YOUNGSTER |
6 | 29 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_TRAINER (sight 4) |
TrainerYoungsterJoey (4a:54c5) |
EVENT_ROUTE_30_YOUNGSTER_JOEY |
ROUTE30_YOUNGSTER3 |
SPRITE_YOUNGSTER |
5 | 23 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_TRAINER (sight 1) |
TrainerYoungsterMikey (4a:5553) |
-1 |
ROUTE30_BUG_CATCHER |
SPRITE_BUG_CATCHER |
4 | 7 | SPRITEMOVEDATA_SPINRANDOM_FAST |
OBJECTTYPE_TRAINER (sight 3) |
TrainerBugCatcherDon (4a:5567) |
-1 |
ROUTE30_YOUNGSTER4 |
SPRITE_YOUNGSTER |
7 | 31 | SPRITEMOVEDATA_WALK_LEFT_RIGHT |
OBJECTTYPE_SCRIPT |
Route30YoungsterScript |
-1 |
ROUTE30_MONSTER1 |
SPRITE_MONSTER |
5 | 24 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
ObjectEvent |
EVENT_ROUTE_30_BATTLE |
ROUTE30_MONSTER2 |
SPRITE_MONSTER |
5 | 25 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
ObjectEvent |
EVENT_ROUTE_30_BATTLE |
ROUTE30_FRUIT_TREE1 |
SPRITE_FRUIT_TREE |
5 | 39 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route30FruitTree1 (4a:559e) |
-1 |
ROUTE30_FRUIT_TREE2 |
SPRITE_FRUIT_TREE |
11 | 5 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route30FruitTree2 (4a:55a0) |
-1 |
ROUTE30_COOLTRAINER_F |
SPRITE_COOLTRAINER_F |
2 | 13 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
Route30CooltrainerFScript |
-1 |
Scripts of interest
YoungsterJoey_ImportantBattleScript(the three objects flaggedEVENT_ROUTE_30_BATTLEat (5,24), (5,25), (5,26)): a cutscene, not a battle -playmusic MUSIC_JOHTO_TRAINER_BATTLE, twoapplymovementlunges, "Leave me alone!",special RestartMapMusic,end. While the flag is clear these three objects occupy the west lane at x=5, which is what stops the player walking north on the left fork.TrainerYoungsterJoey:trainer YOUNGSTER, JOEY1, EVENT_BEAT_YOUNGSTER_JOEY, ...then the phone chain -checkcellnum PHONE_YOUNGSTER_JOEY,EVENT_JOEY_ASKED_FOR_PHONE_NUMBER,askforphonenumber PHONE_YOUNGSTER_JOEY. Rematches pickJOEY2(ENGINE_FLYPOINT_GOLDENROD) orJOEY3(ENGINE_FLYPOINT_OLIVINE).TrainerYoungsterMikey,TrainerBugCatcherDon: plaintrainer+endifjustbattled.Route30YoungsterScriptat (7,31): text switches onEVENT_GAVE_MYSTERY_EGG_TO_ELM.Route30HiddenPotion:hiddenitem POTION, EVENT_ROUTE_30_HIDDEN_POTION- aBGEVENT_ITEMbg event, so it is picked up by pressing A on (14,9), not by stepping on it.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
EVENT_ROUTE_30_BATTLE |
constants/event_flags.asm:1206 |
set by ElmAfterTheftScript |
when set, the three blockers vanish and the west fork opens |
EVENT_ROUTE_30_YOUNGSTER_JOEY |
constants/event_flags.asm:1207 |
set at new game by InitializeEventsScript (engine/events/std_scripts.asm:476), cleared by ElmAfterTheftScript |
Joey the trainer only exists after the egg hand-in |
EVENT_BEAT_YOUNGSTER_JOEY / ..._MIKEY / EVENT_BEAT_BUG_CATCHER_DON |
constants/event_flags.asm:963,964,839 |
trainer macro |
battle already won |
EVENT_ROUTE_30_HIDDEN_POTION |
constants/event_flags.asm:174 |
hiddenitem |
hidden POTION taken |
EVENT_GOT_BERRY_FROM_ROUTE_30_HOUSE |
constants/event_flags.asm:48 |
Route30BerryHousePokefanMScript |
free BERRY taken |
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
POTION |
hidden, press A facing (14,9) | Route30HiddenPotion bg event |
EVENT_ROUTE_30_HIDDEN_POTION |
BERRY |
tree at (5,39) | FRUITTREE_ROUTE_30_1 |
daily |
PSNCUREBERRY |
tree at (11,5) | FRUITTREE_ROUTE_30_2 |
daily |
BERRY |
Pokefan inside the berry house | Route30BerryHousePokefanMScript (62:455c) |
EVENT_GOT_BERRY_FROM_ROUTE_30_HOUSE |
MYSTERY_EGG, POKEDEX |
Mr. Pokemon's House (below) |
Trainers
| const | class | id | party (data/trainers/parties.asm) |
script label | rematch/phone |
|---|---|---|---|---|---|
JOEY1 |
YOUNGSTER ($10) |
1 | YoungsterGroup (1) "JOEY": L4 RATTATA |
TrainerYoungsterJoey |
yes, PHONE_YOUNGSTER_JOEY; JOEY2 = L15 RATTATA, JOEY3 = L21 RATICATE (TAIL_WHIP, QUICK_ATTACK, HYPER_FANG, SCARY_FACE) |
MIKEY |
YOUNGSTER |
2 | YoungsterGroup (2) "MIKEY": L2 PIDGEY, L4 RATTATA |
TrainerYoungsterMikey |
no |
DON |
BUG_CATCHER ($18) |
1 | BugCatcherGroup (1) "DON": L3 CATERPIE, L3 CATERPIE |
TrainerBugCatcherDon |
no |
Base rewards: YOUNGSTER db 4, BUG_CATCHER db 4
(data/trainers/attributes.asm), paid 4x -> Joey 444 = 64G, Mikey 444 = 64G,
Don 434 = 48G. All three match the walkthrough.
Wild encounters (def_grass_wildmons ROUTE_30, 10/10/10 percent; the file is
IF DEF(_GOLD) ... ELIF DEF(_SILVER))
Gold:
- morn: 2 PIDGEY, 3 CATERPIE, 4 CATERPIE, 4 METAPOD, 4 PIDGEY, 4 PIDGEY, 4 PIDGEY
- day: 2 PIDGEY, 3 CATERPIE, 4 PIDGEY, 4 METAPOD, 4 CATERPIE, 5 METAPOD, 5 METAPOD
- nite: 3 SPINARAK, 3 RATTATA, 4 HOOTHOOT, 4 RATTATA, 4 HOOTHOOT, 4 HOOTHOOT, 4 HOOTHOOT
Silver (for contrast, since the walkthrough lists both): LEDYBA/WEEDLE/KAKUNA in the morn/day rows, HOOTHOOT/RATTATA at nite.
Water (data/wild/johto_water.asm, def_water_wildmons ROUTE_30, 2 percent):
20 POLIWAG, 15 POLIWAG, 20 POLIWHIRL - surf only, so not reachable in this section.
Fishing group FISHGROUP_POND (.Pond_Old: MAGIKARP/POLIWAG).
MAP_ROUTE_30_BERRY_HOUSE
- Script:
maps/Route30BerryHouse.asm; blocks sharedmaps/House1.blk - Header:
map Route30BerryHouse, TILESET_HOUSE, INDOOR, LANDMARK_ROUTE_30, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const ROUTE_30_BERRY_HOUSE, 4, 4
Warps: 1 (2,7), 2 (3,7) -> ROUTE_30 warp 1.
BG events: (0,1), (1,1) MagazineBookshelfScript.
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE30BERRYHOUSE_POKEFAN_M |
SPRITE_POKEFAN_M |
2 | 3 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
Route30BerryHousePokefanMScript (62:455c) |
-1 |
Script: checkevent EVENT_GOT_BERRY_FROM_ROUTE_30_HOUSE; if clear,
verbosegiveitem BERRY then set the event.
MAP_MR_POKEMONS_HOUSE
- Script:
maps/MrPokemonsHouse.asm - Blocks:
maps/MrPokemonsHouse.blk(data/maps/blocks.asm:940) - Header:
map MrPokemonsHouse, TILESET_FACILITY, INDOOR, LANDMARK_ROUTE_30, MUSIC_CHERRYGROVE_CITY, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const MR_POKEMONS_HOUSE, 4, 4 - Scenes:
SCENE_MRPOKEMONSHOUSE_MEET_MR_POKEMON= 0,SCENE_MRPOKEMONSHOUSE_NOOP= 1
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 2 | 7 | ROUTE_30 |
2 |
| 2 | 3 | 7 | ROUTE_30 |
2 |
Coord events: none - the cutscene is a scene script
(scene_script MrPokemonsHouseMeetMrPokemonScene, SCENE_MRPOKEMONSHOUSE_MEET_MR_POKEMON
-> sdefer MrPokemonsHouseMrPokemonEventScript), so it fires on map load.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 0 | 1 | BGEVENT_READ |
MrPokemonsHouse_ForeignMagazines |
| 1 | 1 | BGEVENT_READ |
MrPokemonsHouse_ForeignMagazines |
| 6 | 1 | BGEVENT_READ |
MrPokemonsHouse_BrokenComputer |
| 7 | 1 | BGEVENT_READ |
MrPokemonsHouse_BrokenComputer |
| 6 | 4 | BGEVENT_READ |
MrPokemonsHouse_StrangeCoins |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
MRPOKEMONSHOUSE_GENTLEMAN |
SPRITE_GENTLEMAN |
3 | 5 | SPRITEMOVEDATA_STANDING_RIGHT |
OBJECTTYPE_SCRIPT |
MrPokemonsHouse_MrPokemonScript |
-1 |
MRPOKEMONSHOUSE_OAK |
SPRITE_OAK |
6 | 5 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
ObjectEvent |
EVENT_MR_POKEMONS_HOUSE_OAK |
Scripts of interest
MrPokemonsHouseMrPokemonEventScript(62:464e):showemote EMOTE_SHOCK,applymovement PLAYER, MrPokemonsHouse_PlayerWalksToMrPokemon(step RIGHT,step UP),giveitem MYSTERY_EGG,itemnotify,setevent EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON,blackoutmod CHERRYGROVE_CITY(respawn point moves), then falls into the Oak script.MrPokemonsHouse_OakScript(62:46c1):playmusic MUSIC_PROF_OAK,applymovement MRPOKEMONSHOUSE_OAK, MrPokemonsHouse_OakWalksToPlayer,setflag ENGINE_POKEDEX,disappear MRPOKEMONSHOUSE_OAK,special HealParty(Mr. Pokemon's free heal the walkthrough mentions), then the whole post-visit world state:setevent EVENT_RIVAL_NEW_BARK_TOWNsetscene SCENE_MRPOKEMONSHOUSE_NOOPsetmapscene CHERRYGROVE_CITY, SCENE_CHERRYGROVECITY_MEET_RIVALsetmapscene ELMS_LAB, SCENE_ELMSLAB_MEET_OFFICERspecialphonecall SPECIALCALL_ROBBEDclearevent EVENT_COP_IN_ELMS_LAB(cop appears)- starter fork: sets
EVENT_TOTODILE_POKEBALL_IN_ELMS_LAB/EVENT_CHIKORITA_POKEBALL_IN_ELMS_LAB/EVENT_CYNDAQUIL_POKEBALL_IN_ELMS_LAB(which ball is missing in the lab afterwards).
MrPokemonsHouse_MrPokemonScript: repeat talk. Also the RED_SCALE ->EXP_SHAREtrade, far outside this section.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON |
constants/event_flags.asm:39 |
this scene | egg in bag |
ENGINE_POKEDEX |
constants/engine_flags.asm:20 |
MrPokemonsHouse_OakScript |
dex owned |
EVENT_MR_POKEMONS_HOUSE_OAK |
constants/event_flags.asm:1131 |
disappear MRPOKEMONSHOUSE_OAK |
Oak gone |
SPECIALCALL_ROBBED |
constants/phone_constants.asm:46 |
queued here, delivered by ElmPhoneCallerScript .disaster (engine/phone/scripts/elm.asm:75) |
that call also does setevent EVENT_ELM_CALLED_ABOUT_STOLEN_POKEMON |
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
MYSTERY_EGG |
scene on entry | giveitem MYSTERY_EGG in MrPokemonsHouseMrPokemonEventScript |
EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON |
POKEDEX (ENGINE_POKEDEX) |
same scene | MrPokemonsHouse_OakScript |
engine flag |
MAP_ROUTE_31
- Script:
maps/Route31.asm - Blocks:
maps/Route31.blk - Header:
map Route31, TILESET_JOHTO, ROUTE, LANDMARK_ROUTE_31, MUSIC_ROUTE_30, FALSE, PALETTE_AUTO, FISHGROUP_POND - Dimensions:
map_const ROUTE_31, 20, 9(40x18 cells) - Connections: south
Route30(offset 10), westVioletCity(-9) - Callbacks:
callback MAPCALLBACK_NEWMAP, Route31CheckMomCallCallback
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 4 | 6 | ROUTE_31_VIOLET_GATE |
3 |
| 2 | 4 | 7 | ROUTE_31_VIOLET_GATE |
4 |
| 3 | 34 | 5 | DARK_CAVE_VIOLET_ENTRANCE |
1 |
Coord events: none.
BG events
| x | y | type | script/item |
|---|---|---|---|
| 7 | 5 | BGEVENT_READ |
Route31Sign |
| 31 | 5 | BGEVENT_READ |
DarkCaveSign |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE31_FISHER |
SPRITE_FISHER |
17 | 7 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
Route31MailRecipientScript |
-1 |
ROUTE31_YOUNGSTER |
SPRITE_YOUNGSTER |
9 | 5 | SPRITEMOVEDATA_WANDER (radius 1,1) |
OBJECTTYPE_SCRIPT |
Route31YoungsterScript |
-1 |
ROUTE31_BUG_CATCHER |
SPRITE_BUG_CATCHER |
18 | 15 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_TRAINER (sight 3) |
TrainerBugCatcherWade1 (4a:5a01) |
-1 |
ROUTE31_COOLTRAINER_M |
SPRITE_COOLTRAINER_M |
33 | 8 | SPRITEMOVEDATA_WANDER (radius 1,1) |
OBJECTTYPE_SCRIPT |
Route31CooltrainerMScript |
-1 |
ROUTE31_FRUIT_TREE |
SPRITE_FRUIT_TREE |
16 | 7 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_SCRIPT |
Route31FruitTree (4a:5b18) |
-1 |
ROUTE31_POKE_BALL1 |
SPRITE_POKE_BALL |
29 | 5 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_ITEMBALL |
Route31Antidote (4a:5b1a) |
EVENT_ROUTE_31_ANTIDOTE |
ROUTE31_POKE_BALL2 |
SPRITE_POKE_BALL |
21 | 13 | SPRITEMOVEDATA_STILL |
OBJECTTYPE_ITEMBALL |
Route31PokeBall (4a:5b1c) |
EVENT_ROUTE_31_POKE_BALL |
Scripts of interest
Route31CheckMomCallCallback(MAPCALLBACK_NEWMAP):checkevent EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST; if false,specialphonecall SPECIALCALL_WORRIED. A bot that skips the Bank of Mom talk gets a scripted call the first time it walks onto Route 31.TrainerBugCatcherWade1:trainer BUG_CATCHER, WADE1, EVENT_BEAT_BUG_CATCHER_WADE, ..., phone chain onPHONE_BUG_CATCHER_WADE, rematchesWADE2/WADE3gated onENGINE_FLYPOINT_GOLDENROD/ENGINE_FLYPOINT_MAHOGANY.Route31MailRecipientScriptat (17,7): the Kenya / SPEAROW-with-mail sidequest (EVENT_GOT_KENYA->checkpokemail->verbosegiveitem TM_NIGHTMARE). Kenya comes from Goldenrod, so this is dormant in this section.Route31YoungsterScript: the FALKNER / Violet Gym hint.
Flags and events
| constant | defined in | read/written by | meaning for a bot |
|---|---|---|---|
EVENT_ROUTE_31_ANTIDOTE |
constants/event_flags.asm:1103 |
itemball |
ball at (29,5) taken |
EVENT_ROUTE_31_POKE_BALL |
constants/event_flags.asm:1104 |
itemball |
ball at (21,13) taken |
EVENT_BEAT_BUG_CATCHER_WADE |
constants/event_flags.asm:842 |
trainer macro |
Wade beaten |
EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST |
constants/event_flags.asm:73 |
read by the map callback, set by MomScript |
suppresses the "worried Mom" call |
SPECIALCALL_WORRIED |
constants/phone_constants.asm:51 |
map callback | queued call |
Items
| item | how obtained | source | one-time flag |
|---|---|---|---|
ANTIDOTE |
item ball at (29,5), just west of the Dark Cave mouth | Route31Antidote |
EVENT_ROUTE_31_ANTIDOTE |
POKE_BALL |
item ball at (21,13) | Route31PokeBall |
EVENT_ROUTE_31_POKE_BALL |
BITTER_BERRY |
tree at (16,7) | FRUITTREE_ROUTE_31 (data/items/fruit_trees.asm) |
daily |
Trainers
| const | class | id | party | script label | rematch/phone |
|---|---|---|---|---|---|
WADE1 |
BUG_CATCHER ($18) |
4 | BugCatcherGroup (4) "WADE": L2 CATERPIE, L2 CATERPIE, L3 WEEDLE, L2 CATERPIE |
TrainerBugCatcherWade1 |
yes, PHONE_BUG_CATCHER_WADE |
Reward 4 (base) * 2 (last mon level) * 4 = 32G, matching the walkthrough.
Wild encounters (def_grass_wildmons ROUTE_31, 10/10/10 percent, Gold arm)
- morn: 3 PIDGEY, 4 CATERPIE, 3 BELLSPROUT, 5 METAPOD, 5 CATERPIE, 5 METAPOD, 5 METAPOD
- day: 3 PIDGEY, 4 CATERPIE, 3 BELLSPROUT, 5 METAPOD, 5 CATERPIE, 6 METAPOD, 6 METAPOD
- nite: 4 SPINARAK, 4 RATTATA, 3 BELLSPROUT, 5 RATTATA, 5 HOOTHOOT, 5 HOOTHOOT, 5 HOOTHOOT
Water (def_water_wildmons ROUTE_31, 2 percent): 20 POLIWAG, 15 POLIWAG,
20 POLIWHIRL. Fishing group FISHGROUP_POND.
MAP_ROUTE_31_VIOLET_GATE
- Script:
maps/Route31VioletGate.asm; blocks sharedmaps/EastWestGate.blk(data/maps/blocks.asm:280) - Header:
map Route31VioletGate, TILESET_GATE, GATE, LANDMARK_ROUTE_31, MUSIC_ROUTE_30, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const ROUTE_31_VIOLET_GATE, 5, 4
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 0 | 4 | VIOLET_CITY |
8 |
| 2 | 0 | 5 | VIOLET_CITY |
9 |
| 3 | 9 | 4 | ROUTE_31 |
1 |
| 4 | 9 | 5 | ROUTE_31 |
2 |
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ROUTE31VIOLETGATE_OFFICER |
SPRITE_OFFICER |
5 | 2 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
Route31VioletGateOfficerScript |
-1 |
ROUTE31VIOLETGATE_COOLTRAINER_F |
SPRITE_COOLTRAINER_F |
1 | 2 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
Route31VioletGateCooltrainerFScript |
-1 |
Nothing blocks; both NPCs are jumptextfaceplayer.
Return-leg maps
Only the beats this section's text drives are transcribed. The first visit to all three belongs to the previous section.
MAP_NEW_BARK_TOWN
- Script:
maps/NewBarkTown.asm; blocksmaps/NewBarkTown.blk - Header:
map NewBarkTown, TILESET_JOHTO, TOWN, LANDMARK_NEW_BARK_TOWN, MUSIC_NEW_BARK_TOWN, FALSE, PALETTE_AUTO, FISHGROUP_OCEAN - Dimensions:
map_const NEW_BARK_TOWN, 10, 9; connections westRoute29(0), eastRoute27(0) - Callback
NewBarkTownFlypointCallback:setflag ENGINE_FLYPOINT_NEW_BARKandclearevent EVENT_FIRST_TIME_BANKING_WITH_MOM
Warps
| idx | x | y | destination map | dest warp |
|---|---|---|---|---|
| 1 | 6 | 3 | ELMS_LAB |
1 |
| 2 | 13 | 5 | PLAYERS_HOUSE_1F |
1 |
| 3 | 3 | 11 | PLAYERS_NEIGHBORS_HOUSE |
1 |
| 4 | 11 | 13 | ELMS_HOUSE |
1 |
Coord events
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_NEWBARKTOWN_TEACHER_STOPS_YOU (=0) |
1 | 8 | NewBarkTown_TeacherStopsYouScene1 |
teacher drags you back (follow + applymovement) |
SCENE_NEWBARKTOWN_TEACHER_STOPS_YOU |
1 | 9 | NewBarkTown_TeacherStopsYouScene2 |
same, other lane |
ElmDirectionsScript does setmapscene NEW_BARK_TOWN, SCENE_NEWBARKTOWN_NOOP, so
once a starter is in hand the west exit at x=1 is free. NEWBARKTOWN_RIVAL
(object at (3,2), flag EVENT_RIVAL_NEW_BARK_TOWN) is un-hidden by
MrPokemonsHouse_OakScript - he shoves the player away from the lab window.
MAP_ELMS_LAB
- Script:
maps/ElmsLab.asm; blocksmaps/ElmsLab.blk - Header:
map ElmsLab, TILESET_LAB, INDOOR, LANDMARK_NEW_BARK_TOWN, MUSIC_PROF_ELM, FALSE, PALETTE_DAY, FISHGROUP_SHORE - Dimensions:
map_const ELMS_LAB, 5, 6 - Scenes (ordinals):
SCENE_ELMSLAB_MEET_ELM0,SCENE_ELMSLAB_CANT_LEAVE1,SCENE_ELMSLAB_NOOP2,SCENE_ELMSLAB_MEET_OFFICER3,SCENE_ELMSLAB_UNUSED4,SCENE_ELMSLAB_AIDE_GIVES_POTION5,SCENE_ELMSLAB_AIDE_GIVES_POKE_BALLS6 (the last is a barescene_const- a scene id with no scene script, only coord events)
Warps: 1 (4,11), 2 (5,11) -> NEW_BARK_TOWN warp 1.
Coord events (the ones this section fires)
| scene | x | y | script label | effect |
|---|---|---|---|---|
SCENE_ELMSLAB_MEET_OFFICER |
4 | 5 | MeetCopScript |
walk-up then CopScript |
SCENE_ELMSLAB_MEET_OFFICER |
5 | 5 | MeetCopScript2 |
step LEFT first, then the same |
SCENE_ELMSLAB_AIDE_GIVES_POTION |
4 | 8 | AideScript_WalkPotion1 |
verbosegiveitem POTION |
SCENE_ELMSLAB_AIDE_GIVES_POTION |
5 | 8 | AideScript_WalkPotion2 |
same |
SCENE_ELMSLAB_AIDE_GIVES_POKE_BALLS |
4 | 8 | AideScript_WalkBalls1 |
giveitem POKE_BALL, 5 |
SCENE_ELMSLAB_AIDE_GIVES_POKE_BALLS |
5 | 8 | AideScript_WalkBalls2 |
same |
SCENE_ELMSLAB_CANT_LEAVE |
4/5 | 6 | LabTryToLeaveScript |
pushes the player back up (pre-starter) |
Object events (relevant rows)
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
ELMSLAB_ELM |
SPRITE_ELM |
5 | 2 | SPRITEMOVEDATA_STANDING_DOWN |
OBJECTTYPE_SCRIPT |
ProfElmScript |
-1 |
ELMSLAB_ELMS_AIDE |
SPRITE_SCIENTIST |
2 | 9 | SPRITEMOVEDATA_SPINRANDOM_SLOW |
OBJECTTYPE_SCRIPT |
ElmsAideScript |
EVENT_ELMS_AIDE_IN_LAB |
ELMSLAB_OFFICER |
SPRITE_OFFICER |
5 | 3 | SPRITEMOVEDATA_STANDING_UP |
OBJECTTYPE_SCRIPT |
CopScript (60:4366) |
EVENT_COP_IN_ELMS_LAB |
Scripts of interest
CopScript(60:4366):special NameRival(this is the "name your rival" prompt), thenapplymovement OfficerLeavesMovement,disappear ELMSLAB_OFFICER,setscene SCENE_ELMSLAB_NOOP.ElmAfterTheftScript(60:41f1), reached fromProfElmScriptwhenEVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMONis set:checkitem MYSTERY_EGG,takeitem MYSTERY_EGG,setevent EVENT_GAVE_MYSTERY_EGG_TO_ELM,setmapscene ROUTE_29, SCENE_ROUTE29_CATCH_TUTORIAL,clearevent EVENT_ROUTE_30_YOUNGSTER_JOEY,setevent EVENT_ROUTE_30_BATTLE,setscene SCENE_ELMSLAB_AIDE_GIVES_POKE_BALLS. This one script is what turns on the rest of the section.AideScript_GiveYouBalls(60:4317):giveitem POKE_BALL, 5,itemnotify,setscene SCENE_ELMSLAB_NOOP.
MAP_PLAYERS_HOUSE_1F
- Script:
maps/PlayersHouse1F.asm; blocksmaps/PlayersHouse1F.blk - Dimensions:
map_const PLAYERS_HOUSE_1F, 5, 4 - Warps: 1 (6,7), 2 (7,7) ->
NEW_BARK_TOWNwarp 2; 3 (9,0) ->PLAYERS_HOUSE_2F1
Object events
| const | sprite | x | y | movement | type | script label | event flag |
|---|---|---|---|---|---|---|---|
PLAYERSHOUSE1F_MOM1 |
SPRITE_MOM |
7 | 3 | SPRITEMOVEDATA_STANDING_LEFT |
OBJECTTYPE_SCRIPT |
MomScript (60:56cb) |
EVENT_PLAYERS_HOUSE_MOM_1 |
PLAYERSHOUSE1F_MOM2 |
SPRITE_MOM |
2 | 2 | SPRITEMOVEDATA_STANDING_UP (hours -1, MORN) |
OBJECTTYPE_SCRIPT |
MomScript |
EVENT_PLAYERS_HOUSE_MOM_2 |
PLAYERSHOUSE1F_MOM3 |
SPRITE_MOM |
7 | 3 | SPRITEMOVEDATA_STANDING_LEFT (hours -1, DAY) |
OBJECTTYPE_SCRIPT |
MomScript |
EVENT_PLAYERS_HOUSE_MOM_2 |
PLAYERSHOUSE1F_MOM4 |
SPRITE_MOM |
0 | 2 | SPRITEMOVEDATA_STANDING_UP (hours -1, NITE) |
OBJECTTYPE_SCRIPT |
MomScript |
EVENT_PLAYERS_HOUSE_MOM_2 |
Mom's position depends on the time of day - a bot must find her, not assume (7,3).
MomScript (60:56cb): with EVENT_GAVE_MYSTERY_EGG_TO_ELM set it runs
.GaveMysteryEgg -> setevent EVENT_FIRST_TIME_BANKING_WITH_MOM,
setevent EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST, special BankOfMom.
That is the walkthrough's "talk to your mom, who will save your money", and it is
also what silences the Route 31 SPECIALCALL_WORRIED callback.
3. Blockers and gates
| Gate | Enforced by (file:label) | Requirement | Unlock condition |
|---|---|---|---|
| Cannot leave New Bark Town westward before a starter | maps/NewBarkTown.asm:NewBarkTown_TeacherStopsYouScene1/2 at coord events (1,8)/(1,9), scene SCENE_NEWBARKTOWN_TEACHER_STOPS_YOU |
a starter | maps/ElmsLab.asm:ElmDirectionsScript -> setmapscene NEW_BARK_TOWN, SCENE_NEWBARKTOWN_NOOP |
| Cannot leave the lab before a starter | maps/ElmsLab.asm:LabTryToLeaveScript, coord events (4,6)/(5,6) under SCENE_ELMSLAB_CANT_LEAVE |
a starter | same ElmDirectionsScript, via setscene SCENE_ELMSLAB_AIDE_GIVES_POTION |
| Route 30 west fork blocked by "the two boys battling" | maps/Route30.asm object rows at (5,24), (5,25), (5,26), all flagged EVENT_ROUTE_30_BATTLE; objects are visible while the flag is clear (engine/overworld/map_objects_2.asm:CheckObjectFlag) |
deliver the MYSTERY EGG | maps/ElmsLab.asm:ElmAfterTheftScript -> setevent EVENT_ROUTE_30_BATTLE (hides them) and clearevent EVENT_ROUTE_30_YOUNGSTER_JOEY (spawns Joey the trainer) |
| Rival battle before leaving Cherrygrove east | maps/CherrygroveCity.asm coord events (33,6)/(33,7) under SCENE_CHERRYGROVECITY_MEET_RIVAL |
none - it is BATTLETYPE_CANLOSE, so a loss still advances |
armed by maps/MrPokemonsHouse.asm:MrPokemonsHouse_OakScript (setmapscene CHERRYGROVE_CITY, ...); cleared by the scene's own setscene SCENE_CHERRYGROVECITY_NOOP |
| Cop cutscene in Elm's Lab | maps/ElmsLab.asm coord events (4,5)/(5,5) under SCENE_ELMSLAB_MEET_OFFICER -> CopScript (special NameRival) |
walk to y=5 | setscene SCENE_ELMSLAB_NOOP at the end of CopScript |
| POKE BALLs not for sale | maps/CherrygroveMart.asm:CherrygroveMartClerkScript (checkevent EVENT_GAVE_MYSTERY_EGG_TO_ELM) -> MART_CHERRYGROVE vs MART_CHERRYGROVE_DEX in data/items/marts.asm |
deliver the egg | ElmAfterTheftScript |
| Catch tutorial cannot fire yet | maps/Route29.asm coord events (53,8)/(53,9) need scene SCENE_ROUTE29_CATCH_TUTORIAL |
deliver the egg | ElmAfterTheftScript -> setmapscene ROUTE_29, SCENE_ROUTE29_CATCH_TUTORIAL |
| Dark Cave is unusable (the walkthrough's "wait for Flash") | engine/events/overworld.asm:FlashFunction/.CheckUseFlash: ld de, ENGINE_ZEPHYRBADGE / farcall CheckBadge / jr c, .nozephyrbadge, then wTimeOfDayPalset == DARKNESS_PALSET |
ZEPHYRBADGE and HM05 Flash in the party | Violet Gym, next sections. The cave itself is enterable (Route31 warp 3 at (34,5)) - it is just black |
| Tuscany / PINK BOW not obtainable | maps/Route29.asm:Route29TuscanyCallback - checkflag ENGINE_ZEPHYRBADGE, else disappear; then VAR_WEEKDAY == TUESDAY |
ZEPHYRBADGE + Tuesday | later section |
| Mom's "worried" call | maps/Route31.asm:Route31CheckMomCallCallback - fires SPECIALCALL_WORRIED unless EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST |
not a blocker, but an unavoidable interruption | talk to Mom (MomScript) before entering Route 31 |
4. Bot checklist
Preconditions in brackets, postconditions after the arrow.
ELMS_LAB- walk to (4,8) or (5,8). [sceneSCENE_ELMSLAB_AIDE_GIVES_POTION] -> aide script runs, POTION in bag,setscene SCENE_ELMSLAB_NOOP.ELMS_LAB- warp out at (4,11)/(5,11) ->NEW_BARK_TOWNwarp 1 (6,3).NEW_BARK_TOWN- walk west past x=1. [SCENE_NEWBARKTOWN_NOOP] -> Route 29 (west connection).ROUTE_29- walk west along y=11..13. Optional: face (12,2) and press A -> BERRY (fruittree, daily); face/step on (48,2) and press A -> POTION, setsEVENT_ROUTE_29_POTION.ROUTE_29- grind wild encounters (10% step rate,def_grass_wildmons ROUTE_29) to the walkthrough's level 8.ROUTE_29->CHERRYGROVE_CITY(west connection). -> map callback setsENGINE_FLYPOINT_CHERRYGROVE.CHERRYGROVE_CITY- talk toCHERRYGROVECITY_GRAMPSat (32,6), answer YES. [EVENT_GUIDE_GENT_IN_HIS_HOUSEclear] -> follow tour, MAP CARD,setflag ENGINE_MAP_CARD, gramps disappears.CHERRYGROVE_CITY- warp 2 at (29,3) -> Pokecenter; talk to nurse at (3,1) from (3,2) -> party healed. Exit warps 1/2 at (3,7)/(4,7).CHERRYGROVE_CITY- walk north out of the map (north connection, offset 5) ->ROUTE_30, arriving at high y.ROUTE_30- warp 1 at (7,39) -> berry house; talk to the Pokefan at (2,3) -> BERRY,EVENT_GOT_BERRY_FROM_ROUTE_30_HOUSE. Exit warps 1/2 at (2,7)/(3,7).ROUTE_30- face (11,5) press A -> PSNCUREBERRY (daily). Face (14,9) press A -> hidden POTION,EVENT_ROUTE_30_HIDDEN_POTION.ROUTE_30- take the east fork north to warp 2 at (17,5) ->MR_POKEMONS_HOUSE.MR_POKEMONS_HOUSE- the scene fires on load (SCENE_MRPOKEMONSHOUSE_MEET_MR_POKEMON). Just advance text. ->MYSTERY_EGG,EVENT_GOT_MYSTERY_EGG_FROM_MR_POKEMON,blackoutmod CHERRYGROVE_CITY,ENGINE_POKEDEX, party healed,SPECIALCALL_ROBBEDqueued,EVENT_COP_IN_ELMS_LABcleared,SCENE_CHERRYGROVECITY_MEET_RIVALandSCENE_ELMSLAB_MEET_OFFICERarmed.- Walk out (warps 1/2 at (2,7)/(3,7)) and take a few overworld steps ->
Elm's phone call (
engine/phone/scripts/elm.asm.disaster) ->EVENT_ELM_CALLED_ABOUT_STOLEN_POKEMON. ROUTE_30south ->CHERRYGROVE_CITY. Heal at the Pokecenter.CHERRYGROVE_CITY- walk east through x=33 on row 6 or 7. -> rival scene, battleRIVAL1id 1/2/3 by starter (level 5,BATTLETYPE_CANLOSE), thenspecial HealParty,SCENE_CHERRYGROVECITY_NOOP.CHERRYGROVE_CITYeast ->ROUTE_29east ->NEW_BARK_TOWN.NEW_BARK_TOWN- warp 1 at (6,3) ->ELMS_LAB. Step onto (4,5) or (5,5) [SCENE_ELMSLAB_MEET_OFFICER] ->CopScript,special NameRivalprompt, officer leaves,SCENE_ELMSLAB_NOOP.ELMS_LAB- talk toELMSLAB_ELMat (5,2). [MYSTERY_EGGin bag] ->ElmAfterTheftScript: egg taken,EVENT_GAVE_MYSTERY_EGG_TO_ELM, Route 29 tutorial armed, Route 30 blockers removed, Joey spawned,SCENE_ELMSLAB_AIDE_GIVES_POKE_BALLS.ELMS_LAB- walk to (4,8) or (5,8) -> aide gives 5 POKE BALLs.NEW_BARK_TOWN- warp 2 at (13,5) ->PLAYERS_HOUSE_1F; talk to Mom (position depends on time of day: (7,3) by day, (2,2) morn, (0,2) nite) ->EVENT_TALKED_TO_MOM_AFTER_MYSTERY_EGG_QUEST,EVENT_FIRST_TIME_BANKING_WITH_MOM, Bank of Mom menu.ROUTE_29- step on (53,8) or (53,9) -> catch tutorial. YES runs the demo (loadwildmon RATTATA, 5+catchtutorial); NO also clears the scene.- Optional
ROUTE_46:ROUTE_29warp 1 at (27,1) -> gate warp 3, gate warps 1/2 at (4,0)/(5,0) -> Route 46 (7,33)/(8,33). Hunt RATTATA (night has two RATTATA slots). Grab DIRE_HIT at (0,12). Avoid the three trainers - they are L13-L17 and far above the party. CHERRYGROVE_CITY- heal; optionally buy POKE BALLs (MART_CHERRYGROVE_DEXis live now) via warp 1 at (23,3).ROUTE_30- take the west fork north. Trainers in walk order:TrainerYoungsterJoeyat (6,29) sight 4,TrainerYoungsterMikeyat (5,23) sight 1,TrainerBugCatcherDonat (4,7) sight 3. ->EVENT_BEAT_YOUNGSTER_JOEY,EVENT_BEAT_YOUNGSTER_MIKEY,EVENT_BEAT_BUG_CATCHER_DON. Joey will ask for a phone number.ROUTE_30north (y -> 0) ->ROUTE_31. -> map callback: if Mom was not talked to,SPECIALCALL_WORRIEDis queued.ROUTE_31- item ball at (29,5) -> ANTIDOTE. Sign at (31,5) is the Dark Cave sign; the cave warp is at (34,5) - skip it, no Flash.ROUTE_31-TrainerBugCatcherWade1at (18,15), sight 3 (approach from below). ->EVENT_BEAT_BUG_CATCHER_WADE, phone number offer.ROUTE_31- item ball at (21,13) -> POKE BALL. Tree at (16,7) -> BITTER BERRY.ROUTE_31- warps 1/2 at (4,6)/(4,7) ->ROUTE_31_VIOLET_GATEwarps 3/4; cross to gate warps 1/2 at (0,4)/(0,5) ->VIOLET_CITYwarps 8/9. End of section.
5. Port coverage
The Gen 2 port is data-driven: src/import/RomExtractorGen2.lua reads map headers,
warps, coord events, bg events, object events, trainer structs and encounter tables
out of the ROM, and src/world/gen2/World.lua + src/script/gen2/Vm.lua replay
them. So coverage below is per-mechanic, not per-map.
| Beat | Port file | Status |
|---|---|---|
| Map headers / warps / connections / coord events / bg events / objects | src/import/RomExtractorGen2.lua, src/world/gen2/Map.lua, src/world/gen2/World.lua (self.map.def.coordEvents at World.lua:5013) |
implemented |
Scene scripts + setscene / setmapscene |
src/script/gen2/Vm.lua (setmapscene at Vm.lua:279), src/world/gen2/World.lua (s.sceneId match at World.lua:5033) |
implemented |
Object visibility from EVENT_* (appear / disappear, the Route 30 blockers, the rival, the cop) |
src/world/gen2/Events.lua, src/world/gen2/World.lua |
implemented |
follow / stopfollow (Guide Gent tour, catch-tutorial DUDE, New Bark teacher) |
src/script/gen2/Vm.lua:982 |
implemented; driver tests/drivers/gold_teacher_scene.lua asserts the follow leg |
| Overworld trainer sight + battle + beat flag | src/world/gen2/Trainers.lua, src/world/gen2/World.lua |
implemented; driver tests/drivers/gold_trainer_smoke.lua runs the Route 30 bug catcher end to end |
| Trainer phone numbers / rematch chain (Joey, Wade) | src/core/gen2/Phone.lua, src/script/gen2/Vm.lua (askforphonenumber, checkcellnum) |
implemented (not audited against this section's specific rematch gates) |
specialphonecall queue + Elm's SPECIALCALL_ROBBED / Mom's SPECIALCALL_WORRIED |
src/script/gen2/Vm.lua:1364, src/core/gen2/Phone.lua |
implemented |
Catch tutorial (catchtutorial BATTLETYPE_TUTORIAL) |
src/core/gen2/CatchTutorial.lua, src/core/gen2/AutoInput.lua, src/script/gen2/Vm.lua |
implemented |
| Fruit trees (Route 29/30/31/46 berries) | src/script/gen2/Vm.lua:1191 (inlines FruitTreeScript because the extractor cannot reach it), src/core/gen2/Apricorns.lua |
implemented |
Hidden items (BGEVENT_ITEM, Route 30's POTION) |
src/world/gen2/HiddenItems.lua, dispatch at src/world/gen2/World.lua:5291-5296 |
implemented |
Item balls (OBJECTTYPE_ITEMBALL: Route 29 POTION, Route 31 ANTIDOTE + POKE BALL, Route 46 DIRE HIT) |
extracted into obj.itemball at src/import/RomExtractorGen2.lua:2968; nothing consumes it - the A-press dispatch at src/world/gen2/World.lua:5265-5296 only handles trainer, strength boulder, scriptKey, then hidden items, and itemball appears nowhere else in src/ |
missing - every ground item ball in this section is un-takeable |
verbosegiveitem / giveitem / itemnotify (egg, Poke Balls, berries, MYSTIC WATER) |
src/script/gen2/Vm.lua |
implemented |
pokemart + the MART_CHERRYGROVE / MART_CHERRYGROVE_DEX switch |
src/ui/gen2/MartMenu.lua, src/script/gen2/Vm.lua |
implemented (the switch itself is just a checkevent, so it follows for free) |
special BankOfMom (Mom saving money) |
src/ui/gen2/BankOfMom.lua, src/script/gen2/Specials.lua |
implemented; driver tests/drivers/gold_mom_scene.lua covers the MeetMomScript cutscene, not the banking talk |
special NameRival (cop scene) |
src/script/gen2/Specials.lua, src/ui/gen2/NamingScreen.lua |
implemented |
setflag ENGINE_POKEDEX / ENGINE_FLYPOINT_* / ENGINE_ZEPHYRBADGE |
src/script/gen2/Vm.lua:208, src/world/gen2/World.lua:1304-1339 (save.engineFlags) |
implemented |
setflag ENGINE_MAP_CARD reaching the Pokegear |
written to save.engineFlags (World.lua:1325); src/ui/gen2/Pokegear.lua:935 reads save.pokegearFlags with keys map / radio / phone, and no code in the repo writes pokegearFlags outside tests and tests/drivers/gold_menu_shots.lua |
partial - the Guide Gent's reward is recorded but the MAP card will not appear on the Pokegear |
| Time-of-day wild tables (morn/day/nite split, per-time rate) | src/battle/gen2/Encounter.lua |
implemented |
Fishing groups (FISHGROUP_SHORE / FISHGROUP_POND) |
src/battle/gen2/Encounter.lua:81-99 |
implemented |
| Water encounters (Route 30/31 Poliwag) | src/battle/gen2/Encounter.lua |
implemented but unreachable in this section (needs Surf) |
Flash / ENGINE_ZEPHYRBADGE gate on Dark Cave |
src/world/gen2/FieldMoves.lua |
implemented |
blackoutmod CHERRYGROVE_CITY |
src/script/gen2/Vm.lua, src/world/gen2/World.lua |
implemented |
| Route 29 Tuscany weekday/badge callback | src/world/gen2/World.lua map callbacks; asserted by tests/drivers/gold_map_callbacks.lua:118-158 |
implemented |
| New Bark -> Route 29 edge crossing | tests/drivers/gold_walk_smoke.lua |
implemented (driver walks bedroom -> Route 29) |
| Cherrygrove City itself (guide tour, rival scene, Pokecenter) | no dedicated driver found under tests/drivers/gold_*.lua |
untested |
6. Unresolved / verify by hand
- Route 30 "Antidote" does not exist. The walkthrough says "Just above the
house is an Antidote".
maps/Route30.asmhas noOBJECTTYPE_ITEMBALLobject at all; the only ground item is the hiddenPOTIONat bg event (14,9) (Route30HiddenPotion). The ANTIDOTE is on Route 31, item ball at (29,5). - Route 31 "Potion" is an Antidote. The walkthrough says "grab that Potion to
the left of [Dark Cave]". The ball west of the Dark Cave mouth (34,5) is at
(29,5) and is
itemball ANTIDOTE. There is no POTION object on Route 31. - Youngster Mikey's party. The walkthrough says "Level 2 Rattata / Level 4
Rattata".
data/trainers/parties.asmYoungsterGroup(2) "MIKEY" isdb 2, PIDGEY/db 4, RATTATA. - Hoppip on Route 29. Listed by the walkthrough (#187), absent from
def_grass_wildmons ROUTE_29. Hoppip's first Johto grass appearance is Route 32. - Zubat and Poliwag on Routes 30/31. Listed by the walkthrough. Poliwag is
in
data/wild/johto_water.asm(surf, 2% rate) and in.Pond_*fishing, not in grass. Zubat is not in either route's grass table at any time of day - it is a Dark Cave mon. - Weedle / Kakuna on Routes 30-31 in a Gold run. The walkthrough lists them
for both routes; in
data/wild/johto_grass.asmthose slots are inside theELIF DEF(_SILVER)arm. A Gold cart gets CATERPIE / METAPOD instead. The walkthrough's own "(Silver only)" / "(Gold only)" notes are right for Ledyba and Spinarak but not applied to Weedle/Kakuna. - "Pink Bow" listed as a Route 29 item. Reachable only with
ENGINE_ZEPHYRBADGEandVAR_WEEKDAY == TUESDAY(Route29TuscanyCallback), so it cannot be collected during this section. - Onix in Violet City / TM31 / PRZCure Berry. Listed in the walkthrough's
Violet City preamble;
maps/VioletCity.asmwas not opened (next section owns it) so none of it is verified here. - "You get: 300G / 64G / 48G / 32G". Verified indirectly: reward =
base_reward * last mon level(engine/battle/read_trainer_party.asm:300ComputeTrainerReward) paid four times by theld c, 4loop inengine/battle/core.asm:2340-2361. All four figures match. Worth a hand-check in an emulator if a bot budgets money precisely, because the split betweenwMomsMoneyandwMoneydepends onwMomSavingMoney, i.e. on whether the player has done step 21. EVENT_ROUTE_30_BATTLEas a physical block. The three objects at (5,24)/(5,25)/(5,26) are what the walkthrough calls "You can't pass that area just yet". Confirmed that they exist and vanish onElmAfterTheftScript, but whether that column of three fully seals the west lane depends onmaps/Route30.blkcollision, which was not decoded. Verify in game if a bot pathfinder wants to rely on it.- MAP CARD on the Pokegear in this port. See section 5 - the flag is stored
under
save.engineFlagswhile the Pokegear readssave.pokegearFlags. No bridge was found by grep; if one exists it is somewhere the stringpokegearFlagsdoes not appear.