Submission #9293: CasualPokePlayer's GBC Pokémon: Crystal Version "save glitch" in 02:18.90

Game Boy Color
Pokémon: Crystal Version
save glitch
BizHawk 2.9.1
8297 (cycle count 291304258)
59.731602495147875
9423
PowerOn
Pokemon - Crystal Version (USA, Europe).gbc
USA/Europe
Submitted by CasualPokePlayer on 9/15/2024 10:51 PM
Submission Comments
Another improvement to Gen 2 save glitch.
The strategy for this run is to get out of bounds to map 0xFF00, similar to my previous Crystal save glitch TAS. This is done by resetting right after the player's coordinates are written but before the visible map cache is saved, resulting in a desynchronized map state, allowing for the map to be exited in unintentional ways. Map 0xFF00's corruption gives us access to a highly corrupted inventory and thus a seemingly easy vector for ACE.
However, this run opts to do this very early, before even talking to Mom. This poses a grave problem: you can't use wrong pocket TMs/HMs without a Pokemon in the party (as the game prevents item effects for items needing a Pokemon. Granted this is strange for wrong pocket TMs/HMs since separate code handles the correct TMs/HMs pocket). There is also the minor problem of not being able to actually use Mail to setup an ACE payload.
So without a Pokemon, it seems like this route is impossible. However, I discovered a saving grace: registered items. Registered items are not subject to the Pokemon in a party limitation (as Game Freak didn't add such code to registered item handling). So we can freely use a wrong pocket TM/HM by "registering" a wrong pocket TM/HM. An extra saving grace is HM03, which runs the daycare withdraw code, thus allowing us to get a Pokemon!
Using HM03 does have a minor downside, it results in wPokemonWithdrawDepositParameter being set to 1. This is right before wItemQuantityChange, where we normally insert a jp hl by pretending to toss 233. 1 corresponds to ld bc,$xxyy, so this would make the next byte be treated as an operand rather than opcode. This can be worked around by simply using Mail on the second Pokemon in the party, which sets wCurPartyMon to 1. This is two bytes before wPokemonWithdrawDepositParameter, so the problematic 1 gets treated as an operand, thus allowing the old dec h / jp hl bootstrap to work fine.
So with these in place, the plan is follows:
  1. Perform save corruption to misalign the visible map cache and the player's Y coord.
  2. Step down to get OOB.
  3. Fake "register" HM03.
  4. Use Select in the overworld to use "HM03" and thus get a Pokemon.
  5. Use HM03 again.
  6. Create Mail
  7. Put Mail on the second Pokemon
  8. Write ACE payload
  9. Fake toss 233 items
  10. Use TM22 at the 37th item slot.
  11. Use ACE to make the south map connection go to Mt Silver, nuke party count, clear Red flag, set autoinput to go south and spam A.
  12. Win!
Last Edited by CasualPokePlayer 4 days ago
Page History Latest diff List referrers