TODO: - TID manip video w/inputs (and more info on adjacent TIDs) - GBP/GSR offsets in addition to the GBI ones More detailed guide (most things still apply, except for things I explicitly mention here): - https://pokemon-speedrunning.github.io/speedrun-routes/#/gen-2/gold-silver/main-any/gold-silver-backup-collision-route/ My PB video for reference: https://www.youtube.com/watch?v=oaLXa2GWNZo --- GENERAL NOTES --- FlowTimer offsets (GBI): - TID: 20263 - Collision: 2506 - Corruption: 2712 TID Manip for 09705 (0x25e9): > gold_reset1_gfskip_backout2_wait114(setopt)_backout5_newgame, Offset (wait): 20.824, Offset (NG): 28.98 - 1 framerule early: 40977 - 1 framerule late: 12052 Box Names (name them in reverse order to minimize lag): > BOX1-BOX3 E é [ 'd é H 'd ; note: you can't add a final 'd at the end here like you can w/other box names F é 'v 2 H é ] 'd a é d 2 é é 4 'd ; note: 6th character can be anything (it's a placeholder overwritten during ACE) > BOX12 Q D é g 'd 'm v 2 Turnframes saved: - Save facing up before Potion pickup (buffer down while game is saving to turn towards Potion, timing is easy) > incurs 2 total turnframes instead of 3 - Do final menu immediately after second Mr. Pokémon cutscene > opening menu mid-movement is unnecessary and incurs a turnframe Final menu (balls pocket): - Yoloscroll this; it's faster and there's a big enough window (8? frames) to hit it by visual cue and feel - I found it easiest to swap slot 2 with the item you'll register > count cursor blinks once you see question marks, you should get it very consistently w/enough practice - If you registered the correct slot, CANCEL will be 2 down when you start the long scroll to the bottom > if you notice it's not, you can scroll back up to 2 above CANCEL and register to fix it - Emergency backup (for if you royally screw up like I somehow did and bottom quantity isn't 75 when you get there) > count 9 down from where the ? x75 should be, and register that item as a backup to fix it Other notes: - You can determine if collision succeeded or failed without needing to open the Start menu to check > If Pokédex appears on the file info screen (between Badges/Time) and your save loads on r30, it succeeded > Otherwise, it's your old uncorrupted save - Alternative TID Manip (slightly "faster", but 2 soft resets isn't as dead simple to time as just 1 is) > gold_reset2_gfskip_backout2_wait156(setopt)_backout2_newgame, Offset (wait): 24.393, Offset (NG): 28.40 - Don't know if this is worth it, but to possibly avoid things outspeeding you (to the extent possible) > 9:00am clockset for morning: 5 extra frames = only 10% for L4 Pidgey on r30 (instead of 20% for day) - If you are a gaming god who can consistently scroll to slot $6c, you can register that slot and save a swap > Swap ? x0 with ? x[]8 (using the slots you normally do the final swap with) --- RESOURCES AND SUGGESTIONS --- Practice ROMs (especially useful for console runners with flashcarts): - Use RomPatcher.js site to apply one of the patches below to your Gold ROM > https://www.marcrobledo.com/RomPatcher.js/ - Normal Gold practice ROM w/embedded save files for Any% practice > https://cdn.discordapp.com/attachments/878020788303851560/894297030074183690/goldany-practice.bps - Altered practice ROM with extremely condensed New Game and Mr. Pokémon cutscenes > https://cdn.discordapp.com/attachments/878020788303851560/894296996293259337/goldany-practice-efficient.bps > Makes it much more efficient to tune FlowTimer offsets for TID manip and/or collision - Press Down+Select+B on title screen to load the save selection menu, then press A to load a given save - Note: I included saves that were useful for my practice purposes; some may or may not be useful to other runners How to name boxes quickly: - (Optional, but highly recommended) Don't use GBA SP (Start and Select buttons will greatly limit you imo) - Memorize names, not inputs > find fastest input sequences obv, but going by feel removes hesitation and you can quickly notice/correct mistakes - To start, practice each box name individually and gradually improve speed, then move to naming all boxes in sequence - After learning, use LiveSplit and do dedicated practice; easier to take it seriously and progressively push your limits - Takes a daily practice session or two over a few days to build muscle memory to do them with speed and consistency --- CHECKSUM COLLISION AND SAVE CORRUPTION INFO --- NOTE: I use technical terms in this section, but they aren't terribly important to understand; the outcomes and percentages are the more important things to note. There's a technical explainer at the end of this section. Runners don't need to understand the mechanics, but they may help make sense of things for anyone who's curious. If necessary, this is a simple method for tuning your collision offset: - Follow the collision steps from the main guide, but Continue into the overworld instead of selecting New Game - After pressing Continue, there are a couple possible results: (1) If primary checksum didn't get saved, the backup save on r30 will be loaded (2) Otherwise, the save in Mr. Pokémon's house gets loaded - With a good offset, the r30 save should load ~40% of the time, and the Mr. Pokémon save should load ~60% of the time > Around 1/4 of a frame between saving the primary checksum and middle of the collision window, so not quite 50/50 Troubleshooting collision attempts: - Follow the collision & corruption steps from the main github guide - After pressing Continue, the game will attempt to load your backup save and there are a few possible results: 1: "The save file is corrupted!" > You reset during the backup save but missed the window (no easy way to tell if reset was early or late) 2: The game loads your backup save on r30; then you can tell based on whether or not you have a Pokédex (a) No Pokédex means you reset before the backup save started to be written, i.e. your reset was early (b) If you have a Pokédex, you successfully hit the collision window! 3: The game loads a backup save inside Mr. Pokémon's house > This means the backup checksum was saved, i.e. your reset was very, very late (7+ frames) - With a good offset, results should be something like the following (depends on how precise you are): 1: ~47% of the time 2a: ~40% of the time 2b: ~13% of the time (!) 3: Never Other general notes: - Must follow steps exactly (especially ones involving items) for the above troubleshooting advice to fully apply > If you did anything important wrong, you'll see "The save file is corrupted!" even if you hit the window - The window for hitting primary save corruption is large (9+ frames) and you should never miss with a good offset Technical explainer: - Gen 2 games use a "checksum" of game data to determine if a save is valid or corrupt; they also store "backup saves" - When pressing Continue on the main menu: > If the primary save is valid, it is written to the backup save prior to loading the file info screen > If the primary save is corrupt, the backup save is then checked : if the backup save is valid, it overwrites the primary save prior to loading the file info screen : if the backup save is also corrupt, you'll get a message that says "The save file is corrupted!" - Rough order of operations in Gold/Silver when performing a normal save: (1) Save primary game data in normal order (2) Calculate and store primary save checksum (3) Save 3rd part of backup player data (some relevant stuff: pokédex flag, items, which "script" to run on each map) (4) Save remainder of backup save in the otherwise normal order (5) Calculate and store backup save checksum - This particular route works by abusing the above mechanics: > First, the backup save is corrupted such that only a small chunk of static game data is relevant between 2 saves > After the backup save is corrupted, New Game is selected (pressing Continue would overwrite the backup save) > Once in the overworld, the primary save is then corrupted without touching the backup save > If all is done successfully, pressing Continue will load a corrupt backup save (since it has the correct checksum) : The player will have a Pokédex and a Mystery Egg, but the normal Mr. Pokémon cutscene will still play : After getting a second Mystery Egg, key item underflow can be performed, which unlocks other useful glitches --- MISCELLANEOUS STUFF DEFINITELY NOT WORTH READING UNLESS UR A BIG DUMB NERD --- Routine for saving game data in Gold/Silver: - https://github.com/pret/pokegold/blob/e315a38db4c9a13f70d662fc40bb2a948415e47e/engine/menus/save.asm#L273-L292 Gold/Silver SRAM addresses (in order they are saved): options: [1:a000-a007] playerdata1: [1:a009-a226] playerdata2: [1:a227-a3d8] playerdata3: [1:a3d9-a855] curmapdata: [1:a856-a889] pokemondata: [1:a88a-ad68] box: [1:ad6c-b1b9] checksum: [1:ad69-ad6a] b.options: [3:be30-be37] b.playerdata3: [0:ac6b-b0e7]* b.playerdata1: [0:b5c7-b7ec] b.playerdata2: [1:bd96-bf3f] b.curmapdata: [3:be39-be6c] b.pokemondata: [0:b0e8-b5c6] b.checksum: [3:be6d-be6e] * collision window = [0:acde-adc9] > After the key items terminator byte is saved, but before the Mr. Pokémon House "scene ID" is saved Box source code & notes ; BOX 1-3 ; E é [ 'd é H 'd ; F é 'v 2 H é ] 'd ; a é d 2 é é 4 'd ; BOX 12 ; Q D é g 'd 'm v 2 ; Registers ; af = 0040 ; (c=0) ; bc = ff9e ; (0000 after jump in box 12) ; de = 0009 ; hl = f91f ; [hl] = 00 ; sp = dfcb ; pc = f922 ; BOX 12 (d922-d92a) :: Q D é g 'd 'm v 2 sub b ; a=$01, c=1 add e ; a=$0a, c=0 ld [$d0a6], a ; y displacement jp nc, $f8b5 ; jumps into safe code just before box 1 name ; ld bc, $0000 (at f8b8) ; BOX 1 (d8bf-d8c7) :: E é [ 'd é H 'd add h ; a=$03, c=1 ld [$d09e], a ; map group ld [$d087], a ; map height for connection warp ; ld d, b ; BOX 2 (d8c8-d8d0) :: F é 'v 2 H é ] 'd add l ; a=$22, c=0 ld [$f8d6], a ; self-modify for party count (6th char of box 3) add a ; a=$44 ld [$d09f], a ; map number ; ld d, b ; BOX 3 (d8d1-d8d9) :: a é d 2 é é 4 'd and b ; $a=00 ld [$f8a3], a ; make red appear ld [$fa22], a ; party count ($faea is modified to $fa22 above) ret nc For posterity, 09719 (0x25f7) as a TID is an alternative > Only have to scroll to BOX9 instead of BOX12, but the box names are more inputs, so it's slower overall > TID Manip: gold_reset2_gfskip_backout1_wait102(setopt)_backout4_newgame, Offset (wait): 19.400, Offset (NG): 26.16 ; BOX 1-3 ; E é [ 'd é H 'd [ ; d é 'v 2 H é ] 'd ; a é d 2 é é 4 'd ; BOX 9 ; ( H é g 'd 'm v 2