Pokémon data structure (Generation IV): Difference between revisions

From Bulbapedia, the community-driven Pokémon encyclopedia.
Jump to navigationJump to search
(Fixed error in encryption algorithm; denoted decimal versus hexadecimal numbers.)
(Prettified unencrypted block contents.)
Line 108: Line 108:


== Unencrypted bytes ==
== Unencrypted bytes ==
* 0x00-0x03 [[Personality value]]
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
* 0x04-0x05 ''Unknown''
|- style="background: #ccc;" align="center"
* 0x06-0x07 [[Checksum]]
! Offset
! Contents
|- style="background: #eee;" align="center"
| 0x00-0x03
| [[Personality value]]
|- style="background: #ddd;" align="center"
| 0x04-0x05
| ''Unknown''
|- style="background: #eee;" align="center"
| 0x06-0x07
| Checksum
|}


=== Block A ===
=== Block A ===
* 0x08-0x09 Species ID
 
* 0x0A-0x0B Held Item
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
* 0x0C-0x0D OT ID
|- style="background: #ccc;" align="center"
* 0x0E-0x0F OT Secret ID
! Offset
* 0x10-0x13 [[Experience|Experience points]]
! Contents
* 0x14 Friendship/Egg Steps to Hatch
|- style="background: #eee;" align="center"
* 0x15 [[Ability]]
| 0x08-0x09  
* 0x16 Markings
| Species ID
* 0x17 Country of Origin
|- style="background: #ddd;" align="center"
* 0x18-0x1D [[Effort values]]
| 0x0A-0x0B  
* 0x1E-0x23 Contest stats
| Held Item
* 0x24-0x27 Ribbons
|- style="background: #eee;" align="center"
| 0x0C-0x0D
| OT ID
|- style="background: #ddd;" align="center"
| 0x0E-0x0F  
| OT Secret ID
|- style="background: #ddd;" align="center"
| 0x10-0x13
| [[Experience|Experience points]]
|- style="background: #eee;" align="center"
| 0x14
| Friendship/Egg Steps to Hatch
|- style="background: #ddd;" align="center"
| 0x15
| [[Ability]]
|- style="background: #eee;" align="center"
| 0x16
| Markings
|- style="background: #ddd;" align="center"
| 0x17
| Country of Origin
|- style="background: #eee;" align="center"
| 0x18-0x1D
| [[Effort values]]
|- style="background: #ddd;" align="center"
| 0x1E-0x23
| Contest stats
|- style="background: #eee;" align="center"
| 0x24-0x27
| Ribbons
|}


=== Block B ===
=== Block B ===
* 0x28-0x2F Moveset
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
* 0x30-0x33 Move PP
|- style="background: #ccc;" align="center"
* 0x34-0x37 Move PP Ups
! Offset
* 0x38-0x3B [[Individual values]]
! Contents
* 0x3C-0x3F Ribbons 2
|- style="background: #eee;" align="center"
* 0x40 Gender
| 0x28-0x2F  
* 0x41-0x47 ''Unknown''
| Moveset
|- style="background: #ddd;" align="center"
| 0x30-0x33  
| Move PP
|- style="background: #eee;" align="center"
| 0x34-0x37
| Move PP Ups
|- style="background: #ddd;" align="center"
| 0x38-0x3B
| [[Individual values]]
|- style="background: #eee;" align="center"
| 0x3C-0x3F
| Ribbons 2
|- style="background: #ddd;" align="center"
| 0x40
| Gender
|- style="background: #eee;" align="center"
| 0x41-0x47
| ''Unknown''
|}


=== Block C ===
=== Block C ===
* 0x48-0x5D Nickname
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
* 0x5E ''Unknown''
|- style="background: #ccc;" align="center"
* 0x5F Hometown
! Offset
* 0x60-0x62 Contests
! Contents
* 0x63-0x67 ''Unknown''
|- style="background: #eee;" align="center"
| 0x48-0x5D
| Nickname
|- style="background: #ddd;" align="center"
| 0x5E
| ''Unknown''
|- style="background: #eee;" align="center"
| 0x5F
| Hometown
|- style="background: #ddd;" align="center"
| 0x60-0x62
| Contests
|- style="background: #eee;" align="center"
| 0x63-0x67
| ''Unknown''
|}
 


=== Block D ===
=== Block D ===
* 0x68-0x77 OT Name
{| border="1" style="border: 1px solid #999; border-collapse: collapse;"
* 0x78-0x7A Date Egg Received
|- style="background: #ccc;" align="center"
* 0x7B-0x7D Date Met
! Offset
* 0x7E-0x7F Egg Location
! Contents
* 0x80-0x81 Met At Location
|- style="background: #eee;" align="center"
* 0x82 [[Pokérus]]
| 0x68-0x77  
* 0x83 Poké Ball
| OT Name
* 0x84 Met At Level
|- style="background: #ddd;" align="center"
* 0x85 Encounter Type
| 0x78-0x7A  
* 0x86-0x87 ''Unknown''
| Date Egg Received
|- style="background: #eee;" align="center"
| 0x7B-0x7D
| Date Met
|- style="background: #ddd;" align="center"
| 0x7E-0x7F
| Egg Location
|- style="background: #eee;" align="center"
| 0x80-0x81
| Met At Location
|- style="background: #ddd;" align="center"
| 0x82
| [[Pokérus]]
|- style="background: #eee;" align="center"
| 0x83
| Poké Ball
|- style="background: #ddd;" align="center"
| 0x84
| Met At Level
|- style="background: #eee;" align="center"
| 0x85
| Encounter Type
|- style="background: #ddd;" align="center"
| 0x86-0x87
| ''Unknown''
|}


[[Category:Structures]]
[[Category:Structures]]
[[Category:Game mechanics]]
[[Category:Game mechanics]]

Revision as of 09:23, 12 July 2008

Boxed Pokémon in the games Diamond and Pearl are stored in a 136-byte structure. All unencrypted values are stored in little-endian format. The game encrypts the data when it is stored into save data. In-party Pokémon have additional values appended to them to hold calculated stats. The information below describes the boxed Pokémon data format.

Checksum

The checksum serves two purposes:

  1. It validates the data after decryption, and
  2. It serves as the encryption key for the data.

The checksum is calculated in three steps:

  1. Split the unencrypted data from offsets 0x08 to 0x87 into two-byte words,
  2. Take the sum of the words, and
  3. Truncate the sum to sixteen bits.

Block Shuffling

The 128 bytes of Pokémon data are split into four 32-byte blocks for shuffling. The blocks are shuffled according to a shift value derived from the personality value. Give the personality value pv, the expression yielding the shift value is:

((pv >> 0xD) & 0x1F) % 24

To shuffle the blocks, take the four blocks of unencrypted data to be A, B, C, and D. The blocks shall be rearranged in the encrypted data according to this table:

Shift Value (decimal) Block Order
00 ABCD
01 ABDC
02 ACBD
03 ACDB
04 ADBC
05 ADCB
06 BACD
07 BADC
08 BCAD
09 BCDA
10 BDAC
11 BDCA
12 CABD
13 CADB
14 CBAD
15 CBDA
16 CDAB
17 CDBA
18 DABC
19 DACB
20 DBAC
21 DBCA
22 DCAB
23 DCBA

Encryption

The encryption uses the pseudorandom number generator (PRNG), a linear congruential generator. Elements of the PRNG can be described with the recursive function:

X[n+1] = (0x41C64E6D * X[n] + 0x6073) % 0xFFFFFFFF

To decrypt the data, given a function rand() which returns the upper 16 bits of consecutive results of the above given function:

  1. Seed the PRNG with the checksum (let X[n] be the checksum),
  2. Sequentially, for each 2-byte word Y from 0x08 to 0x87, apply the transformation: unencryptedByte = Y xor rand()
  3. Un-shuffle the blocks using the block shuffling algorithm above.

Unencrypted bytes

Offset Contents
0x00-0x03 Personality value
0x04-0x05 Unknown
0x06-0x07 Checksum

Block A

Offset Contents
0x08-0x09 Species ID
0x0A-0x0B Held Item
0x0C-0x0D OT ID
0x0E-0x0F OT Secret ID
0x10-0x13 Experience points
0x14 Friendship/Egg Steps to Hatch
0x15 Ability
0x16 Markings
0x17 Country of Origin
0x18-0x1D Effort values
0x1E-0x23 Contest stats
0x24-0x27 Ribbons

Block B

Offset Contents
0x28-0x2F Moveset
0x30-0x33 Move PP
0x34-0x37 Move PP Ups
0x38-0x3B Individual values
0x3C-0x3F Ribbons 2
0x40 Gender
0x41-0x47 Unknown

Block C

Offset Contents
0x48-0x5D Nickname
0x5E Unknown
0x5F Hometown
0x60-0x62 Contests
0x63-0x67 Unknown


Block D

Offset Contents
0x68-0x77 OT Name
0x78-0x7A Date Egg Received
0x7B-0x7D Date Met
0x7E-0x7F Egg Location
0x80-0x81 Met At Location
0x82 Pokérus
0x83 Poké Ball
0x84 Met At Level
0x85 Encounter Type
0x86-0x87 Unknown