Pokémon Palettes in Generation II
Go back to the main page This is an explanation on how palettes work in the Pokémon games of Generation II, Gold, Silver and Crystal. I am assuming some prior experience with a hex editor, and 24-bit color codes. Look up how to use them if you haven't before. I am also assuming basic Pokémon knowledge (e.g. what a shiny is).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 Pokémon palettes are stored one after another at a set offset. What the offset is depends on the ROM, but it is 0xAD3D in English Gold/Silver, and 0xA8CE in English Crystal. The palettes are ordered according to Pokédex number (or internal id number, but it's the same in Gen II), with the shiny palettes in between the normal ones. There is also a placeholder glitch mon called ????? at index 0, so it goes:
?????, s-?????, bulbasaur, s-bulbasaur, ivysaur, s-ivysaur, venusaur, s-venusaur, charmander, s-charmander, etc. etc.
The palettes are each two colors long, while the sprites use four colors, two of them are always black and white, so they don't need to be encoded for every Pokémon. The colors are 15-bit colors, written in little endian, so they take 2 bytes each. This means each Pokémon palette is 4 bytes long. You can use this to find the offset of a specific Pokémon's palette by adding (4*2*n) to the original offset, where n is the Pokédex number of said mon (in hexadecimal), or add 4 to that to get its shiny palette.To visualize, this here are the first few palettes as they would look in a hex editor:
DE 46 D0 4D DE 46 D0 4D EC 2F 5F 19 94 2F 5F 19 EC 2F 9F 45 94 2F 1F 27
Or if we order them up and add some comments:
DE 46 D0 4D ?????
DE 46 D0 4D s-?????
EC 2F 5F 19 bulbasaur
94 2F 5F 19 s-bulbasaur
EC 2F 9F 45 ivysaur
94 2F 1F 27 s-ivysaur
However, if you were to input #60F858, you would get 2FEC, not EC2F. This is because Pokémon games use little endian, so lower bytes come first in the code. The only thing you have to do is swap the bytes around (so you'd get EC2F). Don't forget to!
Now, let's do a concrete example. Here is AAAB, my Chikorita (on an emulator).
I want to change his (and every other Chikorita's) colors to these bleak emo ones I've done in a painting program:
First, I calculate the offset of Chikorita's palettes. This is a Gold rom, so the general Pokémon palette offset is 0xAD3D. Chikorita's Pokédex number is 152, or 98 in hexadecimal. AD3D + 4*2*98 = B1FD, so Chikorita's palette offset is at 0xB1FD.
We go there with out hex editor, and see Chikorita's palettes.
Now, AAAB is not a shiny Chikorita, so we are only interested in the first four bytes;
FD 32 83 02
Going back to our painting program, we see that Chikorita's first color (its body's) is #777169. We insert this at http://www.budmelvin.com/dev/15bitconverter.html and get 35CE. We flip these bytes, and replace FD 32 with them, so we getCE 35 83 02
We load up our rom again in the emulator, and if using a save state we leave AAAB's status screen and re-enter it - palettes are only reloaded when you change screens.Success!
We repeat the last steps above with the color of the leaves, #4C3E2C, converting it to 14E9, flipping the bytes, and replace 83 02. Our final bytes for Chikorita's changed palette are:
CE 35 E9 14
and loading it up again AAAB looks like this:This change also carries over to the backsprite and the Pokédex, with no need to do anything more. We are done.
Originally written by Voliol 12022-02-19, HE, last updated 12023-04-04. .