Interesting Glitches in Pokémon Red/Blue

Because the franchise is fresh on everyone's mind with Pokémon Go

And more importantly, why they happen

Even if you don't like Pokémon...

I think this is a really good case study about a complex piece of software that tries its best to work on very limited hardware. We take a lot of features on modern hardware for granted.

While not directly applicable to what we do here, some exploits do share similar vulnerabilities to known exploits in PHP, like so:

Missingno. or 'M'

Probably the most popularly known glitch, lots of people know it exists but probably not why it happens

How to Perform:

  • Be able to use both Fly and Surf, and have visited Cinnabar Island already
  • Talk to the Old Man in Viridian City and watch his "how to catch a Pokémon" tutorial
  • Fly to Cinnabar Island and surf along the east coast

What it does:

  • Changes the encounter table so you run into impossibly high-level "normal" Pokémon
    • ... and several not-so-normal ones, like Missingno.
  • Modifies the quantity of the 6th item in your items list to either 128 or 255

The tens-digit is trying to represent a number in base-16 but is just trying to use the sprite data a few blocks after '9' instead of the letter 'F'

Why it happens:

In short: the game reads memory it shouldn't and interprets it as valid data anyhow.

  • Visiting the Old Man is important because the game writes the player's name onto the stack for temporary storage and overwrites your name with "OLD MAN"
    • When finished, the game reads from the top of the stack and replaces "OLD MAN" with your name again, but doesn't change the stack
  • Cinnabar Island is unique in that it's possible to encounter Pokémon on the east coast, but doesn't have an encounter table native to the area
    • When entering a new area, the encounter table read from some table and put into active memory. Normally, this is the previous area you were in, so it's not an issue...
    • ...but if you just came from Viridian City with your character's name on the top of the stack instead, the game reads your name as if it were encounter data
  • Therefore, what you encounter using this glitch depends on the name you input at the beginning of the game
  • Or more specifically, the characters in spots 3, 5, and 7 of your name determine which Pokémon show up
A: Golduck
B: Hypno
C: Golbat
D: Mewtwo 
E: Snorlax
F: Magikarp
G: Missingno.
H: Missingno.
I: Muk
J: Missingno.
K: Kingler
L: Cloyster
M: Missingno. 
N: Electrode
O: Clefable
P: Weezing
Q: Persian
R: Marowak
S: Missingno.
T: Haunter
U: Abra
V: Alakazam
W: Pidgeotto
X: Pidgeot
Y: Starmie
Z: Bulbasaur 
a: Missingno.
b: Missingno.
c: Missingno.
d: Ponyta
e: Rapidash
f: Rattata
g: Raticate
h: Nidorino
i: Nidorina
j: Geodude
k: Porygon
l: Aerodactyl
m: Missingno.
n: Magnemite
o: Missingno.
p: Missingno.
q: Charmander 
r: Squirtle 
s: Charmeleon
t: Wartortle
u: Charizard
v: Missingno.
w: Missingno. (KABUTOPS FOSSIL)
y: Missingno. (GHOST)
z: Oddish 
  • Also, the item count part of the glitch occurs due to some unintended interactions between the Pokédex and the item list
  • The Pokédex stores one of 3 values for a Pokémon:
    • not seen, seen, caught
  • This table is only 151 bytes long, but the index for the 'M' variant of Missingno extends past this
  • Game Boy hardware doesn't have support for array guards, so ... an array is really just a pointer and doesn't 'know' its max length
#define NOT_SEEN = 0;
#define SEEN = 128;
#define CAUGHT = 255;

byte pokedex_table[151];
byte item_list[41];
byte missingno_pokedex_index = //some byte that's definitely greater than 151
pokedex_table[missingno_pokedex_index] = SEEN or CAUGHT;

Glitch 2: Catch Mew without cheating

No Gameshark, no external devices, nothing except natural in-game input

How to Perform:

Not just for Mew, and not intended by the developers

  • Have at least one trainer with a maximum "sight" distance equal to the length of the screen not fought yet and some way to instantly travel (Escape Rope, Dig, Teleport, Fly)
    • For Mew: Gambler on Route 8, youngster on Route 25
  • Has some margin of error - save beforehand to easily retry
  • Step towards this trainer so they will attempt to battle you as soon as you step
  • There will be one frame where you can pause the menu -- use this chance to travel before the fight starts
  • After successfully cancelling the fight, run into grass
    • Doesn't matter where -- we're doing more "override the encounter table" shenanigans
  • A very specific Pokémon should show up!
    • Which one depends on which trainer you used for this glitch

Why it happens:

  • We're able to pause the game for one frame while the trainer gets loaded onto the screen
    • The trainer always faces south, then turns, creating an extra frame of delay in this case
  • Encounter data is loaded for the fight to begin, depending on the trainer
    • The Pokémon itself is dictated by the Special stat Pokémon in the trainer's last slot
      • Certain trainers have Special stats that generate Mew
    • The level depends on the modifier on the attack stat (starts at 7, ranges from 1 to 13, modified with buff/debuff moves like Growl or Swords Dance)

More than 151 again

  • What happens if the Special stat picks something outside of the normal range of 1-151?
  • Same thing as Missingno, just a different method
    • With even more possibilities!

Hijack Pokémon and use it as a programming IDE

  • Yes, really.
  • Requires the use of some automation with frame-perfect timing
    • So getting a bot to play for you is necessary​...
    • ...but this is all still technically feasible without directly modifying any in-game memory via cheating devices

RNG Abuse in Later games

  • "Surely having an in-game clock will satisfactorily randomize the seed value and thwart any attempts to make our RNG deterministic!"
  • Nope:

Pokémon Glitches

By tdhoward

Pokémon Glitches

  • 1,233