-
Notifications
You must be signed in to change notification settings - Fork 0
Pokemon Generation 1 Save Files
The information on Bulbapedia, though not entirely correct, was very helpful in creating cgrr-pokemon and compiling this documentation.
All numbers are big-endian, unless otherwise specified.
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x0000 | unknown | bytes (9624) | |
0x2598 | player_name | str (11) | see below |
0x25A3 | pokedex_owned | bytes (19) | bitfield |
0x25B6 | pokedex_seen | bytes (19) | bitfield |
0x25C9 | pocket_item_list | bytes (42) | item list format |
0x25F3 | money | bytes (3) | binary coded decimal |
0x25F6 | rival_name | str (11) | |
0x2601 | options | byte (1) | bitfield |
0x2602 | badges | byte (1) | bitfield |
0x2603 | unknown | bytes (2) | |
0x2605 | player_trainer_id | Uint16 (2) | |
0x2607 | unknown | bytes (277) | |
0x271C | pikachu_friendship | Uint8 (1) | always 0x00 in Red/blue |
0x271D | unknown | bytes (201) | |
0x27E6 | pc_item_list | bytes (102) | |
0x284C | current_pc_box | Uint8 (1) | |
0x284D | unknown | bytes (3) | |
0x2850 | casino_coins | bytes (2) | binary coded decimal |
0x2852 | unknown | bytes (1179) | |
0x2CED | time_played (hour) | Uint16 (2) | little-endian |
0x2CEF | time_played (min) | Uint8 (1) | |
0x2CF0 | time_played (sec) | Uint8 (1) | |
0x2CF1 | unknown | bytes (571) | |
0x2F2C | team_pokemon | bytes (404) | pokemon list format (full) |
0x30C0 | current_box_pokemon | bytes (1122) | pokemon list format (brief) |
0x3522 | unknown | bytes (1) | |
0x3523 | checksum | Uint8 (1) | |
0x3524 | unknown | bytes (2780) | |
0x4000 | pc_box_1 | bytes (1122) | pokemon list format (brief) |
0x4462 | pc_box_2 | bytes (1122) | pokemon list format (brief) |
0x48C4 | pc_box_3 | bytes (1122) | pokemon list format (brief) |
0x4D26 | pc_box_4 | bytes (1122) | pokemon list format (brief) |
0x5188 | pc_box_5 | bytes (1122) | pokemon list format (brief) |
0x55EA | pc_box_6 | bytes (1122) | pokemon list format (brief) |
0x5A4C | unknown | bytes (1460) | |
0x6000 | pc_box_7 | bytes (1122) | pokemon list format (brief) |
0x6462 | pc_box_8 | bytes (1122) | pokemon list format (brief) |
0x6BC4 | pc_box_9 | bytes (1122) | pokemon list format (brief) |
0x6D26 | pc_box_10 | bytes (1122) | pokemon list format (brief) |
0x7188 | pc_box_11 | bytes (1122) | pokemon list format (brief) |
0x75EA | pc_box_12 | bytes (1122) | pokemon list format (brief) |
0x7A4C | unknown | bytes (1460) |
These are in a proprietary format. One byte can map to multiple displayed
characters, and there are a number of control characters, both printing and
non-printing. The mapping for US versions of Red/Blue/Yellow can be found in
encodings/pokemon_rby_us.py
. Other versions have different encodings. Briefly,
capital letters begin at 0x80 and lowercase letters at 0xA0, with punctuation in
between.
Strings may be up to the specified length. Strings shorter than the maximum length are terminated by 0x50.
Strings decoded by cgrr-pokemon have any characters that couldn't be mapped 1-1
to ordinary unicode characters replaced by codepoints from the PUA. The mapping
is Unicode(byte) = byte + 0xE000
.
Each bit in this region represents a boolean indicating whether the corresponding pokemon has been owned (or seen) by the player. The order is by National Pokedex number, with Pokemon #1 (Bulbasaur) appearing at bit offset 0.
Although there are 152 bits in this region, the last is not meaningful, as there are only 151 Pokemon in the game.
The overall format of item lists is:
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x00 | count | Uint8 (1) | |
0x01 | entries | bytes (2*count) |
| 0xFF | bytes (1) | terminates the item list
Each entry has the following format:
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x00 | index | Uint8 (1) | Item type index |
0x01 | count | Uint8 (1) |
Many possible indices do not correspond to items in the game.
Each BCD uses four bits per digit. Since 3 bytes are dedicated to money
, it
stores a 6-digit number. Similarly casino_coins
stores a 4-digit number. The
numbers are stored in display order, so bytes 0x12 0x34 0x56
correspond to
the number 123456
.
Call the MSB 0:
Bit | Meaning |
---|---|
0 | battle effects (0 for YES) |
1 | battle style (0 for 'SWITCH', 1 for 'SET') |
2 | sound (see below) |
3 | sound (see below) |
4 | |
5-7 | text speed (001 for 'FAST', 011 for 'NORMAL', 101 for 'SLOW') |
In Pokemon Red/Blue, only bit 3 is used for sound: 0 for 'MONO', 1 for 'STEREO'. In Pokemon Yellow, bits 2-3 are used: 00 for 'MONO', 01 for 'EARPHONE1', 10 for 'EARPHONE2', 11 for 'EARPHONE3'.
Each bit represents a badge, with 1 meaning that the badge has been acquired, and 0 meaning that it has not. Call the MSB 0:
Bit | Badge |
---|---|
0 | EARTH |
1 | VOLCANO |
2 | MARSH |
3 | SOUL |
4 | RAINBOW |
5 | THUNDER |
6 | CASCADE |
7 | BOULDER |
The currently-selected PC box. Zero-based, so if box 12 selected this is 11.
The overall format of full pokemon lists is:
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x000 | count | Uint8 (1) | |
0x001 | species | Uint8 (7) | |
0x008 | pokemon | bytes (264) | |
0x110 | ot_names | string (66) | six 11-byte strings concatenated |
0x152 | names | string (66) | six 11-byte strings concatenated |
Each of the first six bytes indicates a species index (not the same as National Pokedex number). Terminated by 0xFF.
These bytes contain six 44-byte entries for the Pokemon currently on the player's team. Format:
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x00 | species | Uint8 (1) | |
0x01 | current_hp | Uint16 (2) | |
0x03 | level_in_box | Uint8 (1) | |
0x04 | status_condition | bytes (1) | bitfield |
0x05 | type_1 | Uint8 (1) | |
0x06 | type_2 | Uint8 (1) | same as type_1 if pokemon has only 1 type |
0x07 | catch_rate | Uint8 (1) | used for held items in trades with gen 2 |
0x08 | move_1 | Uint8 (1) | |
0x09 | move_2 | Uint8 (1) | |
0x0A | move_3 | Uint8 (1) | |
0x0B | move_4 | Uint8 (1) | |
0x0C | original_trainer_id | Uint16 (2) | |
0x0E | experience_points | Uint24 (3) | yes, it's a 24-bit integer |
0x11 | hp_ev | Uint16 (2) | |
0x13 | attack_ev | Uint16 (2) | |
0x15 | defense_ev | Uint16 (2) | |
0x17 | speed_ev | Uint16 (2) | |
0x19 | special_ev | Uint16 (2) | |
0x1B | iv | Uint4 (2) | |
0x1D | move_1_pp | Uint8 (1) | |
0x1E | move_2_pp | Uint8 (1) | |
0x1F | move_3_pp | Uint8 (1) | |
0x20 | move_4_pp | Uint8 (1) | |
0x21 | level | Uint8 (1) | |
0x22 | maximum_hp | Uint16 (2) | |
0x24 | attack | Uint16 (2) | |
0x26 | defense | Uint16 (2) | |
0x28 | speed | Uint16 (2) | |
0x2A | special | Uint16 (2) |
Values from 0x21 on are derived values, recalculated when a pokemon is removed from a box. Because of this, only the first 33 bytes are stored when a pokemon is placed in a box.
Species index, not National Pokedex number.
Set when a pokemon is stored in a box.
Bitfield. Do a bitwise AND of status_condition and the values below to determine which statuses a pokemon suffers from:
value | condition |
---|---|
0x04 | asleep |
0x08 | poisoned |
0x10 | burned |
0x20 | frozen |
0x40 | paralyzed |
See the enum PokemonType in common.py
for the types corresponding to these
values. If a pokemon has only a single type, type_2
is set to the same value
as type_1
.
The catch rate of the pokemon, though I don't know why this is stored here. This value is used to store held items on pokemon traded from Gold/Silver/Crystal, so the item will still be there if the pokemon is traded back. This also means that pokemon traded to G/S/C will be holding an item depending on the catch rate of the R/B/Y pokemon.
Index numbers of moves. See the enum Move in common.py
for the values.
These two bytes represent four 4-bit integers that store the IVs for a pokemon: attack, defense, speed, special.
The names of the original trainers and the names of the pokemon, stored as six 11-byte strings, concatenated. Each string may be up to 11 characters, and is otherwise terminated by 0x50, as usual.
A pokemon list, like team_pokemon
, but with a briefer format that doesn't
store calculated data:
Offset | Name | Type (len) | Notes |
---|---|---|---|
0x000 | count | Uint8 (1) | |
0x001 | species | Uint8 (21) | |
0x016 | pokemon | bytes (660) | |
0x2AA | ot_names | str (220) | twenty 11-byte strings concatenated |
0x386 | names | str (220) | twenty 11-byte strings concatenated |
Twenty pokemon stored in the same format as those in team_pokemon
, but ending
after byte 0x20.
An 8-bit checksum of the data from 0x2598-0x3522, inclusive.
checksum = (255 - sum(savedata[0x2598:0x3523])) & 255