Submission #6796: CasualPokePlayer's GBC Pokémon: Gold Version "game end glitch" in 30:01.80

Game Boy Color
(Submitted: Pokémon: Gold Version)
game end glitch
(Submitted: Coin Case glitch)
(Submitted: pokegold.gbc USA/Europe)
Bizhawk 2.4.2
107717
59.782895244374664
19556
Unknown
Submitted by CasualPokePlayer on 6/30/2020 7:44 AM
Submission Comments

Introduction

Another pokesub from me, this time on the Coin Case TAS. This run is ~40 seconds faster than the previous TAS (accounting for the lack of a BIOS on the previous TAS).

Emulator used: Bizhawk 2.4.2

  • CGB in GBA is enabled for console verification.

Categories

  • Forgoes save data corruption
  • Executes arbitrary code
  • Heavy luck manipulation

About the run

Version Choice

Gold and Silver are mostly the same, the only relevant difference being that Silver’s title screen loads 2 frames slower. Silver was used in the previous TAS since the TID used was faster to manip on that version, however, this run manips a different TID, and Gold happens to be able to manipulate it faster.

Route

Most of the route pre-Coin Case is identical to my glitchless submission, with some differences:
  • TID is manipulated to be F8F7; D8F7 also works, but F8F7 was much faster to manipulate.
  • Time is set to the default time, we don’t have to catch a Wooper here, so no need to set it to morning.
  • The player is named “J”. Purely an artistic choice, there is no extra cost to naming the character J.
  • Cyndaquil’s DVs are manipulated to be F8AF, nothing too different really, still does the job.
  • Cyndaquil is named “B”. Again, another artistic choice, with no extra cost.
  • Bellsprout is caught on Route 31. We need a filler Pokemon for the Coin Case and Bellsprout is the best since we have to encounter it anyways. It is not nicknamed, as its name will only appear 2 times in the run.
  • The Egg’s DVs are manipulated to be 3887. This is important later on for the ACE bootstrap.
  • Burn strats are completely avoided. Turns out it was actually a bit slower to use burns to save turns (loses ~3 seconds overall).
    • Russel’s level 6 Geodude is now taken out with two 1/39 non-crit Embers.
    • The Koffing from the last Rocket grunt is now taken out with a 1/39 non-crit and a high roll non-crit Ember.
    • Rival 2’s Croconaw is now taken out by three 1/39 Tackle crits and one 1/39 Tackle non-crit.
  • Apparently, Amy & May's Ledyba can be KO'd by a Tackle crit, which saves a bit of time over Ember.
  • Tackle is swapped to the third slot on Rival 2. Tackle needs to be in the third slot for the ACE bootstrap to work, and switching moves in battle is a lot faster than out of battle.
  • Cut is taught to Bellsprout. Bellsprout has empty move slots, so it is fastest if we teach Cut to it.
  • Of course, since we’re just going to be glitching with the Coin Case, no need to catch Abra or get the bike, just go underground, defeat the 1 trainer in the way, then Coin Case away.

Coin Case Glitch Improvements

The Coin Case glitch setup is pretty much the same until we reach party data. The previous TAS used a ld hl,D900 and jp hl to jump to box names. This TAS instead uses a ld hl,F86C and rst 30 to jump to box names. rst 30 is really just a 1 byte call to 0030, which corresponds to:
ld l,a
pop de
jp hl
The egg’s DVs are manipulated to correspond to jr c,87 instruction, which will make a relative jump backwards to right before Quilava’s data (there are some other DVs that work too for this). Quilava’s species ID, which corresponds to a sbc h opcode, will be executed, and this will make a = B9. This will make the rst 30 jump to F8B9, which is a little before box names.
Since we jump to the beginning of box names, we don’t have to scroll downwards to boxes 7-8 like the previous TAS. This, however, raises an issue, as we cannot plant our joypad input in the box 1 terminator, due to character restrictions. We can however plant our input in box 2’s terminator, so we can simply split the program into 3 box names. This is still much faster than scrolling down to boxes 7-8, so it’s an improvement nonetheless. The program is written like this:
BytesInstructionComment
Box 1
fa a6 ffld a,(ffa6)Reads current joypad inputs into a
fe 50cp $50We don’t want the terminator executed, so we eat it with a cp
00 x4nop x4Slide down to box 2
Box 2
aaxor dd stores last joypad input: find out differences to current input
ea d0 f8ld (f8d0),aWrite difference; will be executed as opcode later in the next cycle
aaxor dRestore current joypad input value
f5push afCopy current joypad input from a...
d1pop de... to d (store it as last joypad input)
f1pop afRestore a and f from the previous cycle
(f8d0)(any)Execute opcode written earlier this cycle
Box 3
f5push afSave a and f for next cycle
b6or (hl)Clears carry flag, needed for the jump
d2 b9 f8jp nc, f8b9Loop back to right before Box 1; carry will never be set
The input payload can be found here. It’s fairly similar to MrWint’s payload, with a few improvements, namely putting our warp data next to the player’s coordinates, and using the game’s auto-input system to talk to Red, so we can simply let the game beat itself.

Nerd Stuff

I used the same lua in my Pokemon Silver TAS to make this TAS, it can be found here.
Also, for nerds, here is an encode using the lua:
I also used a bot to find the needed trainer ID, my bot (which is heavily based on the RTA TID bot) can be found here.

Console Verification

Tikevin was able to console verify this TAS, the stream for it can be found here.
As a note, since the run is just ~30 minutes, RTC almost never becomes an issue for console sync.
Also, for publication, please use the Libretro GBC palette, that palette is the best.

Memory: Judging
Memory: The execution in this run seems to be very good but there’s major problems with the goal.
The run mimics the glitchless run with some minor route deviations until it gets the coin case to end the game. You look at bellsprout, then at the coin case, and then you’re at red and the game is over. It’s not a visually exciting glitch by game end glitch standards, nor are there any sort of lesser glitches leading up to that one. When discussing the submission with others, I realized the glitch had left such little of an impression on me that I forgot what it looked like and had to rewatch it to remind myself. You might as well just watch like 30 minutes of the glitchless run go “ok I’m done” and then skip to the end of the video. This is the kind of glitch that would make better for a neat youtube video solely dedicated to it than part of a dedicated TAS. The audience reaction wasn’t really great either and the ratings on the published run are less than stellar.
Additionally it is conceptually similar to the save glitch branch. Ultimately both runs aim to use a glitch to directly trigger game end as quickly as possible. The difference between them is that the save glitch branch abuses a mid-save reset to beat the game much faster, whereas this one avoids mid-save resets and performs the coin case glitch (which is a form of Arbitrary Code Execution) a bit later into the game. While Coin Case Glitch is about 26 minutes longer, this is similar to Super Mario Bros. 3 where a much longer run was obsoleted by a much shorter one. The difference in runs here ultimately comes down to the precise “attack vector” to perform the game end glitch, which imo is not an especially compelling difference for a casual audience. One could argue about the legitimacy of mid-save resets, but TASVideos has allowed them for a long time. While the specific method of save glitch used in TASes is hard to verify as being possible, it is known that one can reach game end through save glitch even in real time play. Additionally, save glitches are possible on all versions of Gen 2, meaning that the faster strategy is not locked out of versions.
In my eyes this goal definition is quite flimsy. If the goal is no mid-save reset, what happens if a run that doesn’t use save glitches is faster than the save glitch branch? Would it obsolete both this run and the other? We also have never really made any distinction between mid-save reset and not before, especially when Arbitrary Code Execution enters the picture. If that’s not the goal, is the goal of this run to use specifically the coin case glitch? In that case, wouldn’t runs that use a similar game end glitch setup that isn’t the coin case be unable to obsolete this one?
It seems the Pokemon RTA community has actually came to a similar conclusion, only listing any% and any% glitchless as major categories, whereas no save corruption is only listed under category extensions.
For these reasons, I think allowing the previous Coin Case run to remain unobsoleted was a mistake, and we should correctly have it obsoleted by the save glitch branch. We may revisit this in the future if rules changes occur but for now...
Last Edited by adelikat on 11/5/2023 2:10 PM
Page History Latest diff List referrers