|♪ ♪ ♪
|This user can sing.
||☆ This user's favorite Pokémon is Pikachu. ☆
||This user spends too much time on the computer.
|This user is a hacker.|
Hi. I'm Kawa and I'm an experienced rom hacker and learning GBA homebrewer. For one of my projects, I have to know with 100% certainty what the structures are on the Advanced gen. Pokémon games so you'll see me editing those pages every once in a while when disassembly progress reveals new data.
So I recently found out how the game handles the encrypted data. It doesn't. When the substructures are needed, they're decrypted, read/written and re-crypted. All because I saw something flash by in the memory viewer that looked like raw data.
And here's another fun thing to try: if you want to manipulate your opponent's Pokémon, including a wild encounter, try browsing to your party data (see Pokémon data structure in the GBA) and scroll up about 600 bytes. You see correctly.
Font and Sanity
The font byte in the Pokémon data structure can be 0, 1 or 2. 0 and 2 are both Western. 1 is the Japanese font. Also notice that the variable-width font engine can fit all ten characters in a six tile space, but the Japanese font does not. For this reason, the game automatically cuts off at the sixth character if the font is set to Japanese.
The sanity byte determines if the individual is an egg. Zero and 2 are a regular monster, 1, 3-5 are Bad EGGs but can be changed back, 6 makes the game write "EGG" instead of the monster's nickname but doesn't actually make it an egg and 7 is the actual Bad EGG. When you break the checksum, the sanity byte is set to 7. This persists! Several actions in the game (see below) make it check for Bad EGGs and keep resetting the byte to 7, for example stepping into tall grass and opening the party screen. Good luck turning the Bad EGG back into a real monster. Note that only the first few bits matter so the pattern repeats after 7.
In the DV field, there are two bits left over. One of these determines if a given Pokémon is an Egg. Combine this with the sanity byte set to 6 to make it write EGG instead of whatever the Pokémon's nickname is.
Every time a given property of a Pokémon is read or written, this is done with four specific routines. Two of these are called by the other two if the requested property is in the substructure block. These routines are also responsible for checking if the Pokémon's checksum is correct and set a bunch of values to turn it into a Bad EGG otherwise, but only if it's a substructure property.
Time to Hatch
Silly me, I should've remembered the part where the number of steps is multiplied by 256. Turns out happiness is the number of steps required -- divided by 256! Having made a savestate one step before the happiness value decreases, I'll now try to find the step counter. Having an insight hack really helps tracking those monster properties ^^
Yeah! I found the step counter! Apparently, the hatch steps and poison steps are two seperate values, right next to each other. I'd post the offset, but in an unhacked game it moves around all the time.
More research coming... whenever.
The character sets used in the Pokémon games need a good name. "The Pokémon character sets" just won't do. One user referred to it as "PokéSCII" once, which doesn't even make sense when you expand it: "Pokémon Standard Code for Information Interchange". If it were standard, it wouldn't be different for each generation! Therefore, I came up with a better idea: PCS.
The first three letters are for "Pokémon Character Set". These are followed by the generation number, a dash and a region code. For example, "PCS3-J" would be the character set used in the Japanese GBA games, while "PCS3-W" would be the Western version. Why "western"? Because the differences between localizations are neglible. In the (yecch) French version for example, "Lv." is "Nv." and the “” are «». If the differences are too notable, just use more appropriate region codes.
If the language or generation is obvious from context, just "PCS" will suffice.