Pokemon Save Structure

From ProjectPokemon Wiki
Revision as of 03:01, 15 February 2009 by SCV (talk | contribs)
Jump to navigation Jump to search

Pokemon NDS Structure

Boxed Pokémon in the games Pokémon Diamond Pearl and Platinum are stored in a 136 byte or 236 byte structure. All unencrypted values are stored in little-endian format. The game encrypts the data when it is stored into save data. Party Pokémon have additional values to hold current battle stats and conditions. The information below describes the 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 16 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. Given the personality value pv, the expression yielding the shift value is:

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

The right shifting (pv >> 0xD) is equivalent to a division of 8192.

To shuffle the blocks, take the four blocks of unencrypted data, 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)

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. Unshuffle the blocks using the block shuffling algorithm above.

To encrypt the data:

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

Unencrypted bytes

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

Encrypted bytes

Block A

Offset Contents
0x08-0x09 PokeDex National Index
0x0A-0x0B Held Item
0x0C-0x0D OT ID
0x0E-0x0F OT Secret ID
0x10-0x13 Experience points
0x14 Friendship (Steps to Hatch if an egg)
0x15 Ability
0x16 Markings
0x17 Country of Origin
0x18 HP Effort Value
0x19 Attack Effort Value
0x1A Defense Effort Value
0x1B Speed Effort Value
0x1C SP Attack Effort Value
0x1D SP Defense Effort Value
0x1E-0x23 Contest stats
0x24-0x25 Ribbon Set 1
0x26-0x27 Ribbon Set 2

Block B

Offset Contents
0x28-0x2F Move Set
0x30-0x33 Move PP
0x34-0x37 Move PP Ups
0x38-0x3B Bits 0-29 - Individual values

HP ( [0-31] << 0 )
Attack ( [0-31] << 5 )
Defense ( [0-31] << 10 )
Speed ( [0-31] << 15 )
SP Attack ( [0-31] << 20 )
SP Defense ( [0-31] << 25 )

Bit 30 - IsNicknamed Flag
Bit 31 - IsEgg Flag

0x3C-0x3D Ribbon Set 3
0x3E-0x3F Ribbon Set 4
0x40-0x41 Bit 0 - Fateful Encounter Flag
Bit 1 - Female
Bit 2 - Genderless
Bit 3-15 - #Alternate Forms (Form Index << 3)
0x42-0x43 Unknown
0x44-0x45 Egg Location (Platinum)
0x46-0x47 Met at Location (Platinum)

Block C

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

Block D

Offset Contents
0x68-0x77 [[Original Trainer|OT Name]
0x78-0x7A Date Egg Received
0x7B-0x7D Date Met
0x7E-0x7F Egg Location (Diamond/Pearl)
0x80-0x81 Met At Location (Diamond/Pearl)
0x82 Pokérus
0x83 PokéBall
0x84 Bit 0-6 - Met At Level
Bit 7 - Female OT Gender
0x85 Encounter Type
0x86-0x87 Unknown

Battle Stats

Country of Origin

Markings

Encounter Types

Ribbons

DP stores the ribbon data as bitfields in 16-bit words. Given below are the bytewise representations of the ribbon bitfields:

Ribbon Set 1

Bit Ribbon
0x25 & 0x01 Sinnoh Champ Ribbon
0x25 & 0x02 Ability Ribbon
0x25 & 0x04 Great Ability Ribbon
0x25 & 0x08 Double Ability Ribbon
0x25 & 0x10 Multi Ability Ribbon
0x25 & 0x20 Pair Ability Ribbon
0x25 & 0x40 World Ability Ribbon
0x25 & 0x80 Alert Ribbon
0x24 & 0x01 Shock Ribbon
0x24 & 0x02 Downcast Ribbon
0x24 & 0x04 Careless Ribbon
0x24 & 0x08 Relax Ribbon
0x24 & 0x10 Snooze Ribbon
0x24 & 0x20 Smile Ribbon
0x24 & 0x40 Gorgeous Ribbon
0x24 & 0x80 Royal Ribbon

Ribbon Set 2

Bit Ribbon
0x27 & 0x01 Gorgeous Royal Ribbon
0x27 & 0x02 Footprint Ribbon
0x27 & 0x04 Record Ribbon
0x27 & 0x08 History Ribbon
0x27 & 0x10 Legend Ribbon
0x27 & 0x20 Red Ribbon
0x27 & 0x40 Green Ribbon
0x27 & 0x80 Blue Ribbon
0x26 & 0x01 Festival Ribbon
0x26 & 0x02 Carnival Ribbon
0x26 & 0x04 Classic Ribbon
0x26 & 0x08 Premier Ribbon

Ribbon Set 3

Bit Ribbon
0x3D & 0x01 Cool Ribbon
0x3D & 0x02 Cool Ribbon Super
0x3D & 0x04 Cool Ribbon Hyper
0x3D & 0x08 Cool Ribbon Master
0x3D & 0x10 Beauty Ribbon
0x3D & 0x20 Beauty Ribbon Super
0x3D & 0x40 Beauty Ribbon Hyper
0x3D & 0x80 Beauty Ribbon Master
0x3C & 0x01 Cute Ribbon
0x3C & 0x02 Cute Ribbon Super
0x3C & 0x04 Cute Ribbon Hyper
0x3C & 0x08 Cute Ribbon Master
0x3C & 0x10 Smart Ribbon
0x3C & 0x20 Smart Ribbon Super
0x3C & 0x40 Smart Ribbon Hyper
0x3C & 0x80 Smart Ribbon Master

Ribbon Set 4

Bit Ribbon
0x3F & 0x01 Tough Ribbon
0x3F & 0x02 Tough Ribbon Super
0x3F & 0x04 Tough Ribbon Hyper
0x3F & 0x08 Tough Ribbon Master
0x3F & 0x10 Champion Ribbon
0x3F & 0x20 Winning Ribbon
0x3F & 0x40 Victory Ribbon
0x3F & 0x80 Artist Ribbon
0x3E & 0x01 Effort Ribbon
0x3E & 0x02 Marine Ribbon
0x3E & 0x04 Land Ribbon
0x3E & 0x08 Sky Ribbon
0x3E & 0x10 Country Ribbon
0x3E & 0x20 National Ribbon
0x3E & 0x40 Earth Ribbon
0x3E & 0x80 World Ribbon

Save File Location

The party Pokémon are stored in the save file beginning at offset 0x00098 for the first small block, and 0x40098 for the second small block. Each party Pokémon is 236 bytes in size. Pokemon in the daycare center and pal park also consist of 236 bytes.

The PC storage Pokémon are stored in the save file from Box 1 to Box 18. The offset starts at 0x0C105 for the first big block and 0x4C105 for the second big block. Each PC stored Pokémon is 136 bytes in size.