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
- 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:
Bytes | Instruction | Comment |
---|
Box 1 | | |
fa a6 ff | ld a,(ffa6) | Reads current joypad inputs into a |
fe 50 | cp $50 | We don’t want the terminator executed, so we eat it with a cp |
00 x4 | nop x4 | Slide down to box 2 |
Box 2 | | |
aa | xor d | d stores last joypad input: find out differences to current input |
ea d0 f8 | ld (f8d0),a | Write difference; will be executed as opcode later in the next cycle |
aa | xor d | Restore current joypad input value |
f5 | push af | Copy current joypad input from a... |
d1 | pop de | ... to d (store it as last joypad input) |
f1 | pop af | Restore a and f from the previous cycle |
(f8d0) | (any) | Execute opcode written earlier this cycle |
Box 3 | | |
f5 | push af | Save a and f for next cycle |
b6 | or (hl) | Clears carry flag, needed for the jump |
d2 b9 f8 | jp nc, f8b9 | Loop 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: 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...