Skip to content

Run the Safari game from its gate's fee to the PA that ends it - #598

Merged
Decryptu merged 1 commit into
mainfrom
gen1-safari-zone
Sep 8, 2026
Merged

Run the Safari game from its gate's fee to the PA that ends it#598
Decryptu merged 1 commit into
mainfrom
gen1-safari-zone

Conversation

@Decryptu

@Decryptu Decryptu commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Added

The Safari Zone. SafariZoneGate_Script's seven states decode, and what the purchase wanted was the two stores behind SafariZoneEntranceAutoWalk, which are Gen2WorldState's own safari_balls and safari_steps.

SafariZoneCheckSteps runs where _complete_player_step stands in front of CheckWarpsNoCollision, SafariZoneCheck reads the same ball count, and SafariZoneGameOver is a step list of its own: TimesUpText only while balls are left, GameOverText, EVENT_SAFARI_GAME_OVER, the gate left on its leaving state and the warp to its third warp. PrintSafariZoneSteps draws beside the START menu list on the nine maps between SAFARI_ZONE_EAST and CERULEAN_CAVE_2F, and ItemUseEscapeRope ends the game where it stands.

InitBattleVariables reads wCurMap alone, so every wild fight on the four zones is BATTLETYPE_SAFARI: TryRunningFromBattle takes .canEscape on it, SAFARI_BATTLE_MENU_TEMPLATE is the box SafariZoneBattleMenuText's four rows and .safariLeftColumn's count sit in, and a throw spends wNumSafariBalls rather than a bag row. ItemUseBait halves wEnemyMonActualCatchRate where ItemUseRock doubles it, each zeroing the other's factor and growing its own by .randomLoop's 1 to 5; PrintSafariZoneBattleText counts one down a turn and puts the species' own rate back when the escape counter runs out; and .notOutOfSafariBalls rolls against twice the low byte of the enemy's Speed, quartered while it is eating and doubled while it is angry.

Yellow's gate is its own routine. ld a, [hli] / or [hl] / inc hl / or [hl] over wPlayerMoney is a has_money of one, and its two admission routines are one node each: SafariZoneEntranceCalculateLowCostAdmission divides the balance by the seventeen ld a, 23 writes in packed decimal and stops at 29 balls, and SafariZoneEntranceGetLowCostAdmissionText counts an empty purse's visits in wSafariSteps' own high byte and pays one ball on the fourth.

Fixed

_extend_texts ran once, so a text row the grown table reached could not grow it again and the Safari Zone gate read four of its six rows. It is a loop now: Red and Blue go from 316 text_asm rows to 317 and Yellow from 369 to 370, and their unknown arms from 3 and 17 to 2 and 16.

wDestinationWarpID was read one-based where LoadDestinationWarpPosition's add a / add a counts from zero, so every scripted warp landed on the row in front of its own.

A map's entry script was spent at EnterMap and then resolved a second time to show its boxes, which a body consuming what it read answers differently: CheckAndResetEvent in the gate's leaving state lost its own event that way. The one run is kept instead.

wNextSafariZoneGateScript is a union over wSavedCoordIndex, and a store of it into a map script byte is read now.

Checks

tools/checks/gen1_maps.gd pins the gate's states, its texts and both map runs; gen1_walk.gd pays the fee, walks all 502 steps out and is answered by the PA and the warp, and takes Yellow's discount and its four empty-handed visits; gen1_battle.gd runs the bait, the rock, the two counters and 4,000 run rolls. All three cartridges. tools/preview_world.gd -- red 0 220 <out.png> live safari 300 0 photographs the battle menu and 0 1 the step window.

validate.gd -- all passes, the unit tier is 3916 green, the analyser reports 0 warnings in 637 scripts, replay_world.gd is 33 routes and 0 failures, and the three-profile story walk runs to Silver Cave.

`SafariZoneGate_Script`'s seven states decode: the purchase wanted the two
stores behind `SafariZoneEntranceAutoWalk`, which are `Gen2WorldState`'s own
`safari_balls` and `safari_steps`. `SafariZoneCheckSteps` runs where
`_complete_player_step` stands in front of `CheckWarpsNoCollision`,
`SafariZoneCheck` reads the same ball count, and `SafariZoneGameOver` is a step
list: `TimesUpText` only while balls are left, `GameOverText`,
EVENT_SAFARI_GAME_OVER, the gate on its leaving state and the warp to its third
warp. `PrintSafariZoneSteps` draws beside the START menu list on the nine maps
between SAFARI_ZONE_EAST and CERULEAN_CAVE_2F, and `ItemUseEscapeRope` ends the
game where it stands.

`InitBattleVariables` reads `wCurMap` alone, so every wild fight on the four
zones is BATTLETYPE_SAFARI: `TryRunningFromBattle` takes `.canEscape` on it,
`SAFARI_BATTLE_MENU_TEMPLATE` is the box `SafariZoneBattleMenuText`'s four rows
and `.safariLeftColumn`'s count sit in, and a throw spends `wNumSafariBalls`.
`ItemUseBait` halves `wEnemyMonActualCatchRate` where `ItemUseRock` doubles it,
each zeroing the other's factor and growing its own by `.randomLoop`'s 1 to 5;
`PrintSafariZoneBattleText` counts one down a turn and puts the species' rate
back when the escape counter runs out; `.notOutOfSafariBalls` rolls against
twice the low byte of the enemy's Speed, quartered eating and doubled angry.

Yellow's gate is its own routine. `ld a, [hli] / or [hl] / inc hl / or [hl]`
over `wPlayerMoney` is a `has_money` of one, and its two admission routines are
one node each: the first divides the balance by the seventeen `ld a, 23` writes
in packed decimal and stops at 29 balls, the second counts an empty purse's
visits in `wSafariSteps`' high byte and pays one ball on the fourth.

Four things fixed beside them. `_extend_texts` ran once, so a row the grown
table reached could not grow it again and the gate read four of its six rows; it
is a loop now, taking Red and Blue from 316 `text_asm` rows to 317 and Yellow
from 369 to 370, and their unknown arms from 3 and 17 to 2 and 16.
`wDestinationWarpID` was read one-based where `LoadDestinationWarpPosition`'s
`add a / add a` counts from zero, so every scripted warp landed on the row in
front of its own. `wNextSafariZoneGateScript` is a union over `wSavedCoordIndex`
and a store of it into a map script byte is read now. And a map's entry script
was spent at `EnterMap` and resolved a second time to show its boxes, which a
body consuming what it read answers differently: `CheckAndResetEvent` in the
gate's leaving state lost its own event that way, so the one run is kept.
@Decryptu
Decryptu merged commit 56e9a22 into main Sep 8, 2026
1 check passed
@Decryptu
Decryptu deleted the gen1-safari-zone branch September 8, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant