Part 4: Time for an Upgrade

Every generation has a different internal structure for storing Pokémon. This chart shows how this data is stored in each of the first three generations. While most of this data can easily be converted between generations by directly copying the data from Generations 1 and 2 to the correct location in Generation 3, there’s a handful of new things that have to be created. Generation 3 also added a new section known as “data”, which stores much of the Pokémon’s specific data such as held item, moves, EVs, IVs, and power points.

The three major additions to the Pokémon data structure in Generation 3 were:

  • A 32-bit "Personality Value" that is used to determine various random aspects of each Pokémon.

  • A 48-byte section of the Pokémon's data that is encrypted.

  • A 4-byte checksum for the 48-byte section of data.

Personality Value

In Generation 3, the 32-bit personality value determines the following random aspects of a Pokémon:

  • Gender

  • Ability

  • Nature

  • Shininess

  • Unown's Letter

  • Size

  • Wurmple's Evolution

  • Spinda's Spots

Of these items, we only need to pay attention to three of them when generating a Personality Value: Gender, Nature, and Unown's Letter. Wurmple and Spinda can't be transferred, Size is not in generation 1 or 2, Shininess can be set based on a different value (the Secret ID), and the Ability should be set at random. Unown has no gender so that simplifies things further, as we will only ever need to get a Personality Value based on two items at a time.

 
The Gender is determined by the lowest eight binary digits of the Personality Value: 

10100011 01000110 11010110 00011101 

0011101 = 29

This byte is then compared to the Pokémon's Gender Ratio to determine the Gender
 

The Nature is determined by taking the Modulus of the entire Personality Value:

10100011 01000110 11010110 00011101 = 2,739,328,541

2,739,328,541 % 25 = 16

This byte directly correlates to one of the 25 different Natures a Pokémon can have

 

Unown's Letter is determined by the modulus of the composite value of the least significant 2 bits of each byte in the Personality Value:

10100011 01000110 11010110 00011101

11101001 = 223

223 % 28 = 9

This byte directly correlates to one of the 28 characters Unown can be

 

With this knowledge, we can calculate a Personality Value that is random, yet gives us the correct values that we need:

This gives us our Personality Value! Interestingly, this is completely different from how it is implemented in the actual games. In the games, the function just keeps rolling until it finds a value that satisfies the Letter, Nature, and Gender. This is a non-optimal way of implementing it, as theoretically, it could go on forever. In practice though, it works just fine.

Encrypted Data and Checksum

Unlike Generations 1 and 2, Generation 3 stores most of each Pokémon's data in an encrypted format and within multiple substructures. Each of these substructures is 12 bytes long and is shuffled around based on the Personality Value. These substructures can be seen here:

In order to keep things simple, I split each substructure into its own array. This allows me to set the data, no matter where it needs to end up. After importing the data from Generations 1 or 2, the checksum is calculated by adding together all 48-bytes of data in groups of 4 bytes. This value is saved in a different section of the Pokémon data structure. The data is then all encrypted by XORing every four bytes with the Trainer ID and the Personality Value. Finally, the arrays are shuffled around according to the Personality Value.

This gives us our completely converted Pokémon, ready to be injected into Generation 3. All of the data conversions were designed to be as close to how GameFreak implemented the Virtual Console re-release conversions. A list of all of the modifications can be found on the project’s GitHub page, here.

Rocky the Onix, one of the first Pokémon successfully transferred.

At this point, I had successfully done what I had set out to do- transfer Pokémon from Generations 1 and 2 to Generation 3. But currently, my program was a black screen with yellow debug text. Hardly professional looking or user friendly. My goal was to make this feel like an official piece of Pokémon software, surely something had to be done.

What my program looked like at this point.

It was time for the engineer to jump into the world of art. What could possibly go wrong?

Previous
Previous

Part 3: A Link Between Worlds

Next
Next

Part 5: A Quick Break for Creativity