Listen "#10103: FractalFusion's GBA Pokémon: Sapphire Version in 22:04.834"
Episode Synopsis
In Aug. 2025, BluMagma beat Pokemon Ruby in less than 30 minutes (https://www.youtube.com/watch?v=VGgvNNeypSc) with a game-end glitch. I decided to make a TAS version, writing programs to find the necessary manips with a relatively small amount of delay, while applying known optimizations (for battle strategies as well as overworld mechanics). This TAS comes in at around 22m 4.8s, or 0:20 in-game.
For additional quick notes, there are on-screen subtitles added to the video above.
The goals are:
Aims for fastest time
Enters hall of fame
Speed/entertainment tradeoff (name Treecko "T")
Heavy luck manipulation
Note that the Japanese (J) version works differently from the USA/Europe (UE) version and there is no known equivalent to this particular game end glitch in the J version due to the differences in how the text parser deals with control codes. Also note that the natures of NPC trainer Pokemon in the J version, and thus the stats, are generally different.
Table of contents Glossary
Full notes (Part 1 - Background of the glitch)
Prototype TAS
Full notes (Part 2 - Forming the battle strategy)
Searching for a good manip
Full notes (Part 3 - Making the TAS)
Reducing delays while waiting for manips
Initial seed
Difference between boy and girl
Difference between Ruby and Sapphire
Specific events prior to the final preparation of the glitch
After whiting out - final preparation for the glitch
Optimizing naming movement
Possible improvements
Glossary
Manip: Can refer to any manipulation, whether RNG manipulation or memory manipulation for the game end glitch.
Crit max: Maximum damage roll on a critical hit. 1/256 chance of occurring (1/16 for critical hit, 1/16 for maximum damage).
RNG cycle: A call to the RNG advancing routine. May refer to a specific number indicating how many RNG calls since the initial seed. Also known as "RNG frame" (mkdasher's Pokemon Gen 3 Lua script) or "RNG advance" (PokeFinder).
FF: A byte with an unsigned value of 255 which in hexadecimal is FF. Indicates end of string for name parsers in Gen 3.
FD 00: A pair of consecutive bytes, with the first having an unsigned value of 253 (FD in hexadecimal) and the second having a value of 0. This is needed for the game end glitch.
FC 44: A pair of consecutive bytes, with the first having an unsigned value of 252 (FC in hexadecimal) and the second having a value of 68 (44 in hexadecimal). This is also needed for the game end glitch.
0x: Indicates a RAM address in hexadecimal.
Spinners: NPC trainers who can change which direction they are facing. Can be random or non-random. Will try to look toward the direction of the player when the player runs nearby.
Full notes (Part 1 - Background of the glitch)
The fact that using Thief on a Pokemon holding mail steals the mail and causes it to be glitched was known for many years on the J version. However, it was not explored on the UE version because it was (mistakenly) believed that it only worked on the J version. BluMagma uploaded a video showing that the UE version had this glitch.
It was then found at some point after that sending glitched mail as the 10th mail of the PC Mailbox while in an outside area will write map data to the 10th mail, causing the name field to be unterminated. It still took some time to take advantage of this glitch, but eventually BluMagma used a strategy that allowed Pokemon Ruby to be beaten in less than 30 minutes.
The important points of the strategy are as follows:
Use Thief on ally Pokemon holding mail in a double battle to get glitched mail.
Send glitched mail to the PC Mailbox while in an outside area so it is the 10th (the last) mail.
Have the first name parser read the byte sequence FD 00 after the 10th mail. This is done using the Dewford trend data set at the beginning of the game.
A name will be read from a different part of memory. Have that second name parser read the byte sequence FC 44 from Pokemon data. This is done by manipping a Pokemon and placing it first in the party.
This will cause execution to jump into box data. Execute the box names and jump to the hall of fame.
Thief and glitched mail
See BluMagma's video for how using Thief on a Pokemon holding mail results in a glitched mail.
By sending this glitched mail to the PC Mailbox as the 10th mail at address 0x202849C (EWRAM, 0x2849C) while in an outside area, it overwrites the mail data with map data so that the name field is unterminated (an FF byte terminates a string in this game.) This allows the name parser to potentially read a byte sequence FD 00 from beyond mail data.
FD 00
In order for the first name parser to read a sequence of bytes FD 00, the fastest way is to get the sequence to show up in the 40 Dewford trend bytes 0x2028508 (EWRAM, 0x28508). This code explains how the Dewford trend data are set up near the beginning of the game. Because the Dewford trend data involves storing an random 16-bit value, the sequence FD 00 is possible. As an example, arranging the 40 bytes from my TAS in 5 rows of 8:
2d 18 cb 81 44 14 06 18
aa 1d 73 fd 00 14 0a 1a
20 11 d9 03 0e 14 21 18
1e 5b 6a ec 16 14 17 18
1e 51 e8 21 10 14 07 1a
Since the 3rd/4th columns contain the RNG value, FD 00 can show up either in the 3rd/4th columns, or the 4th/5th columns. However, this only occurs with a probability of about 1/2780.
Additionally, there must not be an FF byte before the FD 00 byte, since FF terminates the name string. In order for this to happen, the Dewford trend data itself must not contain FF before FD 00 (which is unlikely to happen). However, the data between mail and Dewford trend involve the random man in the Mauville Pokemon Center (Bulbapedia calls them the Old guys). In order for FF byte(s) not to show up in this part of data, the man must be Bard, Hipster or Giddy. That is, the last digit of the trainer ID must be 0, 1, 2, 3, 8, or 9.
Once the first parser hits FD 00, it invokes a second parser that starts reading from address 0x3002900 (IWRAM, 0x2900)
FC 44
In order for the second name parser to read a sequence of bytes FC 44, it is required to place a Pokemon whose data contains FC 44 in the first party slot at address 0x3004360 (IWRAM, 0x4360), keeping in mind how Pokemon data is stored. There are a few different ways to do this.
The RTA (speedrun) strategy is to manip a specific Treecko. Due to how difficult the other manips in RTA already are, the strategy used by BluMagma involves getting a specific Treecko, having two moves' PP at specific numbers, and naming the player AAAAAAA and Treecko AAAAAAAAAA to prevent FF bytes from showing up in Treecko's name field. Having to name the player and Pokemon long names is a big time loss.
That being said, there is a more direct method that doesn't require extremely long names and that is to get FC 44 in the first 8 bytes of the Pokemon. Since the first 8 bytes of Pokemon data are the Personality ID (four bytes), original owner's trainer ID (two bytes) and original owner's secret ID (two bytes), all of which are randomly generated numbers, it is quite feasible (at least for TAS) to manip these values to get FC 44. It is also possible to use Abra as the Pokemon for this manip instead of Treecko.
In addition, prior to activating the glitch, a save and reset is required in order to clear FF bytes from before the Pokemon data (FF bytes usually occur when doing a battle).
Once the second parser hits FC 44, it accesses a control table of ROM pointers, but goes outside it since there is no bounds checking for the second parser on the FC control byte. FC 44 causes the execution to start executing RAM from inside the box Pokemon data in Box 1 Pokemon #2 at address 0x20300FE (EWRAM, 0x300FE). Provided the boxes have no Pokemon, it is all zero bytes (lsl r0, r0, #0, which does nothing) until the box names at address 0x20383E4 (EWRAM, 0x383E4).
Box names
Box names are written so that executing them will jump to the hall of fame. The exact box names depend on version 1.0 vs 1.1 (but not on Ruby vs Sapphire). The box names used in RTA for v1.1 are as follows:
Box 1: F ♂ L B _ 6 L ’ [F♂LB 6L’] ← '_' is space, '’' is right single quote.
Box 2: Y F C T I D F [YFCTIDF]
Box 3: A A 3 R B H [AA3RBH]
Box 4: A S U R H [ASURH]
Box 5: 3 G R H [3GRH]
Box 6: E E I 3 m j n 3 [EEI3mjn3]
Box 7: g n [gn]
This sequence of box names is widely accepted by the RTA community as the proper way to activate the hall of fame in the glitched run, so it is best to use these box names.
Prototype TAS
It took me a while to understand how the glitch worked (my first attempt to get the glitch ended in failure), so I used BluMagma's speedrun guide and recreated BluMagma's strategy in BizHawk, down to the trainer ID, the Treecko, and the move PP. It was only after successfully recreated the strategy in BizHawk that I could trace log it to understand how the glitch actually worked.
For historical purposes, here is the prototype Pokemon Ruby (v1.1) TAS that I made in recreating BluMagma's strategy. It is not TAS-optimized:
UserFiles/Info/639007598267496995
Full notes (Part 2 - Forming the battle strategy)
First, it is well understood that Treecko and Abra are the best two Pokemon to use here. Treecko gets Absorb (a same-type move) earlier than the other starters, which is vital for the first gym leader battle. A second Pokemon is required for the mail Thief glitch, and Abra not only learns Thief, but has Teleport to go back quickly to the double battle south of Rustboro City.
Second, it is important to get a good Treecko, even upon all the other required manipulations. To figure out a Treecko that does well in the battles, I had to analyze each battle. There are websites help with stat and damage calculation.
After going through many iterations, I settled on the following strategy. Brief notes on some battles are as follows (More detailed notes on every battle are on this wiki page.)
VS Rival
This battle requires a crit max (probability 1/256) as one of the two crits on Torchic, unless Treecko has Attack IV of 30-31 with Attack+ nature. Note that Brendan's Torchic has a greater Attack stat than May's Torchic.
VS Youngster
If one of the hits from Pound is a crit max, the other does not need to be a crit, just a max (non-crit) damage roll. Otherwise, two crits are needed.
Wally tutorial
As in previous TASes, to get the Ralts KO, Zigzagoon needs an Attack stat of 11 or 12, and Ralts needs an HP stat of 17 (HP IV less than 4) and a Defense stat of 6 (Def IV less than 10 and Def- nature). Then Zigzagoon can KO Ralts with max damage rolls.
VS Grunt 1
In order to 2-hit KO Poochyena, the first hit is crit Pound, the second is crit Absorb when the Overgrow ability is active (move power is 1.5x if Treecko's current HP is at 1/3 of max HP or lower). So Treecko needs to take hits when possible to make this happen.
Crit Absorb with reasonable stats does 15 damage at most. With Attack IV at 25+ with Atk+ nature, crit Pound does 12 at most, so no crit max is necessary. Otherwise, crit Pound does 10 at most and a crit max manip is necessary for both hits, which I consider an unreasonable manip. This pretty much requires Attack IV at 25+ with Atk+ nature on Treecko.
VS Gym Leader
Nosepass can't be two-hit KO unless one of the next two Absorbs is with Overgrow active. Since Treecko's HP is full at this point, the strategy is to get a crit Absorb (not in Overgrow), then have Nosepass use Rock Throw to hit Treecko into Overgrow range, then get a crit Absorb with Overgrow.
Conditions required: One of HP IV and Defense IV must be 9 or less and the other is 19 or less. The Sp.Attack IV must be 20 or greater. Finally, for Nosepass to use Rock Throw instead of Rock Tomb, Treecko's Speed must not be greater than Nosepass's Speed. So Speed IV must be 9 or less with a Spe- nature.
VS Twins Double Battle
Since I don't need to win this battle (only need to thief mail from Treecko to get glitched mail), the strategy is to white out as fast as possible. The most feasible strategy is for Abra to hit Treecko with Thief, Treecko to KO Abra with crit Pound, and Lotad to KO Treecko with Astonish.
A second, far less likely strategy, is for Abra to KO Treecko with Thief and Lotad to KO Abra with crit Astonish. This requires an Abra with very low HP and Defense (including a Defense-lowering nature), and with all the other manips required, this did not come up in my search.
Searching for a good manip
After running through a few trials, I nailed down a reasonable range of RNG cycles for the important manips (trainer ID, Treecko stats, Abra encounter in Granite Cave). In particular, the Abra encounter has a wide range, keeping in mind that I can give and take mail with Treecko to pass the time without losing more than a couple seconds. I estimated the RNG range for the Abra encounter to be from cycle 73000 to cycle 81000.
Here are all the conditions together that I ran a search for:
The last digit of the trainer ID must be 0,1,2,3,8,9.
The Dewford trend data must contain FD 00.
Treecko must have Brave (Atk+ Spe-) nature.
Treecko must have Attack IV >=27 and Sp.Attack IV >=20.
Of Treecko's HP IV and Def IV, one of them must be <=9 and the other must be <=19.
Treecko must have Speed IV <=9.
The first 8 bytes of either Treecko or Abra's data contains FC 44. This may involve manipping their PIDs, and/or the trainer ID and/or the secret ID.
Manipulating all this would be nearly impossible without my custom C++ program which tries to find results with small amounts of delay. The link to this C++ is shown below:
https://www.mediafire.com/file/pjq9jx6by7jclox/newruby3.c
My program found a result which I will just summarize as follows:
The initial seed is 16026 (or in hex, 3E9A).
The trainer ID is 02372 (in hex, 0944) the secret ID is (in hex) c750, and the Dewford trend bytes are the same as in the example above for the section "FD 00". The RNG cycle that yields this trainer ID is cycle number 2561 and the expected frame delay is 75.
The Treecko has a PID of (in hex) 1e4394f7, a nature of 2 ("Brave", Attack+ Speed-), and IVs of (9/27/18/25/26/6) (Speed listed last). The RNG cycle that yields this Treecko is cycle number 9528 and the expected frame delay is 122.
The Abra has a PID of (in hex) fc08317e, a nature of 15 ("Modest", Sp.Attack+, Attack-) and IVs of (18/2/5/14/15/10). The RNG cycle that yields this Abra encounter is cycle number 80200 (near the end of the possible range).
The trainer ID ends in 2, the sequence FD 00 shows up in the Dewford trend, and the first 8 bytes of Abra's data are 7E 31 08 FC 44 09 50 C7, which contains FC 44. These are all required for the glitch to work.
There is a small 1/20 chance that the result is screwed by the Abra being generated holding a Twistedspoon. Fortunately, it didn't happen for this result.
Full notes (Part 3 - Making the TAS)
Now that I have a result, the only thing left is to put the run together. Overworld optimizations such as bumping an object/NPC before slow turning, and talking to NPCs from the side due to pathing, are used here. Also, it's best to keep text at mid speed, because it makes battle easier to manip by controlling the text timing. Some games like Fire Red / Leaf Green have a 1-frame penalty for each dialog box on mid speed instead of fast, but not Ruby/Sapphire.
Reducing delays while waiting for manips
In all battles where you see the battle field (i.e. not in the bag or Pokemon menu), the RNG cycles twice per frame, instead of once per frame like on the overworld. So this incentivizes delaying in battle vs delaying in the overworld.
To further reduce the delay, I try to make random overworld NPCs consume as many RNG cycles as possible. This is very random (no pun intended).
If there is a random spinner trainer, running nearby will consume one extra RNG cycle per frame for 8 frames while the spinner tries to look toward your direction. Normally random NPCs randomly wait 32, 64, 96 or 128 frames before the next action, but running near a spinner rerolls this every frame. So, running near random spinners is a way to consume RNG cycles to help with manips.
(If the spinner is not random, no reroll occurs and the RNG is not affected.)
Initial seed
I set the date/time to 2010 Jul. 1, 17:52:00 and that date/time yields this initial seed (in hex) 3E9A. It was found using PokeFinder . (For how the date and time determine the initial seed, see this forum post).
Difference between boy and girl
It turns out for this manip that there are less delays if you choose the girl over the boy. Normally the boy is faster because there are more long Brendan dialogs (if you choose girl) than there are long May dialogs (if you choose boy), as well as the walking distance depending on which house you start, but for this manip, choosing the girl is faster. As a bonus, Brendan's Torchic has a higher Attack and does more damage (see the strategy above).
It doesn't cost anything to name the character something other than A since I have to wait for the trainer ID manip anyway.
Difference between Ruby and Sapphire
Since I do not encounter Carvanha or Numel, the only difference is that "AQUA" has one less character than "MAGMA". That's why the final TAS uses Sapphire. :)
Specific events prior to the final preparation of the glitch
Since I need to wait for the Treecko manip, it is better to set the options during the time I need to wait. It would be slower to do it afterward. I leave the text speed on mid.
Fortunately the game gave me a wild Poochyena with 5 Defense as the first tutorial battle. So, no max damage roll is required.
I had to wait a while to get the necessary crit max here vs Rival Torchic.
The crit max I got here vs Youngster Zigzagoon needed some delay but was slightly faster than getting two crits.
In Petalburg, I get 10 (actually 11) mails from this mart. Normally I would also buy an Escape Rope for Granite Cave later (this would save like 1 second) but the manip doesn't work out, so I don't do that.
I will need to eventually give and take mail (sending mails to the PC Mailbox) on Treecko 9 times, and give a 10th mail so that Abra can thief that mail. Since I have to wait to get a good tutorial Ralts manip, I use that time to give and take mail to Treecko. I enter the menu after turning for 1 frame in the overworld to save the slow turn delay.
I try to consume as many RNG cycles as possible by running near random spinners, because the necessary Abra encounter is near the very end of the possible manip.
In Rustboro, I don't need Quick Claw for this TAS, and Treecko is at least as fast as any other opposing Pokemon.
I found that, by getting a crit max as the first Absorb on Nosepass (which conveniently required very little delay), that allowed Treecko to absorb one less HP on the second Absorb, and it turns out a critical hit on Treecko will be saved in the future.
Nosepass needs to do max non-crit damage with its Rock Throw on Treecko so Treecko goes from 28 HP to 9 HP for Overgrow.
It is faster to go along the lower portion of the path going to the right, but on the upper portion going back to the left.
Based on the manipped Treecko and Abra, it is best to take a critical hit from the grunt's Poochyena here.
On the way back left, I run about 3 squares away from a random spinner in such a way that her rerolled delay is 32 frames. This allows me to walk by exactly when she looks away, and I don't need to take more than 3 walking steps or take a longer path.
While leaving Rustboro, I enter the Pokemon Center to set the teleport point. It is faster to do it here instead of before doing the 1st gym, since it avoids a slow turn delay.
Talking to Steven from the side is not actually faster than talking in front. It is actually slower by 1 frame. However, the Abra manip is faster when I do it this way.
Since I have to wait a long time for the Abra manip, I give and take the rest of the mail on Treecko, then as I run out of Granite Cave, encounter the necessary Abra near the entrance/exit.
For the double battle, with Treecko at 9 HP, critical hits are not required for the hits against Treecko. Just max (non-crit) damage rolls.
After whiting out - final preparation for the glitch
Once back in front of Rustboro Pokemon Center, take off glitched mail from Abra and send it to the PC Mailbox as the 10th mail. It must be done here, not inside the Pokemon Center. Since I need to save and reset at some point, the best time would be here as well.
After continuing the save file, I enter the center and use the PC. I will eventually have to move Treecko out of the first party slot. Depositing Treecko in the box saves on the hall of fame animation, so I do that. However, since I have to rename the boxes, the fastest way is to select the "Move Pokemon" option, rename the boxes, then deposit Treecko here (rather than in the "Deposit Pokemon" option). Treecko is deposited into Box 1 slot 1 and doesn't interfere when execution jumps into Box 1 slot 2.
Optimizing naming movement
The menu screen for entering names has some weird features that I take advantage of when renaming the boxes. Pressing start moves the cursor to END. Moving one or two characters then pressing select to pull up a different chart might be faster than pressing select first. Things like that.
If you enter a full 8-character name, there is an unavoidable delay before the cursor jumps to END.
After renaming the boxes, I dump Treecko in Box 1 slot 1, then go to the Mailbox PC and look at the 10th mail to jump to the hall of fame.
Possible improvements
It might be possible to get a better manip.
Gabraltar brought to my attention that very rarely Nosepass can actually use Rock Throw over Rock Tomb, even if Treecko is faster than Nosepass and at full health at the beginning of the turn. Funnily enough, neither of us knew until very recently. So it probably makes a better manip even more likely.
A program that optimizes overworld even more than I've done so far might work. Good luck understanding how it all works, though.
Changing the box names in ever more gimmicky TAS-only ways maybe, but I think that should be based on community consensus.
One possible angle of attack brought up in RTA discussion (but one that I do not think will be faster) is the 0-badge route of using Zigzagoon's Pickup ability to get 20+ Rare Candies, then level either Zigzagoon/Linoone or Skitty until it learns Covet (which works like Thief). How it looks like is completely theoretical as this is completely untested. I don't think this will work due to how long it takes to manipulate 20+ Rare Candies and use them.
More episodes of the podcast TASVideos Submissions
#10105: eien86's DOS Street Rod in 11:02.754
22/12/2025
ZARZA We are Zarza, the prestigious firm behind major projects in information technology.