Pokémon DP Save File Structure
General Save File Structure
A Pokémon Diamond and Pearl save file is divided into two pairs of blocks. Each pair consists of one general block, one storage box block, and one hall of fame block. The storage box block contains current information regarding the Bebe's storage system, including stored Pokémon, box names, box wallpapers, and the current open box. The general block contains current information on every other aspect of the game's progress, such as the trainer's name, ID number, acquired badges, party Pokémon, items, and much more. The hall of fame block contains information about the Pokémon used to defeat the Elite 4. The other pair of blocks is a backup from the previous save.
The first general block in the file begins at 0x00000. The first storage block begins at 0x0C100. The first hall of fame block starts at 0x20000. The second general, storage, and hall of fame blocks are at the same address + 0x40000. The current blocks are not always stored in linear order in the save file (i.e. if the second general block is the more current, the first or second storage box block can possibly be the current as well).
The last 20 bytes of each general and storage box block is a footer. The last 24 bytes of each hall of fame block is a footer. The footer is used to determine:
- The size of the block
- Whether the block is current or a backup.
- Which big & small blocks link together.
Offset | Purpose |
---|---|
0x00 - 0x03 | Save ID number |
0x04 - 0x07 | Save index number |
0x08 - 0x0B | Size of block |
0x0C - 0x0F | Run-time usage |
0x10 - 0x11 | Run-time usage |
0x12 - 0x13 | Checksum |
Offset | Purpose |
---|---|
0x00 - 0x03 | Save ID number |
0x04 - 0x07 | Save index number |
0x08 - 0x0B | Run-time usage |
0x0C - 0x0F | Run-time usage |
0x10 - 0x13 | Size of block |
0x14 - 0x15 | Run-time usage |
0x16 - 0x17 | Checksum |
Loading/Saving A Save File
When the game loads the save file, it first compares the save index number of each small block. If the small block with the highest save index number has a correct checksum, then the game checks to see which big block has a matching ID number. If both big blocks have the same ID number as the small block, then the big block with the highest save index number is chosen. If the big block chosen by the save file has a correct checksum, then the game loads successfully. If the checksum is incorrect in either the small or big block, the game reverts to the other block pair. If either of their checksums are incorrect, then no data is loaded, and a new game must be started.
When the game saves data, the save index number is incremented + 1 from the current save index number, and the backup small block is overwritten with the new data.
If nothing in the big block has changed, then the save ID number in both blocks is retained. However, if changes have been made to the big block, then the backup big block is overwritten with the new data, and a new save ID number is generated, which is then written to the new small block. This is the reason why the game varies on how long it takes to save.
Thus, either small block can be linked with either big block, and the current pair is identified using the footer information.
Small block offsets
Adventure Started - 0x34
- Unsigned 32bit integer.
- Number of seconds since 1/1/2000 00:00:00
Pokémon League Champ Date - 0x3C
- Unsigned 32bit integer.
- Number of seconds since 1/1/2000 00:00:00
Trainer Name - 0x64
- 8 unsigned 16bit integers.
- Each word represents a character in the game's character table.
Trainer ID - 0x74
- Random unsigned 16bit integer
- The visible identification number of a trainer
- Determines ownership of Pokémon.
Secret ID - 0x76
- Random unsigned 16bit integer
- The hidden identification number of a trainer
- Determines ownership of Pokémon.
- Determines variation in the game.
Money - 0x78
- Unsigned 32bit integer.
- Limited to 0xF423F (999,999)
Trainer Gender - 0x7C
- 0 if male, 1 if female.
- Determines ownership of Pokémon.
Multiplayer Avatar - 0x7F
- Unsigned 8bit integer.
- Determines the sprite seen by other players in a multiplayer environment such as the Union Room.
- 0x00 = None
- 0x03 = School Kid
- 0x05 = Bug Catcher
- 0x06 = Lass
- 0x07 = Battle Girl
- 0x0B = Ace Trainer Male
- 0x0D = Beauty
- 0x0E = Ace Trainer Female
- 0x0F = Roughneck
- 0x1F = Pop Idol
- 0x23 = Social
- 0x25 = Cowgirl
- 0x2A = Ruin Maniac
- 0x32 = Black Belt
- 0x3E = Rich Boy
- 0x3F = Lady
- 0x46 = Psychic
Number of Current Party Pokémon - 0x94
- Unsigned 8bit integer.
Party Pokémon - 0x98
The Pokémon in the trainer's party.
- 6 blocks of 236byte structures
- Main article: Pokemon NDS Structure
Fly Locations - 0x1112
- 9byte bit field
Berry Trees - 0x1E84
- 128 blocks of 14byte structures
- List of Berry Tree locations
- Main article: Berry Trees
Rival's Name - 0x25A8
- 8 unsigned 16bit integers.
- Each word represents a character in the game's character table.
Safari Zone Pokémon - 0x72D0
- Unsigned 32bit integer result from the ARNG.
- Four daily safari zone Pokémon
- Indexn = ( ARNG >> ( n * 0x5 ) ) & 0x1F
- List of Safari Zone Pokémon
- Notes: Both Safari Zone Pokémon and Swarm Pokémon have the same ARNG value.
Swarm Pokémon - 0x72D4
- Unsigned 32bit integer result from the ARNG.
- One daily swarm Pokémon
- Index = ARNG % 0x1C
- List of Swarm Pokémon
- Notes: Both Safari Zone Pokémon and Swarm Pokémon have the same ARNG value.
Daily Trophy Pokémon Today - 0x72DC
- Unsigned 8bit integer
- First daily trophy garden Pokémon
- List of Daily Trophy Pokémon
Daily Trophy Pokémon Yesterday - 0x72DE
- Unsigned 8bit integer
- Second daily trophy garden Pokémon
- List of Daily Trophy Pokémon
- Notes: Yesterday's Pokémon can be caught after beating the Elite 4 and receiving the National Pokédex upgrade.
Honey Trees - 0x72E4
- 21 blocks of 8byte structures
- List of Honey Tree locations
- Main article: Honey Trees