Analyzing Pokemon Yellow - disassembled!

Analyzing Pokemon Yellow - disassembled!
Photo by Mika Baumeister / Unsplash

In my journey to analyse and manipulate retro games, I came across this disassmbled version of Pokemon Yellow. With my low level programming skill being, eh low level, I instead performed a static analysis of the files to uncover any secrets or interesting facts about one of the greatest games of all time.

This post contains a portion of the game data that I was interested in. Much more Yellow and other Pokemon game data is also available.

Constants

Fixed values for game data such as Text, Trainer names and SFX.

Trainers

https://github.com/pret/pokeyellow/blob/master/constants/trainer_constants.asm

There 47 types of trainers, including a few you will not encounter in the OG game, such as:

  • trainer_const UNUSED_JUGGLER ; $0D
  • trainer_const PROF_OAK ; $1A
  • trainer_const NOBODY ; $00

Types

https://github.com/pret/pokeyellow/blob/master/constants/type_constants.asm

A new type?! BIRD is defined here, unfortunately it looks like it was eventually dropped during development. Perhaps having PIDGEOT use SKY ATTACK with STAB BIRD would have been overkill.

  • const BIRD ; $06
  • const PSYCHIC_TYPE ; $18

Also, this is the only type name appended with _TYPE, further proving PSYCHIC prowesss in gen 1.

Music

https://github.com/pret/pokeyellow/blob/master/constants/music_constants.asm

Nothing too crazy down in the Music files, however there is an unused song. We will never know ...

  • music_const MUSIC_YELLOW_UNUSED_SONG, Music_YellowUnusedSong

Text

Conversation dialgue between characters in game.

Cinnabar Gyn

https://github.com/pret/pokeyellow/blob/master/text/CinnabarGym.asm

Gym guide:

para "You better take"
line "some BURN HEALs!"

Blaine pre-battle:

para "Hah! You better"
line "have BURN HEAL!"

In case you got burnt by ARCANINE, there was ample warning for burn heals from the gym guide. YO CHAMP!

Shortcut for 'Pokemon'

Throughout the data, the use of #MON and #DEX indicates that the # is mapped to a value of "POKE", producing POKEMON and POKEDEX respectively.

Example: https://github.com/pret/pokeyellow/blob/master/text/ChampionsRoom.asm

para "While working on"
line "#DEX, I looked"
cont "all over for"
cont "powerful #MON!"

Data

A massive amount of data used throughout the game to drive battles, credits, maps, types, encounters and more.

Credits pokemon

https://github.com/pret/pokeyellow/blob/master/data/credits/credits_mons.asm

The list of pokemon shown during the credits sequence.

Move details

https://github.com/pret/pokeyellow/blob/master/data/moves/moves.asm

Every pokemon move listed with power, type, accuracy and effect.

Most powerful moves:

  1. move EXPLOSION, EXPLODE_EFFECT, 170, NORMAL, 100, 5
  2. move HYPER_BEAM, HYPER_BEAM_EFFECT, 150, NORMAL, 90, 5
  3. move SKY_ATTACK, CHARGE_EFFECT, 140, FLYING, 90, 5

As you can see, the less PP a move has, the more powerful that move is. Let's see if that theory holds up.

  1. move FISSURE, OHKO_EFFECT, 1, GROUND, 30, 5
  2. move SELFDESTRUCT, EXPLODE_EFFECT, 130, NORMAL, 100, 5

FISSURE is a OHKO move so, assuming the user is faster than the oppenent, and the move hits, it all checks out!

'Bird' type is real

https://github.com/pret/pokeyellow/blob/master/data/types/names.asm

Surely there is hope for BIRD pokemon?!

dw .Rock
dw .Bird
dw .Bug
dw .Ghost

Bird must have been dropped during development as it's no longer mentioned in type matchups. If there was both Flying and Bird, good luck if you were using a PARAS and hit with DRILL PECK. That would go for 8x damage! Plus STAB!!

Move choice modifications

https://github.com/pret/pokeyellow/blob/master/data/trainers/move_choices.asm

move_choices 1, 2, 3 ; POKEMANIAC
move_choices 1, 2, 3 ; LORELEI

LORELEI and POKEMANIAC are in a class of their own as they contain all 3 move modification methods. It looks like that would apply to all POKEMANIAC trainers.

All trainers parties

https://github.com/pret/pokeyellow/blob/master/data/trainers/parties.asm

Analyse every single trainer's pokemon and their respective levels.

Champion's team

Rival3Data:
; Champion's Room
db $FF, 61, SANDSLASH, 59, ALAKAZAM, 61, EXEGGUTOR, 61, CLOYSTER, 63, NINETALES, 65, JOLTEON, 0
db $FF, 61, SANDSLASH, 59, ALAKAZAM, 61, EXEGGUTOR, 61, MAGNETON, 63, CLOYSTER, 65, FLAREON, 0
db $FF, 61, SANDSLASH, 59, ALAKAZAM, 61, EXEGGUTOR, 61, NINETALES, 63, MAGNETON, 65, VAPOREON, 0

Which champion's team is the most difficult? The weak link is NINETAILS in my eyes, and MAGNETON is bulkier than JOLTEON. This narrows it down to the FLAREON team (although FLAREON lets this team down by using FIRE-SPIN).

Cool trainers are top-tier

If only the unused teams were available, these trainers could put a fight against LORELEI! Tough teams for both trainer types throughout the game.

  • levels in the mid-high 40s
  • final stage evolutions
CooltrainerMData:
; Viridian Gym
	db 39, NIDORINO, NIDOKING, 0
; Victory Road 3F
	db 43, EXEGGUTOR, CLOYSTER, ARCANINE, 0
	db 43, KINGLER, TENTACRUEL, BLASTOISE, 0
; Unused
	db 45, KINGLER, STARMIE, 0
; Victory Road 1F
	db 42, IVYSAUR, WARTORTLE, CHARMELEON, CHARIZARD, 0
; Unused
	db 44, IVYSAUR, WARTORTLE, CHARMELEON, 0
	db 49, NIDOKING, 0
	db 44, KINGLER, CLOYSTER, 0
; Viridian Gym
	db 39, SANDSLASH, DUGTRIO, 0
	db 43, RHYHORN, 0

CooltrainerFData:
; Celadon Gym
	db 24, WEEPINBELL, GLOOM, IVYSAUR, 0
; Victory Road 3F
	db 43, BELLSPROUT, WEEPINBELL, VICTREEBEL, 0
	db 43, PARASECT, DEWGONG, CHANSEY, 0
; Unused
	db 46, VILEPLUME, BUTTERFREE, 0
; Victory Road 1F
	db 44, PERSIAN, NINETALES, 0
; Unused
	db 45, IVYSAUR, VENUSAUR, 0
	db 45, NIDORINA, NIDOQUEEN, 0
	db 43, PERSIAN, NINETALES, RAICHU, 0

Prof Oak Battle

Of course, the proposed final battle that we never got to see in the OG games. Oak has type coverage and a final form starter. Although I see a missing 6th party member which could hurt his chances.

ProfOakData:
; Unused
db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, BLASTOISE, 70, GYARADOS, 0
db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, VENUSAUR, 70, GYARADOS, 0
db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, CHARIZARD, 70, GYARADOS, 0

Most frequent trainer pokemon

To wrap up this analysis, I've always wondered what is the most frequent POKEMON a trainer uses in the game. I'll take a random guess and say it's a POISON type, maybe ZUBAT or GRIMER.

Now to extract the numbers I've:

  1. copied https://github.com/pret/pokeyellow/blob/master/data/trainers/parties.asm to a local file, named trainerData
  2. copied https://github.com/pret/pokeyellow/blob/master/data/pokemon/dex_order.asm to a local file, named pokedexEntries
  3. trainerData contains references to unused pokemon + trainers. To keep the spirit of the OG game, I've removed all unused references manually (painful)
  4. pokedexEntries meanwhile contains db 0 ; MISSINGNO. several times and prefixes to each POKEMON. In order to use this file as a base to match against all trainer pokemon, I need to remove unwanted data. I run grep -v 'db 0 ; MISSINGNO.' pokedexEntries > pokedexEntries-clean to output the same file with lines containing db 0 ; MISSINGNO. removed. I then manually clean up 3 more lines which contain instructions. Following this, I use awk -F 'db DEX_|_' '{print $2}' pokedexEntries-clean > pokedexEntries-final to remove the prefix from each POKEMON entry and have a final POKEMON list
  5. Now, I am ready to loop through each POKEMON entry from pokedexEntries-final and count how many times they appear in trainerData. I've created a bash script for that:
#!/bin/bash
while read line
do  
    frequency=$(cat trainerData | grep -o -w $line | wc -l)
    pokemon=$line
    echo $pokemon,$frequency >> pokemonFrequency.csv
done < pokedexEntries-final
sort -k2 -n -r -t, pokemonFrequency.csv

And with this, I can finally unveil the podium ...

KOFFING, 36 > 1st place!
RATTATA, 27 > tied 2nd place
PIDGEY, 27 > tied 2nd place
MACHOP, 26 > 3rd place
ZUBAT, 20
GRIMER, 20
GEODUDE, 19
HORSEA, 18
GOLDEEN, 18
SPEAROW, 17
GASTLY, 17
VOLTORB, 16
MAGNEMITE, 16
WEEZING, 15
TENTACOOL, 15
MEOWTH, 15
KADABRA, 15
SHELLDER, 14
RATICATE, 14
ODDISH, 14
CATERPIE, 14
SANDSLASH, 13
MACHOKE, 13
BELLSPROUT, 13
SANDSHREW, 12
POLIWAG, 12
ONIX, 12
MAGNETON, 12
FEAROW, 12
EKANS, 12
DROWZEE, 12
VULPIX, 11
NINETALES, 11
CLOYSTER, 11
STARYU, 10
SLOWPOKE, 10
SEAKING, 10
PIDGEOTTO, 10
GROWLITHE, 10
MANKEY, 9
ARBOK, 9
MAGIKARP, 8
CUBONE, 8
WEEDLE, 7
GOLBAT, 7
EEVEE, 7
CLEFAIRY, 7
METAPOD, 6
HYPNO, 6
HAUNTER, 6
ELECTRODE, 6
WEEPINBELL, 5
SEADRA, 5
RHYHORN, 5
PRIMEAPE, 5
PERSIAN, 5
MUK, 5
DODUO, 5
VENONAT, 4
TENTACRUEL, 4
PONYTA, 4
NIDORINO, 4
JIGGLYPUFF, 4
IVYSAUR, 4
GLOOM, 4
EXEGGUTOR, 4
EXEGGCUTE, 4
ALAKAZAM, 4
VAPOREON, 3
SLOWBRO, 3
POLIWHIRL, 3
JOLTEON, 3
GRAVELER, 3
FLAREON, 3
CHARMELEON, 3
CHARMANDER, 3
BULBASAUR, 3
WARTORTLE, 2
TANGELA, 2
STARMIE, 2
RAPIDASH, 2
PARASECT, 2
PARAS, 2
NIDOQUEEN, 2
NIDOKING, 2
LICKITUNG, 2
LAPRAS, 2
KAKUNA, 2
HITMONLEE, 2
HITMONCHAN, 2
GENGAR, 2
FARFETCHD, 2
DUGTRIO, 2
DRAGONAIR, 2
DODRIO, 2
DIGLETT, 2
DEWGONG, 2
BEEDRILL, 2
ARCANINE, 2
WIGGLYTUFF, 1
VICTREEBEL, 1
VENOMOTH, 1
TAUROS, 1
SEEL, 1
RHYDON, 1
RAICHU, 1
NIDORINA, 1
MACHAMP, 1
KINGLER, 1
JYNX, 1
GYARADOS, 1
GOLDUCK, 1
DRAGONITE, 1
CHARIZARD, 1
CHANSEY, 1
BUTTERFREE, 1
BLASTOISE, 1
AERODACTYL, 1
ABRA, 1
ZAPDOS, 0
VILEPLUME, 0
VENUSAUR, 0
SQUIRTLE, 0
SNORLAX, 0
SCYTHER, 0
PSYDUCK, 0
PORYGON, 0
POLIWRATH, 0
PINSIR, 0
PIKACHU, 0
PIDGEOT, 0
OMASTAR, 0
OMANYTE, 0
NIDORAN, 0
NIDORAN, 0
MR, 0
MOLTRES, 0
MEWTWO, 0
MEW, 0
MAROWAK, 0
MAGMAR, 0
KRABBY, 0
KANGASKHAN, 0
KABUTOPS, 0
KABUTO, 0
GOLEM, 0
ELECTABUZZ, 0
DRATINI, 0
DITTO, 0
CLEFABLE, 0
ARTICUNO, 0

Dang, not too bad for a guess with both ZUBAT and GRIMER in the top 10. There we have it. KOFFING is the most used Pokemon (by trainer) in Yellow. A few points worth mentioning:

  • whilst there is 1 each of CHARIZARD and BLASTOISE used by trainers, there is no trainer who uses a VENASAUR. Maybe this is why PROF OAK was removed, that VENASAUR was just too powerful
  • Legendaries are not used by any trainers, yet the likes of KRABBY, DRATINI and CLEFABLE are just as rare!
  • RHYDON, the very first POKEMON ever designed is used only once in the game by GIOVANNI, further cementing its historic legacy

That's it for today folks. I enjoyed brushing up on awk, bash and learning more assembly. Useful guides I found are:

In future, I'll look to create an improved bash script that can be used across all pokemon games to easily extract interesting data.

For anyone interested, the team at pret also have made guides for patchers and modders to modify game data. If you wanted to make every wild encounter a level 100 MEWTWO, this is the place for you.