With Pokémon being one of the most famous RPG series, I was quite baffled to see that there seems to be no valid any% route for the first generation games (RBY) that utilizes all of the known beneficial glitches, which this game certainly has plenty of.
While this game can be beaten in less than a minute of in-game time using save data corruption (see here), the term "any%" for this game commonly refers to a category where this specific glitch is forbidden and therefore more of the actual game is presented in the movie.
- Forgoes save data corruption
- Aims for the fastest completion time
- Heavy luck manipulation
- Heavy glitch abuse
- Contains speed-entertainment tradeoffs
Used emulator: BizHawk 1.4.1
About the run
The choice of the right emulator was a tough one. Since VBA is not a preferred emulator anymore and is also known to not emulate very accurately, I deemed it unusable for this run. The movie contains some heavy glitches, which require a high amount of emulation accuracy that VBA can't provide. Pokémon RBY has SGB capabilities, so I'd like to use them, but other than VBA the only option is to emulate an SGB rom with bsnes, which is both too unstable and too slow for the purpose of this movie. A whole lot of luck manipulation will be required for this run, which means a whole lot of rerecords. Emulating a complete SNES system just for a GB game, especially with bsnes, which is known for being a slow emulator, was not what I needed. So, forgoing the SGB capabilities, I decided to use gambatte, which is both accurate and fast. While both of the preferred GB emulators (BizHawk and lsnes) use the gambatte core, I found lsnes unusable for my purposes due to the frame timing it uses (see this topic for more info), so I ultimately went with BizHawk.
As the Red and Blue versions are basically the same game, differing only in very few aspects, they are considered the same category. The differences relevant to this run are:
- Charmanders cry is 7 frames shorter than Squirtles, making the title screen 7 frames quicker in Red. The run soft resets twice, adding up to a total of 21 frames advantage for Red
- The rival's default name is one letter shorter in Blue (RED vs. BLUE), saving one frame for each occurence of the rival's name. It occurs 26 times in this run, a 26 Frames advantage for Blue
The total advantage for Blue is therefore 5 frames, which can be easily gained or lost in the process of luck manipulation. I chose the Blue version merely as a presonal preference.
Luck manipulation is one of the main aspects of any Pokémon TAS. Almost everything in this game is random: encounters, stats, hit chance, amount of damage, critical hits, status ailments (e.g. burn using ember), the move an enemy uses, overworld movement of NPCs, etc. To make it even worse, the RNG of the first generation Pokémon games depends on the value of a hardware register (which is basically a clock counting the number of CPU cycles), and it has proven to by hard to predict. Also, it means that literally every decision influences the RNG state, as the number of CPU cycles is likely to be different for each execution path. To deal with this issue, I decided to not play it by hand, but let a computer program play it and brute-force different possibilities to get favourable RNG outcomes when needed. As a result, the whole run is generated by a computer program, not a single input is made by hand. That is also the reason for the high amount of rerecords used to create the movie.
A few speed-entertainment tradeoffs were made in this run, which are basically the same tradeoffs made by the currently published run (#2945: p4wn3r's SGB Pokémon: Red/Green/Blue/Yellow Version in 41:02.38)
- Naming the character "I": While the name "A" would be a couple of frames shorter to select, naming it I results in sentences like "I defeated BUG CATCHER" or "I found POTION" which make it worthwhile.
- Forgoing using red bar: Having the fighting Pokémon at low health plays a constant warning sound which prevents other sounds from playing and therefore saves some frames. But since the constant beeping is a major annoyance, it is not used in this run.
This run uses quite a lot of glitches, some of which are new to this category and cause most of the improvement compared to the published run.
Brock Skip glitch
You can bypass the boy that is supposed to prevent you from leaving Pewter city without fighting Brock. Due to a programmer's oversight, the joypad is not properly disabled during that scene, allowing you to use A,B,Select,Start (but not the directional keys) at a specific frame after the text finishes and before he is escorting you to the gym. If you set the menu cursor to the "Save" option beforehand, it enables you to save and quit in the middle of it, skipping the escort and allowing you to leave Pewter. This glitch is rather easy to perform even on console, as long as you use the B button to close the text boxes. Using the A button is also possible, but makes it way harder to hit the correct frame for opening the menu.
Trainer-Fly is the most important glitch in this game, as it is a precursor to all more advanced and drastic glitches and offers a multitude of possibilities. When an NPC enters your screen, it faces south for one overworld tick (two frames) until the game corrects it to the actual facing direction. When encountering trainers that have a line of sight that reaches the edge of the screen and that are facing north, west or east, this leaves you with a one overworld tick window until the trainer engages you and the inputs are disabled. You can use this tick to open up the menu and escape the battle by using Fly, Teleport, Dig or an Escape Rope, activating the Trainer-Fly glitch. It has the following notable effects:
- you can't interact with overworld entities. This includes NPCs, Items, Signs, ... (since the game thinks you are currently being engaged by a trainer)
- you can't open the main menu
- the fight you escaped is stored for the area you triggered it in
Skipping mandatory trainers (Trainer-Fly)
This glitch, although it's a pretty obvious consequence of Trainer-Fly, has not been used in any route I've seen and saves a major part of the time compared to the currently published run. After using Trainer-Fly, all trainers in the area you triggered it in are inactive, since the game thinks you are already in the process of battling one in this area. This allows you to simply walk past them, even if they are mandatory otherwise. This is used twice in this run, in Mt. Moon (skipping both mandatory fights) and in Route 6 (also skipping both mandatory trainers).
Re-enabling overworld interaction (Trainer-Fly)
The first two undesirable effects of Trainer-Fly can be undone while preserving the third one by either saving and quitting or blacking out. Fortunately, the PCs are not treated as overworld entities, allowing you to access them and save the game by changing storage boxes. This is used once in this run in Mt. Moon, allowing picking up the fossil after bypassing the mandatory trainers. Note that the cutscene that is triggered by doing that overrides the state of the area, canceling out all further Trainer-Fly effects.
Encountering arbitrary Pokémon or Trainers (Trainer-Fly)
This variant is widely known as the Mew glitch, as is allows you to catch the otherwise unobtainable Pokémon Mew. After battling some trainer while Trainer-Fly is active, it resets the "currently in battle" flag, while still preserving the stored battle in the area it was triggered. Whenever you enter that area then, the stored battle will start, although the data for the fight is overridden by encounters that happened inbetween. Manipulating the last battle therefore allows you to manipulate the battle you'll get upon entering the area. More specifically, the Special stat of the last fought Pokémon determines the type of Pokémon you encounter, while its Attack modifier determines its level (ranging from 1 to 13) This is used once in this run at Route 6. A wild Drowzee is used to encounter the glitch Pokémon Missingno.
Skipping Snorlax (Trainer-Fly)
When encountering a Pokémon using Trainer-Fly, the game treats it as legendary Pokémon encounter (like Snorlax, Mewtwo, legendary birds). After the fight, the sprite of the legendary Pokémon is removed from the map. Due to particular laziness of the programmers, the game simply removes the first removable sprite in the area. In no removable sprites are present, the game does not override the list and keeps the removable sprites of the last area that had one. This can be exploited to remove either of the two Snorlaxes and clear the road, sequence-breaking the game, and is used in this movie to remove the Route 12 Snorlax.
Missingno. item duplication
Missingno. is a glitch Pokémon that is encountered when there is no matching Pokémon for the Pokémon index number that was issued. The most useful property of Missingo. is that it has the PokéDex number 000. Upon encounter, the game tries to set the "seen" flag for the encountered Pokémon, which in Missingno.'s case overrides the highest bit of the quantity of the 6th item in the player's bag with a 1. What that does is essentially giving the player 128 more of that item, unless he already had 128 or more of it, in which case it does nothing. When Missingno. is cought, the same bit is set again, allowing two item duplications with one Missingno. encounter. This is used in this run to obtain 255 potions that are needed for another glitch described below.
Inventory Unterflow Glitch
This is the second new glitch introduced to the route and allows the corruption of the item list and therefore arbitrary code execution. It is an alternative to the ZZAZZ glitch that is used in the currently published run, and is faster to set up, less destructive and better controllable.
The item list is represented the following way in memory:
<# of items> <item 1> <quantity 1> <item 2> <quantity 2> ... <item n> <quantity n> 0xFF
The value 255 (0xFF) is used to mark the end of the list. Using item duplication, it is possible to obtain 255 of one item, which confuses the game and modifies the list in unexpected ways. Especially removing items operates unexpectedly. What it does is decreasing the number of items by 1 and shifting all following bytes by two until it finds an 0xFF. For example, if your items look like:
3 <ball> 1 <potion> 0xFF <water> 1 0xFF
and you toss the ball, it becomes
2 <potion> 0xFF <potion> 0xFF <water> 1 0xFF
The potions duplicated, and the water is still there, even though the item count is only 2. When tossing all the potions in the first slot two more times, we get
0 <potion> 0xFF <potion> 0xFF <water> 1 0xFF
No more inventory actions are possible at this point, because the item counter is what soley determines how far you can scroll in the item list. But when you now trigger an action that removes some item from your inventory, like the Saffron City guards, the item counter underflows:
0xFF <potion> 0xFF <potion> 0xFF 0xFF
You can now scroll down far beyound the actual item list into other memory areas, using the inventory as a hex editor to modify bytes as you please. This is all that is needed to complete the game, just writing the right bytes to the right spots will make the game ending sequence start immediately.
I manipulate the low byte of my trainer ID to be 0xC2, which is used at the end to trigger the credits. Some other values work, too, but this one is the fastest to manipulate.
Since I am going to use Charmander throughout this run, I need excellent stats to kill off opponents quickly. I manupulate the Attack and Speed DVs to be 15 and my Special DV to be 14. I actually need all of them to be that high for some trainers, having any of them lower than that would cost me a turn.
I collect a hidden potion which is needed for later glitches. Buying one at the mart would also work but is slower.
I buy 2 escape ropes and 6 pokeballs at the mart. I will only ever use two of the balls, but buying the extra ones decreases my money to just the right amount that is needed at the end. Also, I execute the Brock skip glitch as described above to avoid fighting Brock. Note that a soft reset is performed (by pressing A, B, Select and Start for 16 frames) to ensure not to corrupt the save file.
Visiting the Pokecenter sets my teleport location. I collect and learn Mega Punch and do Trainer-Fly from the rocket at the third floor (unsing one of the escape ropes I bought). This is where the first route differences occur. Instead of using the Trainer-Fly to obtain a L100 Gengar, I re-gain interaction control using save and soft reset and skip the rocket and the nerd, who are otherwise mandatory. The time saved by this easily outweights the additional turns needed to defeat the upcoming trainers.
The second and last visit of a Pokecenter is used for both restoring PP and setting the teleport location. The PPs will be used up almost completely in the upcoming fights, leaving Mega Punch with 0 PP and Ember at 1 PP at the end of the run.
After clearing the Nugget Bridge, I catch an Abra for its move Teleport, which I will use to trigger a second Trainer-Fly. The second escape rope is used to return to Cerulean after talking to Bill.
While fighting the rocket, I am purposely taking damage from the Machop, which enables me to use potions later. The Machop is the most convenient place to take damage, as it has only the move karate chop which hits with 255/256 probability, making it hard to manipulate to fail.
I switch the potion I got in Viridian Forest into my 6th item slot and do Trainer-Fly from the Bug Catcher to skip the two mandatory trainers right before Vermilion. Re-gaining menu control is not necessary here, as I face the gambler at Route 11 anyway to set up encountering an arbitrary Pokémon. I enter and immediately leave Route 12 to set up the Snorlax skip and encounter a L13 Drowzee with a special stat of 31 (32 works too) in order to encounter Missingno. Missingno. increases my potion count to 129, and I use one of them right away (healing the damage inflicted by machop) and get hit by water gun to use a second potion. After that I catch Missingno. to increase the number of potions once more to a total of 255, the number I need for the Inventory Unterflow Glitch. Also, Missingno. has a ridiculously long cry which contains many other cries in it, you can test yourself and see how many you recognize.
With Snorlax being removed, I can proceed to Celadon City to buy some fresh water and finishing the game using the Inventory Unterflow Glitch. This is where everything I did during the run comes together. My money is now exactly 7600, which puts a 0x76 (the amount of money is BCD-encoded) at memory address 0xD348, which corresponds to the 22nd item slot. By switching the 22nd item with the 33rd, I move the 0x76 to 0xD35E, which is the address the current map is stored in. 0x76 represents the Hall of Fame room. Also, the low trainer ID byte 0xC2 is residing at 0xD35A, which corresponds to the 31st item slot. The address 0xD35B is related to the background music and is always 0xC3 in this area. Switching the 31st and the 41st item moves both values to 0xD36E and 0xD36F, respectively, which are used to store the map's script pointer. The script pointer contains an address which is executed once every overworld tick. By tossing 95 items, the address is changed to 0x64C2 (it's Little Endian), which corresponds to starting Oak's final rating and the credits.
In order to be able to toss the glitch item 0xC2, it is necessary to open the save menu beforehand. The addresses used to determine whether 0xC2 is a key item (and therefore too important to toss) is the same that is used to save background tiles covered by a yes/no popup in order to restore them afterwards. The popup that occurred upon tossing the inventory items made 0xC2 a key item, and the save menu popup can be used to undo that.
- Changing the game options at the title screen is actually significantly slower than doing it in-game.
- When closing a text box, there is a function that holds the text box open until A is released. Closing a text box using the B button (instead of A) therefore saves a frame.
- Pressing A or B during a text display may or may not delay the text by one frame, depending on where the program counter was when the VBlank interrupt occurred. To avoid delaying a frame on the end of a text box when you are required to press A or B to progress the text, pressing and holding A or B at a prior frame that has no delay can save 1 frame compared to not pressing any button.
- When scrolling the inventory, the game only requires you to press some key that you didn't press in the last frame, it doesn't need to be the directional key you want the cursor to go to. That means holding up/down while alternatingly pressing left and right will save one frame per scrolled item, compared to tapping the up/down key.
Route variations that didn't work out
- Getting the bike. Getting the bike seems tempting, but it turned out to be slower by about 30s
- Dumping all but one Pokémon in a box to save time at the Hall of Fame cutscene. Same as with getting the bike, the extra time needed is larger than the amount of time it saves.
- Skipping the Hall of Fame cutscene. Although it is possible to do so and execute the credits directly, the game will not properly end afterwards. It would be stuck in an infinite loop, repeating the credits over and over, much like seen in #3903: Masterjun & FractalFusion's GBC Pokémon: Red/Green/Blue/Yellow Version "glitched" in 01:10.47
All of the glitches shown here are doable on console as well, especially the new Inventory Underflow glitch. I personally tested it on console, but unfortunately I don't have the proper equipment to provide video evidence. None of the glitches require tool assistance to be performed, they are not sensitive to precise timing or any other obscure requirement that is not controllable by a human player. You can easily create a (non-TAS) speedrun using a variation of this route, all you need is to find a setup to get the right bytes in the right places. Note, however, that memory addresses differ in Yellow, or even in different language versions of Red and Blue, so the setup may be different than this one.