Talk:Pokémon data substructures (Generation III)

From Bulbapedia, the community-driven Pokémon encyclopedia.
Jump to navigationJump to search

The "Order" section must be wrong. When I calculed Personality 3935877326(in decimal) by 24(decimal too) I got "14" - which correspond to order EAGM - but something was wrong. After 4 hours intense counting and trying I realized the ordering was wrong. The correct ordering was GEAM . Game version: Ruby (US version) Pokemon: First in party Myself: ICQ: 343370964 . btw: Now I am stuck at recalculating data checksum. If somebody know... please...

I have solved your problem. 3935877326 turns to 0xEA98B8CE in hexadecimal. You have to use little endian, to which the rule applies, least significant byte first. In other words, the very last byte will end up being first. Rearranged as follows
0x1234ABCD -> little endian -> CDAB3412. So your number should be 0xCEB898EA, or 3468204266 in decimal. 3468204266 MOD 24 = 2, which is GEAM. Nice? Twigpi 20:51, 29 October 2007 (UTC)
Also, the checksum loops. Adding the unencrypted values should give you a value greater then 0xFFFF (max size), so it just loops. To find the correct value, MOD by 65536 (decimal) or 0x10000. Twigpi 20:51, 29 October 2007 (UTC)

Substruct encryption

If you play in an emulator like No$GBA or VBA, you can open a RAM viewer. Sometimes, if you look at a Pokémon data structure, you can see the encrypted substructs change values in a flash. This is because the game decrypts the whole thing for use and encrypts them again immediately afterwards. I always did wonder how it was supposed to use the data if it's encrypted... --Kyoufu Kawa 16:52, 31 July 2007 (UTC)


Investigation of Fire Red assembly code reveals that the DVs field is not exactly as described. More to follow. --Kyoufu Kawa 20:06, 10 August 2007 (UTC)

As stated in my previous edit, the last two DV bits are actually used. One of them is the egg flag, as opposed to the ribbons, which was an endian error on my part.

Little Endian

Using little endian. This means for every word (two bytes), you reverse the order of the bytes. The encryption and decryption will work as long as you keep the order the same for the key and the data. Twigpi 14:01, 29 October 2007 (UTC)


It's not a signed value that has the sign bit ignored. Some non-ASM research tells me that the eight bit is actually part of another value -- the monster's origin game. Wether to read it from the GBA or the Gamecode list depends on this value. Technically speaking:

0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
Level met Original game Pokeball Trainer gender

Or, in C speak:

u32 Level:7
u32 OriginGame:4;
u32 Pokeball:4;
u32 TrainerGender:1;

--Kyoufu Kawa 10:41, 17 August 2008 (UTC)

Species Oddities

Is the species perhaps set somewhere else as well as in the Growth section? I've been looking at my entire lot of boxed pokemon on FireRed/Emerald (which can be seen here) but some have all zeros in their species. It can't be a misread though as it's the decrypted data that shows zeros.

Anyone able to shed any light on this? PuppyBoy 10:03, 3 October 2008 (UTC)

As far as I can tell, no -- the species is stored in only two out of (in your case) 80 bytes. Very interesting. Perhaps you (the person) simply misread the data itself? I prefer to display this kind of stuff parsed. --Kyoufu Kawa 19:06, 3 October 2008 (UTC)
Nevermind, I double checked the pokemon on the actual game - the pokemon where their species was set to zero weren't actually in the boxes. It looks like it doesn't actually delete the pokemon from the box in some cases, just sets the species to zero? I don't know, I guess I'll know to expect it in the future though. PuppyBoy 02:20, 5 October 2008 (UTC)
I should do some research into that. I remember empty slots being zero'd out in the party, except for some 0xFF bytes. I'll call you back on this page with my test results for party and box. --Kyoufu Kawa 14:05, 5 October 2008 (UTC)

Research results

An empty slot in the party is all zeroes, except for the field marked "????" in the Pokémon structure which is, as far as I can tell, always 0xFF. Clearing a Pokémon in the middle of your party makes the rest unselectable, although they're still drawn in the party screen. The important factor is the monster's species -- ?????? (#0) is considered an empty slot. ? (#252-276) are not, but crash the game regardless. The exact same rules apply for boxes, but in only 80 bytes. Also, because the box manager has a cursor that can hover empty slots but the party screen has not, adding a party member while in the party screen makes the new one unselectable until the screen redraws. The game caches the party size, which is reset when the party screen is drawn, so the new one will be unselectable in the status screen too. Stupidly, when you remove a party member (by setting the species to zero), it remains selectable until redraw and will crash the game. Note that this research is done using my insight hack, but all that means is that I don't get Bad EGGs all over the screen. So, to reiterate:

  • Slots are considered taken if the species is non-zero.
  • Party size is cached and recounted when opening the party screen, likely also when recieving a new monster the proper ways.
  • Party screen drawing ignores the cached size and just draws all six slots.
  • Even so, you can't move the cursor beyond the cached size.
  • #252-276 are non-zero so they count as party members - but they'll still crash your game.
  • Incidentally, so does #412, which only serves to store the EGG image.

This research was brought to you by --Kyoufu Kawa 18:17, 6 October 2008 (UTC)

Playing with Subdata Decryption

I've been working for a couple of days in a C++ tool that builds a report of the active party. So far thanks to the available articles regarding data and subdata structures, everything has been easy. I can build a human-readable output containing most of the information of a Pokémon (I've actually published a quick enquiry looking for interest towards such a tool, but so far no response). There are, however, some minor problems where I can not obtain the correct information. In particular, when decrypting the subdata structures, for any Pokémon whose subdata order index is 10 or 11, 16 or 17, the reported subdata order seems to be wrong. Can anyone confirm me that the permutations currently appearing in the table are all correct? -- --Solovino 03:02, 14 August 2009 (UTC)


I started looking into the ribbons and i think there is a mistake with the bit assignments. The "Smart" and "Tough" bits are the only ones consisting of 4 bits each, and the last bit used for the "Smart"-Ribbon is also the first bit used for the "Tough"-Ribbon. I don't think that is correct. I also tried it with the arrangement showed here and i get for instance the value "8" for the "tough" ribbon, so something must be off. If there is a bit off, i think the right arrangement would be:

Bits Ribbon
0-2 Cool
3-5 Beauty
6-8 Cute
9-11 Smart
12-14 Tough
15 Champion
16 Winning
17 Victory
18 Artist
19 Effort
20 Special 1
21 Special 2
22 Special 3
23 Special 4
24 Special 5
26 Special 6

Please correct me if i'm wrong :) -- Deviler (talk) 16:49, 30 May 2014 (UTC)

You're likely right. The source I used to make that table says the Contest Ribbons all take 3 bits; I probably just got confused and didn't do the start/end addition/editing correctly. Thanks for catching it and pointing it out. ^_^ Tiddlywinks (talk) 17:13, 30 May 2014 (UTC)


There needs to be more specific information on how the checksum is calculated. The page says "To validate the checksum given in the encapsulating Pokémon data structure, the entirety of the four unencrypted data substructures must be summed into a 16-bit value." Is the whole structure added together 16 bits at a time to produce the checksum, or is every field of all four structures added together (like Species + Item held + Experience + ... and so on), or something different? And if the result is greater than 65535 (largest value for a 16-bit number), does it wrap around and continue from 0 when the result exceeds 65535? Saxorus (talk) 02:57, 24 August 2014 (UTC)