Pokémon Palettes in Generation I

Go back to the main page

This is an explanation on how palettes work in the Pokémon games of Generation I, Red, Blue, Green (and Japanese Red) and Yellow. I'm assuming some prior knowledge of computer-related terms such as "byte", "hexadecimal", and "offset".
This article is primarily for the sake of curiosity, not for practical use by ROM hackers. Unless you are working on some weird legacy project, there should be no reason to not use the disassemblies.

The Super Game Boy, and the available colors

In the Generation I games, all Pokémon are generally colored the same - due to the Game Boy being monochrome. The exception is when these games are played using a Super Game Boy, or when Pokémon Yellow is played on a Game Boy Color. Then, each Pokémon is assigned a simple 4-color palette, replacing the shades of gray or green. In practice, each of these palettes only contain 2 unique colors, as the other 2 are always white and black. They also tend to be monochrome - if the bright color is bright pink, then the darker color will be darker pink, though this is not a technical restriction.
The games use 37 palettes in total for the Super Game Boy (40 in Yellow), 10 of which are reserved for Pokémon*. They are as follow in the table below. Names are taken from the Pokémon Red disassembly and are thus descriptive but not official, and the "palette ID" (number of the palette) is represented in both hexadecimal and decimal. The exact colors differ between Red/Blue/Green (on a Super Game Boy), Yellow on a Super Game Boy, and Yellow on a Game Boy Color** so there is three example images given for each palette.

*Mostly reserved. The palettes "meant" for Pokémon are also used in a few other places, like the "Mew" palette being used for most of the trainer card screen.
**I base this on the pokeyellow decompilation listing two alternate sets of definitions for the palettes, and emulation using mGBA; I do not have the hardware to test it out "for real".

Name Palette ID (hex / dec) Pokémon using palette Example R/B/G Example Yellow (SGB) Example Yellow (GBC)
Mew 0x10 / 16 MissingNo., Jynx, Mewtwo, Mew
Blue 0x11 / 17 Nidoran♀, Nidorina, Nidoqueen, Zubat, Golbat, Poliwag, Poliwhirl, Poliwrath, Seel, Dewgong, Tangela, Gyarados, Omanyte, Omastar, Articuno, Dragonair
Red 0x12 / 18 Charmander, Charmeleon, Charizard, Vulpix, Gloom, Vileplume, Paras, Parasect, Arcanine, Ponyta, Rapidash, Krabby, Kingler, Goldeen, Seaking, Staryu, Magmar, Magikarp, Flareon, Moltres
Cyan 0x13 / 19 Squirtle, Wartortle, Blastoise, Butterfree, Golduck, Tentacool, Tentacruel, Horsea, Seadra, Lapras, Vaporeon
Purple 0x14 / 20 Ekans, Arbok, Nidoran♂, Nidorino, Nidoking, Venonat, Venomoth, Grimer, Muk, Gastly, Haunter, Gengar, Koffing, Wheezing
Brown 0x15 / 21 Pidgey, Pidgeotto, Pidgeot, Spearow, Fearow, Sandshrew, Sandslash, Diglett, Dugtrio, Mankey, Primeape, Growlithe, Farfetch'd, Doduo, Dodrio, Hitmonlee, Hitmonchan, Kangaskhan, Pinsir, Kabuto, Kabutops, Dragonite
Green 0x16 / 22 Bulbasaur, Ivysaur, Venusaur, Caterpie, Metapod, Oddish, Bellsprout, Weepinbell, Victreebel, Exeggutor, Scyther
Pink 0x17 / 23 Clefairy, Clefable, Jigglypuff, Wigglytuff, Slowpoke, Slowbro, Exeggcute, Lickitung, Chansey, Mr. Mime, Snorlax
Yellow 0x18 / 24 Weedle, Kakuna, Beedrill, Pikachu, Raichu, Ninetales, Meowth, Persian, Psyduck, Abra, Kadabra, Alakazam, Drowzee, Hypno, Voltorb, Electrode, Electabuzz, Jolteon, Zapdos
Gray 0x19 / 25 Rattata, Raticate, Machop, Machoke, Machamp, Geodude, Graveler, Golem, Magnemite, Magneton, Shellder, Cloyster, Onix, Cubone, Marowak, Rhyhorn, Rhydon, Starmie, Tauros, Ditto, Eevee, Porygon, Aerodactyl, Dratini

Pokémon palette table

Above, we showed what Pokémon use what palettes. This is done by means of a table, with a byte for the palette ID of each Pokémon. The table is ordered according to Pokédex order, with the addition of MissingNo. at index 0, and is thus 152 entries/bytes long. What its offset is depends on the ROM, but it is 0x725C8 in English Red/Blue, and 0x72921 in English Yellow. The table in full is shown below:

10 16 16 16 12 12 12 13 13 13 16 16 13 18 18 18
15 15 15 19 19 15 15 14 14 18 18 15 15 11 11 11
14 14 14 17 17 12 18 17 17 11 11 16 12 12 12 12
14 14 15 15 18 18 18 13 15 15 15 12 11 11 11 18
18 18 19 19 19 16 16 16 13 13 19 19 19 12 12 17
17 19 19 15 15 15 11 11 14 14 19 19 14 14 14 19
18 18 12 12 18 18 17 16 19 19 15 15 17 14 14 19
19 17 11 15 13 13 12 12 12 19 17 16 10 18 12 15
19 12 11 13 19 19 13 18 12 19 11 11 15 15 19 17
11 18 12 19 11 15 10 10

Note it starts with "10" for the "Mew" palette that MissingNo. uses, and then has three green "16"s in a row - the Bulbasaur family. Should we want to change the palette of any Pokémon, all we have to do is change its number in the table. We actually aren't restricted to the palettes named above, even if those are the only ones used by default. E.g. if we wanted to change a Pokémon to use the Indigo League overworld palette, that would be as easy as changing its number to "0A" (the numbers for all Super Game Boy palettes can be found here).

Palette definitions

So how are the actual palettes stored/defined?
Each palette is 4 colors long. The colors are 15-bit colors, written in little endian, so they take 2 bytes each. This means each palette is 8 bytes long.
Each palette contain a "white" color at index 0, and a "black" color at index 3 (these are actually slightly off-white, and off-black, but that doesn't matter). However, only the two middle colors can be changed for the corresponding effect with no side effects. Changing the "white" color of a palette does nothing to the Pokémon sprites that use it, while changing the last "black" color will also lead to miscolorations of other tiles.
Example of miscoloration, caused by changing the "Mew" palette:
A Mew, and surrounding GUI with miscolored lines
The Palettes used by Pokémon are grouped with the other Super Game Boy palettes. The offset of where these palettes start depends on the ROM, but it is 0x72660 English Red and English Blue. English Yellow has, like other versions of Yellow (but not the Japanese one), two sets of palette data. One set is for the Super Game Boy, and the other contains palettes for the Game Boy Color. These start at 0x72A39 and 0x72B79 respectively, directly following another.
The order is the one that can be found here, where Pokémon palettes are at positions 16-26 (0x10-0x19 in hexadecimal).

Now, let's do a concrete example. Here is AAA, by Zubat (on an emulator).
A blue Zubat
I want it to be purple, for whatever reason. The ROM I'm using is the English version of Red, and Zubat has the Pokédex number 41 = 0x29, so the palette ID for Zubat is at 0x725C8 + 0x29 = 0x725F1. I go there using a hex editor, and yup, the byte at that position is 0x11, which I identify as the ID for the "Blue" palette used by Zubat. The ID for the "Purple" palette is 0x14, so I change it to that.
A hex editor, the byte "14" at position 0x725F1 in red.
Does this work?
A purple Zubat
It works! (note: upon resetting the emulator, and reloading the screen if save states are used)

Now, I'm still not satisfied with this purple color. I think it could be purpler, magenta even! Something like this:
A magenta Zubat, not in-game
To do that, I calculate the offset of the Purple palette. Again, this is English Red, so the base offset is 0x72660. 0x72660 + (0x14*8) = 0x72700. Going there I see:

BF 7F DB 62 F5 5D 43 08

For aforementioned reasons, we only care about the middle four bytes (the middle two colors):

DB 62 F5 5D

Going to the paint program where the mockup of the magenta Zubat was created, I can select the bright magenta color and see it is #FF00FF. This is a 24-bit color code, so before we can insert it must be converted. Luckily this site can do that: http://www.budmelvin.com/dev/15bitconverter.html
I pop in #00FFFF and get 7C1F. The color bytes should be written in little endian, so I swap their order before replacing DB 62, giving:

1F 7C F5 5D

I then do the same to the darker magenta color. #930093 => 4812 => 1248, replacing the second color, F5 5D. We finally have:

1F 7C 12 48

Upon resetting the emulator to see if this works, the side effect of this change becomes apparent before we even load up the game. The Nidorino and Gengar in the start animation are also magenta!
A magenta Zubat, not in-game
This is naturally because we've changed how all purple Pokémon look, not just Zubat. Of course, AAA, and all other Zubats are properly magenta now. This change also carries over to the backsprite and the Pokédex, with no need to do anything more. We are done.
A magenta Zubat The backsprite of a magenta Zubat shown in a battle A magenta Zubat in the Pokédex

Originally written by Voliol 12022-10-29, HE.