Editing of Bulbapedia is currently restricted. Please see this message for more details.
Pokémon Omega Ruby and Alpha Sapphire are coming this November!

Check BNN and Bulbanews for up-to-date Pokémon news and discuss it on the forums or in our IRC channel.

Save data structure in Generation I

From Bulbapedia, the community-driven Pokémon encyclopedia.
Jump to: navigation, search
292Shedinja.png The contents of this article have been suggested to be split into Character encoding in Generation I.
Please discuss it on the talk page for this article.
050Diglett.png This article is incomplete.
Please feel free to edit this article to add missing information and complete it.

129Magikarp.png This article does not yet meet the quality standards of Bulbapedia. Please feel free to edit this article to make it conform to Bulbapedia norms and conventions.

Overview

The save data structure for Generation I is stored in the cartridge's volatile battery-backed RAM chip (SRAM), or as a ".sav" file from most emulators. The structure consists of 32 KB of data, though not every byte is used. Emulators may append additional data for the purposes of maintaining real-time clock operations, despite the fact that Generation I games do not use any such functionality.

A region of the save data has its integrity validated via checksum. This region contains all of the information that directly pertains to the player and his or her Pokémon. Additional information pertinent to the save file is also present in the other regions of the data.

Data types

Unless otherwise noted, integer values occupy the specified number of bytes, and are big-endian and either unsigned or two's complement.

Text data

Text data for Generation I is stored in a proprietary character set. The text characters available for use by players in the game have the following byte values:

  -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F
0-
1-
2-
3-
4-
5-
6-
7-
Unused, except for:
0x50 (terminator) and
0x7F (space)
8- A B C D E F G H I J K L M N O P
9- Q R S T U V W X Y Z ( ) : ; [ ]
A- a b c d e f g h i j k l m n o p
B- q r s t u v w x y z  
C-
D-
Unused
E-   PK MN -   ? ! .  
F-   ×   / , 0 1 2 3 4 5 6 7 8 9

Notes

  • Strings of text are terminated with 0x50, rather than the traditional 0x00. A terminator must be present at the end of every string of text.
  • If a string is shorter than the maximum number of characters allocated for it, then the remaining bytes after the terminator are padded with junk.

Item lists

Lists of items in the save data follow a particular format.

Lists have entries of 2 bytes each, and a capacity. The total size of the list data, in bytes, is:

Capacity * 2 + 2

For example, your pocket inventory can hold 20 item entries, so the size of that list is 20 * 2 + 2 = 42 bytes.

Offset Size Contents
0x00 1 Count
0x01 2 * Capacity Entries
... +0x00 1 Terminator

Count

The number of item entries actually being represented in the list.

Entries

The exact data for each item entry in the list. For more information, see below.

Terminator

The byte following the last item entry, according to Count, must always be a terminator, which is byte value 0xFF.

This spare byte is present at the end of the list data for the event when the list is filled to capacity.

Entry format

The Entry record has the following format:

Offset Size Contents
0x00 1 Index
0x01 1 Count

Count

The number of that particular item. Must be 1 to 99, inclusive.

Index

The item's index.

Pokémon lists

Lists of Pokémon in the save data follow a particular format.

Lists have entries of varying sizes, and a capacity. The total size of the list data, in bytes, is:

Capacity * (Size + 23) + 2

For example, your Pokémon team contains 6 entries and each entry is 44 bytes in size, so the size of that list is 6 * (44 + 23) + 2 = 404 bytes.

Offset Size Contents
0x0000 1 Count
0x0001 Capacity + 1 Species
... + 0x0000 Capacity * Size Pokémon
... + 0x0000 Capacity * 11 OT Names
... + 0x0000 Capacity * 11 Names

Count

The number of Pokémon entries actually being represented in the list.

Species

A list of species indexes, one for each Pokémon in the list. This is used by the team menu as well as the PC management interface.

The byte following the last species entry, according to Count, must always be a terminator, which is byte value 0xFF.

Editor's Note: This field is used in Generation II to specify whether the corresponding Pokémon is still in its egg.

Pokémon

The exact data for each Pokémon entry in the list. For the format, please refer to: Pokémon data structure in Generation I

  • For team Pokémon, the entry size is the full 44 bytes as documented in that article.
  • For PC Pokémon, only the first 33 bytes are used, meaning everything after Move 4's PP values is not included. Instead, those values are regenerated upon withdrawing a Pokémon from the PC. This is the basis of the Box trick.

OT names

Text strings representing the names of the original trainers for each Pokémon entry. Each name can contain from 1 to 10 characters.

Names

Text strings representing the names for each Pokémon entry. Each name can contain from 1 to 10 characters.

A name is considered a "nickname" if it does not perfectly match the default name for a Pokémon. The default name follows these rules:

  • The first however many characters must match the species name exactly. This is typically all-uppercase.
  • The remainder of the string must be all terminator characters, aka 0x50.

Therefore, if a Pokémon with a 9- or 10-letter species name, such as Charmander, is given a nickname that matches the species name, the nickname will not be retained should that Pokémon evolve.

File structure

Known data within the save file can be found at the following offsets within the data, such that offset 0 is the first byte of the emulator ".sav" file:

Editor's Note: This applies to the North American Red, Blue and Yellow for sure, but whether any of it is different in other releases has yet to be seen.

Offset Size Contents
0x2598 8 Player name
0x25A3 19 Pokédex owned
0x25B6 19 Pokédex seen
0x25C9 42 Pocket item list
0x25F3 3 Money
0x25F6 8 Rival name
0x2601 1 Options
0x2602 1 Badges
0x2605 2 Player Trainer ID
0x271C 1 Pikachu FriendshipY
0x27E6 102 PC item list
0x284C 1 Current PC Box
0x2850 2 Casino coins
0x2CEE 4 Time played
0x2F2C 404 Team Pokémon list
0x30C0 1122 Current Box Pokémon list
0x3523 1 Checksum
0x4000 1122 PC Box 1 Pokémon list
0x4462 1122 PC Box 2 Pokémon list
0x48C4 1122 PC Box 3 Pokémon list
0x4D26 1122 PC Box 4 Pokémon list
0x5188 1122 PC Box 5 Pokémon list
0x55EA 1122 PC Box 6 Pokémon list
0x6000 1122 PC Box 7 Pokémon list
0x6462 1122 PC Box 8 Pokémon list
0x68C4 1122 PC Box 9 Pokémon list
0x6D26 1122 PC Box 10 Pokémon list
0x7188 1122 PC Box 11 Pokémon list
0x75EA 1122 PC Box 12 Pokémon list

Player name, rival name

Represents text strings that can be from 1 to 7 characters in length.

Pokédex Owned, Pokédex Seen

Represents the specific Pokédex entries that have been either seen or owned during gameplay.

Pokémon are indexed by their usual Pokédex order, meaning the order is the same as in the National Pokédex. However, indexes begin counting at 0, rather than 1.

1 bit is used to represent whether a given Pokémon has been seen/owned. Bits are ordered within bytes from lowest to highest, starting with the first byte. Therefore, the exact bit can be extracted from the list using the following formula:

Bit = ( Data[ RoundDown(PokeNum / 8) ] / 2 ^ (PokeNum Mod 8) ) AND 1

Or in C-style code (shift occurs before other bitwise operations):

Bit = Data[PokeNum >> 3] >> (PokeNum & 7) & 1;

Example

Let us say that we want to know whether #120 Staryu has been seen/owned:

  • PokeNum becomes 119, since it is 0-based.
  • The byte of the list in which bit 119 is located is = 119 / 8 = 14
  • The bit within that byte is = 119 Mod 8 = 7
  • Dividing the byte value by 2 ^ Bit, or shifting right by Bit, moves the bit to the least-significant position
  • Performing a bitwise AND with 1 will remove all but the least-significant bit

Entry #152

As the bit lists are packed into 19 bytes, there is actually space for 152 entries. The last entry, bit 7 of byte 18, does in fact represent an entry #152 in the Pokédex. However, it is simply a copy of Kangaskhan.

Pocket item list

The items that the player has in his or her pocket inventory.

Stored as an Item list with a capacity of 20.

Money

Represents how much money the character has. The figure is a 6-digit number, 2 digits per byte, encoded as binary-coded decimal, where each digit is allocated a full 4 bits.

This figure is still big-endian.

Casino coin

Represents how much coins the character has. The figure is a 4-digit number, 2 digits per byte, encoded as binary-coded decimal, where each digit is allocated a full 4 bits.

This figure is still big-endian.

Options

Options are stored in one byte:

* bit 7 (MSB): battle effects ('1' for No, '0' for Yes)
* bit 6: battle style ('1' for Set, '0' for Switch)
* bit 4: sound ('0' for Mono, '1' for Stereo)
* bit 2-0: text speed ('001' for Fast, '011' for Normal, '101' for Slow)

In Pokémon Yellow:

* bit 5-4: sound ('00' for Mono, '01' for Earphone1, '10' for Earphone2, '11' for Earphone3)

Print options are stored somewhere else.

Badges

The eight badges are stored on eight bits, one bit for each badge, being '1' is the badge is acquired, '0' otherwise.

From MSB to LSB, badges are in this order: Boulder, Cascade, Thunder, Rainbow, Soul, Marsh, Volcano, Earth.

Pikachu Friendship

Represents the friendship level of the starter Pikachu. For Red and Blue, this value is fixed at zero.

PC Item list

The items that the player has stored in the PC.

Stored as an Item list with a capacity of 50.

Current PC Box

Indicates which PC box is currently selected, minus 1. That is to say, box 1 is represented as 0, and box 12 is represented as 11.

The highest bit of this value is not part of the box index. Its purpose is not yet known for certain, but it appears to be set when PC box data has been initialized.

The lowest 4 bits of this value are the box index.

Time played

Specifies how much time has elapsed during gameplay.

The first 2 bytes store the number of hours played in little-endian. The next 2 bytes store minutes and seconds in this order.

This timer is not halted when the game is paused, and also counts up on the main menu before selecting to continue a saved game.

Team Pokémon list

The Pokémon that the player has in his or her team.

Stored as a Pokemon list with a capacity of 6 and an entry size of 44 bytes.

PC Box Pokémon lists

The Pokémon that the player has stored in PC boxes.

This is stored as Pokemon lists with a capacity of 20 and an entry size of 33 bytes.

Normally, Pokémon are deposited and withdrawn from the Current Box list, which is within the checksum-validated region of the save data. When switching boxes, the data from the Current Box is copied to the corresponding PC Box data, then the data from the switched-to PC Box is transferred into the Current Box data.

Editor's Note: The curious operation of box switching indicates that originally, the PC only had a capacity for 20 Pokémon. The means by which the boxes function would have been easy to implement on top of that.

Checksum

Used to validate the integrity of saved data.

The checksum in Generation I is only 8 bits, and there is only one copy of the data protected by it. If this value is incorrect, the player will be forced to start a new game.

The algorithm used to calculate the checksum is as follows:

  • Initialize the checksum to 0
  • For every byte from 0x2598 to 0x3522, inclusive, add its value to the checksum
  • Invert the bits of the result

Alternately, you can start at 255 and subtract for each byte, meaning you won't have to perform the bit inversion at the end.

The checksum neatly validates all of the data starting at player name through the end of Current Box Pokémon list.


Data structure in the Pokémon games
Generation I Pokémon data structurePokémon base stats data structureSave data structure
Generation II Pokémon data structurePokémon base stats data structureTrainer data structureSave data structure
Generation III Pokémon data structurePokémon data substructuresPokémon base stats data structureMove data structure
Contest data structureContest move data structureItem data structurePokédex data structureBattle Frontier data structures
Trainer Tower data structuresPokémon evolution data structureType Chart data structureSave data structure
Generation IV Pokémon data structureSave data structure

Project Games logo.png This data structure article is part of Project Games, a Bulbapedia project that aims to write comprehensive articles on the Pokémon games.