Analyzing Pokemon Yellow - disassembled!
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:
move EXPLOSION, EXPLODE_EFFECT, 170, NORMAL, 100, 5
move HYPER_BEAM, HYPER_BEAM_EFFECT, 150, NORMAL, 90, 5
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.
move FISSURE, OHKO_EFFECT, 1, GROUND, 30, 5
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:
- copied https://github.com/pret/pokeyellow/blob/master/data/trainers/parties.asm to a local file, named
trainerData
- copied https://github.com/pret/pokeyellow/blob/master/data/pokemon/dex_order.asm to a local file, named
pokedexEntries
trainerData
contains references tounused
pokemon + trainers. To keep the spirit of the OG game, I've removed allunused
references manually (painful)pokedexEntries
meanwhile containsdb 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 rungrep -v 'db 0 ; MISSINGNO.' pokedexEntries > pokedexEntries-clean
to output the same file with lines containingdb 0 ; MISSINGNO.
removed. I then manually clean up 3 more lines which contain instructions. Following this, I useawk -F 'db DEX_|_' '{print $2}' pokedexEntries-clean > pokedexEntries-final
to remove the prefix from each POKEMON entry and have a final POKEMON list- Now, I am ready to loop through each POKEMON entry from
pokedexEntries-final
and count how many times they appear intrainerData
. 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:
- https://www.digitalocean.com/community/tutorials/awk-command-linux-unix
- https://www.baeldung.com/linux/awk-count-matches
- https://www.geeksforgeeks.org/sort-command-linuxunix-examples/
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.