Save data structure (Generation IV)

This article is incomplete.
Please feel free to edit this article to add missing information and complete it.

The save data structure in the Nintendo DS is stored as a .SAV file, which is broken up into two pairs of blocks. Each pair has one general (small) block, and one storage (big) block. The offsets for Platinum are different from Diamond and Pearl.

In Diamond and Pearl, the first small block starts at 0x00000 and ends at 0x0C0FF, the first big block starts at 0x0C100 and ends at 0x1E2DF. In Platinum, the first small block starts at 0x00000 and ends at 0x0CF2B, the first big block starts at 0x0CF2C and ends at 0x1F10F. The second pair of blocks are at the same address plus 0x40000 for all the three games.

In HeartGold and SoulSilver, the first small block starts at 0x00000 and ends at 0x0F6FF, the first big block starts at 0x0F700 and ends at 0x21A10.

One block pair is always a backup of the other block pair.

General (small) block

The small block has the following data:

Offset Length (bytes) Type Contents Notes
0x00 8 i64 RTC Offset
0x08 6 u8[6] DS MAC Address This is always set, even if you have never used networking
0x0E 1 u8 DS Profile birthday month
0x0F 1 u8 DS Profile birthday date
0x10 4 bool Canary This is always set to 1
0x14 4 u32 RTC Year
0x18 4 u32 RTC Month
0x1C 4 u32 RTC Date
0x20 4 u32 RTC Weekday 0 = Sunday, 1 = Monday ...
0x24 4 u32 RTC Hour
0x28 4 u32 RTC Minute
0x2C 4 u32 RTC Second
0x30 4 u32 Day
0x34 8 i64 Timestamp when the save started Number of seconds since 2000-01-01T00:00:00Z
0x3C 8 i64 Timestamp of first Hall of Fame entrance Number of seconds since 2000-01-01T00:00:00Z
0x44 4 u32 Clock change penalty This is a number of minutes set when you load your save and the RTC mismatches
0x48 1 bool Mystery Gift unlocked
0x49 1 Unused?
0x4A 4 s32 Network profile ID This is only set after an initial connection to DS WiFi Communications
0x68 16 string Trainer Name See Character Encoding (Generation IV) to convert each u16 into a character
0x78 2 u16 Trainer ID
0x7A 2 u16 Secret ID
0x7C 4 u32 Money Capped at 999,999
0x80 1 u8 Gender 0 = Male, 1 = Female
0x81 1 u8 Cartridge Locale 1 = Japan, 2 = Western English (US/UK/AU),

3 = French, 4 = Italian, 5 = German,

6 = Spanish, 7 = South Korean

0x82 1 bool[8] Badges Stored as a bitfield:

(value & 1) = Coal; (value & 2) = Forest; (value & 4) = Cobble; (value & 8) = Fen;

(value & 16) = Relic; (value & 32) = Mine; (value & 64) = Icicle; (value & 128) = Beacon

0x83 1 u8 Avatar 0 = None; 3 = School Kid; 5 = Bug Catcher; 6 = Lass; 7 = Battle Girl; 11 = Ace Trainer Male;

13 = Beauty; 14 = Ace Trainer Female; 15 = Roughneck; 20 = Pop Idol; 35 = Social;

37 = Cowgirl; 42 = Ruin Maniac; 50 = Black Belt; 62 = Rich Boy; 63 = Lady; 70 = Psychic

0x88 2 u16 Game Corner coins
0x8A 2 u16 Hours played
0x8C 1 u8 Minutes played
0x8D 1 u8 Seconds played
0x9C 1 u8 Number of Pokémon in Party
0xA0 - 0x627 1416 pkmn[6] Party Pokémon blocks See Pokémon data structure (Generation IV) to decrypt and parse these entries.

NOTE: Party Pokémon include Battle stats which takes up an extra 100 bytes.

0x00630 - 0x008C3 660 item[165] Items placeholder
0x008C4 - 0x0098B 200 item[50] Key Items placeholder
0x0098C - 0x00B4B 400 item[100] TMs & HMs placeholder
0x00B4C - 0x00BEB 160 item[40] Medicines placeholder
0x00BDC - 0x00CEB 256 item[64] Berries placeholder
0x00CEC - 0x00D27 60 item[15] Poké Balls placeholder
0x00D28 - 0x00D5B 52 item[13] Battle Items placeholder
0x00D5C - 0x00D8B 48 item[12] Mail placeholder
0x0CF18 - 0x0CF2B 20 Footer

Item placeholders

In these placeholders, each item takes 4 bytes with the following structure:

Offset Contents
0x00 - 0x01 Item ID
0x02 - 0x03 Item amount

Each item has a unique ID to get identified. See the list of items by index number in Generation IV for these IDs.

Storage (big) block

The storage block contains information regarding your boxes. In generation 4, you have 18 boxes, each with 30 Pokémon.

Diamond / Pearl / Platinum

Offset Length (bytes) Type Contents Notes
0x00 4 u32 Last selected box index 0 = Box 1 ...
0x04 73,440 box[18] Box Pokémon See Pokémon data structure (Generation IV) to decrypt and parse these entries.

NOTE: each Pokémon is 136 bytes.

0x11EE4 720 string[18] Box names See Character Encoding (Generation IV) to convert each u16 into a character
0x121B4 18 u8[18] Box wallpapers
0x121C6 20 Footer

HeartGold / SoulSilver

NOTE: exclusive to HGSS, box data is padded. The last 0x10 (16) bytes of each box are empty, making each box 0x1000 (4096) bytes long. In addition, the last 0x16 bytes of the storage block are unused.

Offset Length (bytes) Type Contents Notes
0x00 73,728 box[18] Box Pokémon See Pokémon data structure (Generation IV) to decrypt and parse these entries.

NOTE: each Pokémon is 136 bytes.

0x12000 4 u32 Last selected box index 0 = Box 1 ...
0x12004 4 u32 Total number of Pokémon stored in boxes This value may not always be set?
0x12008 720 string[18] Box names See Character Encoding (Generation IV) to convert each u16 into a character
0x122D8 18 u8[18] Box wallpapers
0x122EA 22 Unused
0x122FE 20 Footer

Footer

The last 0x14 bytes of each block (small and big) are used as a footer. It has the following structure:

Offset Contents
0x00 - 0x03 Used to connect a small block with a big block
0x04 - 0x07 Number of the save
0x08 - 0x0B Size of the block
0x0C - 0x0F K
0x10 - 0x11 T
0x12 - 0x13 Checksum of the block

Checksum

The game uses a CRC-16-CCITT algorithm for the checksums. These checksums are calculated from a whole block without taking the footer.

Example

SMALL BLOCK 1
D1 01 00 00 | 42 04 00 00 | 00 C1 00 00 | 23 06 06 20 | 00 00 | 7E 7A

BIG BLOCK 1
D0 01 00 00 | F1 02 00 00 | E0 21 01 00 | 23 06 06 20 | 01 00 | 0D 39
SMALL BLOCK 2
D0 01 00 00 | 41 04 00 00 | 00 C1 00 00 | 23 06 06 20 | 00 00 | 0C 7F

BIG BLOCK 2
D1 01 00 00 | F2 02 00 00 | E0 21 01 00 | 23 06 06 20 | 01 00 | F6 8A

Since the value of 0x0C0F0 - 0x0C0F3 is higher in small block 1 (42 04 00 00 > 41 04 00 00), that is the current small block. Then, by matching the value of 0x0C0EC - 0x0C0EF (which is D1 01 00 00) to the big block. This means that the current big block is actually big block 2 (assuming the big block's checksum is correct).

Related articles

Data structure in the Pokémon games
General Character encoding
Generation I Pokémon speciesPokémonPoké MartCharacter encoding (Stadium) • Save
Generation II Pokémon speciesPokémonTrainerCharacter encoding (StadiumKorean) • Save
Generation III Pokémon species (EvolutionPokédexType chart)
Pokémon (substructures) • MoveContestContest moveItem
Trainer TowerBattle FrontierCharacter encoding (GameCube) • Save
Generation IV Pokémon species (EvolutionLearnsets)
Pokémon • • Character encoding (Wii)
Generation V–present Character encoding
Generation VIII Save
TCG GB and GB2 Character encoding
This data structure article is part of Project Games, a Bulbapedia project that aims to write comprehensive articles on the Pokémon games.