The current URL is datacrystal.tcrf.net.
Pokémon 3rd Generation
This is a work in progress by Kawa. I'm keeping it all on this page for later splitting and standardizing if that's okay with you guys.
The third generation Pokémon games comprise Pokémon Ruby, Sapphire, Emerald, Fire Red and Leaf Green. Since all five share a common set of data structures with only some offsets and minor details in difference, it seems more effective to consider them one single "game" and note the differences where applicable.
Interesting locations in ROM
Name | Fire Red | Ruby | Notes |
---|---|---|---|
Pokémon images | 0x2350AC | 0x1E8354 | Pointer tables in system order |
Monster heights | 0x235E6C | ??? | |
Pokémon images from the back | 0x23654C | 0x1E97F4 | Pointer tables in system order |
Pokémon image palettes | 0x23730C | 0x1EA5b4 | |
Pokémon alternate colors | 0x2380CC | 0x1EB374 | |
Trainer images | 0x23957C | 0x1EC53C | Pointer tables |
Trainer palettes | 0x239A1C | 0x1EC7D4 | |
Trainer class names | 0x23E558 | 0x1F0208 | |
Trainer data | 0x23EAF1 | 0x1F0525 | Trainer structure at the OpenPoké wiki |
Pokémon species names | 0x245EE0 | 0x1F7184 | Listed in system order |
Move names | 0x247094 | 0x1F8320 | |
Ability names | 0x24FC4D | 0x1FA26D | |
Move data | 0x250C04 | 0x1FB12C | Same order as their names |
TM allowance sets | 0x252BC8 | 0x1FD0F0 | |
Pokémon base stats | 0x254784 | 0x1FEC30 | Listed in system order |
Move sets | 0x257496 | 0x20192A | |
Evolution chains | 0x25977C | 0x203B90 | |
Party icons | 0x3D37A0 | 0x3BBD20 | Pointer table again, in system order |
Party icon palette | 0x3D3740 | 0xE966D8 | |
Party icon palette LUT | 0x3D3E80 | 0x3BC400 | Simple byte array |
Item data | 0x3DB028 | 0x3C5580 | Item structure at the OpenPoké wiki |
TM table | 0x45A5A4 | 0x376504 | Maps TM numbers to moves |
Pokédex data | 0x44E850 | 0x3B1874 | Confusingly, this is in national dex order. Pokédex entry structure at the OpenPoké wiki |
Footprints | 0x43FAB0 | 0x3B4EE4 | Pointer table |
Contest data | N/A | 0x3C9408 | |
Cries | 0x48C914 | 0x452590 | M4A Voice Group-style pointer list. In system order? |
Following the Pokémon image pointers, you may notice that each species has all its image data in one chunk.
More information on the data structures can be found at Bulbapedia: Category:Structures
Images
Trainer and monster images are LZ77-compressed 64 by 64 pixels, 16 colors. Trainers' back-facing images are much taller and (in Fire Red/Leaf Green) uncompressed. Monster front images in Emerald are 128 pixels tall to allow animation. In all games, certain monsters always have nonstandard heights (ie. Castform). Alternate colors (aka Shiny) are usually represented by the back-facing images since it makes an intuitive kind of sense.
Text
A full lookup table can be found at the OpenPoké wiki: Pokémon Character Set. That page does not include Thingy tables, but they can be produced.
Maps
Maps are split among banks, each bank roughly being one location. For example, there's a bank with all the cities and routes and several banks with each city's interiors. Generally, a map can be defined by a Doom-like "bank X, map Y" scheme. In Pokémon Fire Red, the bank pointer list is at 0x3526A8. Following one of the pointers found there yields that bank's map pointer list, which can be followed to a given map's header.Here's the map header format, including example data from Pallet Town (B3M0, 0x350618):
Data type | Description | Example |
---|---|---|
Pointer | Map data | 0x082DD4C0 |
Pointer | Event data | 0x083B4E50 |
Pointer | Map scripts | 0x0816545A |
Pointer | Connections | 0x0835276C |
Short | Music index | 0x012C (Pallet Town) |
Short | Map pointer index? | 0x004E |
Byte | Label index | 0x58 ("Pallet Town") |
Byte | Something with Flash? | 0x00 |
Byte | Weather | 0x02 |
Byte | Type | 0x01 |
Short | ??? | 0x0601 |
Byte | Show label on entry | 0 |
Byte | Battle type? | 0 |
Kawa is not sure why there is both a pointer and an index to the same data (the map). Further studies will show.
The map layout data is another header:
Data type | Description | Example |
---|---|---|
Long | Width in tiles | 24 |
Long | Height in tiles | 20 |
Pointer | Border | 0x082DD0F8 |
Pointer | Actual map data | 0x082D1D00 |
Pointer | Global tileset | 0x082D4A94 (outside) |
Pointer | Local tileset | 0x082D4AAC |
Byte | Border width | 2 |
Byte | Border height | 2 |
Border size is only in FireRed/LeafGreen. In R/S/E it is missing and borders are always 2x2 squares.
Map data is quite straightforward: each 16-bit entry encodes the tile number and attribute. The trick is that there are only 64 attributes and 512 tiles, so the 16-bit entry is split up 7:9 instead of 8:8. The border data is technically the same format, but does not use attributes[check this].
Important Notice: The above statement is not accurate, at least not for Ruby. Tiles and attributes are broken up 6:10, not 7:9. For example, a map tile in Advance Map that shows as "block 1D4" with a movement permission of "01" will be represented in a hex editor as "D405", which is "1101 0100 0000 0101" in binary. To extract the tile you take the last 2 bits "01" and prepend that to the first 8 bits. This gives you "01 1101 0100", which is "1D4". Bits 9-14 are "000001" which gives a hex value of "1". - Joncom
Kawa is now left to ponder what to add next.