Ruby/Sapphire Save Data Map

This is a map of the Save data from Pokemon Ruby & Sapphire where the save file data blocks have been concatonated. See Pokemon GBA Save Format for more details.

If you have any information not listed, or you'd like to correct something I've gotten wrong, send me a note at pokemonresearch@furlocks-forest.net.

Bear in mind that I've not been consistent with wording here. Words/Ints are 32-bit, half-words are 16-bit. Also note that bytes are stored little-endian for 16-bit/32-bit values.

Ruby/Sapphire Data Map
---------------------

=== BLOCK 0 (0x0000 - 0x0F79) ===
=== Trainer data, Pokedex status, Battle Tower stats ===

0x0000 - Trainer Name (7Bytes)
0x0007 - 0xFF terminating byte?
0x0009 - Bit 0 = Gender - 0=Male, 1=Female
0x000A - Trainer ID (4Bytes)

...

0x0028 - Pokedex Owned flags (49 Bytes / 386 bits)
0x005C - Pokedex Seen flags (49 Bytes / 386 bits)

...

0x0098 - Adventure Start Time
         This is according to the RTC module, which seems to only start
         running when you first power it up.  
         The format is 1 byte per value:
         DD, H, M, S - with DD being a 16-bit value.
         None of these are BCD, they're just integers.

         My tests suggest this isn't a straight up dump of the RTC at
         adventure start though.  
         

0x00A0 - Save Timestamp (5 bytes) - 
         In-game time.  Same format as the Offset
 
         If the value of the RTC (+/- offset) is lower than the timestamp
         then it will not update any in-game timer-based events.
         For more details see Pokemon Ruby/Sapphire New Battery Glitch

...

0x00A8 - Battle Tower Data - (6 x 164 Bytes)

...

0x0498 - Mossdeep Trainer Data (188 Bytes)

...

=== BLOCK 1 (0x0F80 - 0x1EFF) ===
=== Part Pokemon, Inventory, Pokeblock case ===

0x0F80 - Your Y Position on the current map (short)
0x0F82 - Your X Position on the current map (short)
0x0F84 - The address of the current map (word)

0x0xFB4 - Map data from when you last saved.
It looks like this stores actual GBA tilemap data
The intention was probably to use this for temporary
event rooms.  
1 short per tile.  Not sure what the limit is on tiles.

...

0x11B4 - Number of pokémon in party (Byte)
0x11B8 - Party Position #1 (100Bytes)
0x121C - Party Position #2 (100Bytes)
0x1280 - Party Position #3 (100Bytes)
0x12E4 - Party Position #4 (100Bytes)
0x1348 - Party Position #5 (100Bytes)
0x13AC - Party Position #6 (100Bytes)

...

0x1410 - Money (Word)
0x1414 - Coins (Halfword)

...

0x1418 - Start of Inventory 
Each entry consists of one short for the item ID
and one short for the item quantity.  
In FireRed, LeafGreen and Emerald, the quantity value is
XOR'd with an encryption key stored in Block 0.
This is not the case for Ruby/Sapphire though.

...

0x1778 - Pokeblocks (n x 8 bytes)
         0x00 - Colour
         0x01 - Spicy
         0x02 - Dry
         0x03 - Sweet
         0x04 - Bitter
         0x05 - Sour
         0x06 - Feel
         0x07 - ???
         
         The 'level' shown in the menu is the 
         highest value out of the different 
         flavours.  
...

=== BLOCK 2 (0x1F00 - 0x2E79) ===
=== Some item/environment variables, loamy soil status ===

0x2308 - Pretty sure this is the Mirage Island random value.
         If the last two bytes of a pokemon you're carrying match this 
         value then Mirage Island will appear on Route 130.

...

0x2350 - Amount of Volcanic Ash (Halfword?)

...

0x2590 - Loamy Soil (88 x 8 Bytes)
         These don't appear to be in any particular
         order...

         0x00 - Berry ID (1-42)     Byte
         0x01 - State               Byte
                The 3 least significant bits are 
                used to determine plant state
                1 - mound/just planted
                2 - sprouting
                3 - growing taller
                4 - flowering
                5 - fruiting
                In the trees that you find throught
                Hoenn initially, these trees have
                the most significant bit set to
                prevent them from dying.
         0x02 - Minutes remaining   Halfword 
                This is the number of minutes left
                of the current phase (ie: sprouting)
         0x04 - Number of berries   Byte
                Obviously this is only set if the
                tree is fruiting.
         0x05 - Water/Regrowing     Byte
                The higher nibble's bits are set
                starting with the LSB to show 
                whether the plant was watered during
                each phase.
                The lower nibble keeps count of 
                the number of times the plant has 
                died/expired and a berry has regrown
                in its place.
         0x06 - Unknown.             Byte
         0x07 - Unknown.             Byte
                These two may just be padding.

...

0x2988 - Start of Secret Base Data 20 x 160 Bytes

...

=== BLOCK 3 (0x2E80 - 0x3DFF) ===
=== Television & Contest data ===

0x377C - Television Show Data
         Unsure of format as yet - research needed

...

0x3D7C - Contest Hall Winner Paintings (13 x 32 Bytes)
         First 8 are Contest Hall Winner Paintings
         Last 5 are Lilycove Museum Paintings and
         will be blank if player has not entered
         any paintings yet.
         0x00 - Pokemon's personality (Word)
         0x04 - Pokemon's OT ID       (Word)
         0x08 - Pokemon's species     (Halfword)
         0x0A - Padding               (Byte)
         0x0B - Pokemon's name        (10 Bytes)
         0x16 - Trainer's name        (7 Bytes)
                This is the trainer who won the
                contest using this pokemon, not 
                the original trainer

=== BLOCK 4 Daycare, eCard related data ===
0x3F1C - Daycare Pokemon #1 (80 bytes)
0x3F6C - Daycare Pokemon #2 (80 bytes)

...

0x4038 - Link Battle Results (5 x 16 Bytes)
         0x00 - Name        (7 Bytes)
         0x07 - Padding     (1 Byte)
         0x08 - Unknown     (Halfword?)
         0x0A - Wins        (Halfword)
         0x0C - Losses      (Halfword)
         0x0E - Draws       (Halfword)

...

0x4610 - Start of Mystery Event Data (0x3E7 bytes?)
Mystery Event data consists of a 2byte checksum, 
2 bytes of padding and then Event data.  I am 
currently examining the Eon Ticket event in hopes
of understanding how it works.  From what I can tell,
whenever you talk to Norman in Petalburg Gym, the
game checks if an event is stored here before 
either displaying his default NPC text or the text
saved in the Mystery Event data.  

I'm guessing that the event is rather specifically
structured and can only provide Norman with text
and an item to give you such as the Eon Ticket or
Enigma Berry.  

For Trainer Battle e-cards see this page.

If you would like to examine a save that contains
the Mystery Event data drop me an email and I'll 
send you a copy of the .sav file.

...

=== BLOCK 5-13 - 0x3E00 - 0xD8FF) ===
=== PC Box Pokemon, Box settings - spans multiple data blocks ===

0x4D80 - Currently Selected Box? (Byte)

0x4D84 - Start of Box Pokemon data (80Bytes x 30 PKMN x 14 Boxes)

...

0xD0C4 - Start of Box Names (9Bytes x 14 Boxes)

0xD142 - Box Wallpaper (14 Bytes)

...

Block 0x1B

There is an additional block of save data positioned after the main 2 save files. This block contains the data on the Hall of Fame PC.

What's Missing?

There's some bits and bobs that I've spotted in the data but have no idea of the structure, while some other things I haven't a clue about.

Spotted

  • TV Programme Data

Unknown

  • Trainers' Eyes
  • A way of determining version

There's much more of course.

Other

Ribbons aren't really documented anywhere else so I'd probably better cover them here.

In the 'Misc' data block of each pokemon, there is a single Word value that stores the ribbons attached to that pokemon. It's a bit odd as there are significantly more that 32 ribbons so I'll try to break it down here.

Contest Ribbons

The first 15 bits tell us what contest ribbons the pokemon holds, but it's not a case of it being 1 bit per ribbon. Instead, what he have is 3 bits per ribbon, each showing a value representing the number of ranks that pokemon has achieved per contest type:

  • 0 - 2 -> Cool Rank
  • 3 - 5 -> Beauty Rank
  • 6 - 7 -> Cute Rank
  • 9 -11 -> Smart Rank
  • 12-14 -> Tough Rank

Each value gives us from 0 - 4, 0 being no rank, 4 being master rank. When a pokemon is any rank higher than 1, they will have all the ribbons for earlier ranks as well.

Other Ribbons

The next few bits give specific ribbons:

  • Bit 15 -> Champion Ribbon
  • Bit 18 -> Artist Ribbon
  • Bit 19 -> Effort Ribbon
  • Bit 24 -> Cleared All Difficulties Ribbon (Purified on Colusseum)

There are a number of other ribbons that seem impossible to fit here. I'm currently investigating these.

Last updated 07:26pm 16/08/2014 by Adam
blog comments powered by Disqus