Skip to content

Save Format

Niema Moshiri edited this page Jul 21, 2019 · 71 revisions

The save slots in Final Fantasy VII save files have identical structure between various platforms, but the save file headers/footers and number of save slots per file differ between platforms. This wiki and Black Chocobo are excellent resources for learning more about Final Fantasy VII save files.

Section 1: File Header

The save file begins with a file header. The format of this header differs between the game platforms (see Version/Format Differences).

Section 2: Save Slot(s)

After the header, the save file contains the save slot(s). Note that the PlayStation and PlayStation Vita formats only have a single save slot, whereas all others explored in this write-up have 15.

Save Slot Header

With the exception of the PC version of Final Fantasy VII, all save slots start with a 512 byte header, the contents of which I don't know. The PC version has no save slot headers.

Save Slot Data

All versions of Final Fantasy VII store the core save slot data in the same format, and it is always exactly 4,340 bytes in size. All of the following offsets are given such that 0x0000 denotes the start of the Save Slot Data.

Offset (bytes) Size (bytes) Description
0x0000 4 Checksum
0x0004 1 Preview: Lead Character's Level
0x0005 1 Preview: Party Portrait 1
0x0006 1 Preview: Party Portrait 2
0x0007 1 Preview: Party Portrait 3
0x0008 16 Preview: Lead Character's Name
0x0018 2 Preview: Lead Character's Current HP
0x001A 2 Preview: Lead Character's Maximum HP
0x001C 2 Preview: Lead Character's Current MP
0x001E 2 Preview: Lead Character's Maximum MP
0x0020 4 Preview: Total Gil
0x0024 4 Preview: Total Playtime (seconds)
0x0028 32 Preview: Save Location
0x0048 3 RGB Color of Upper-Left Corner of Window
0x004B 3 RGB Color of Upper-Right Corner of Window
0x004E 3 RGB Color of Lower-Left Corner of Window
0x0051 3 RGB Color of Lower_Right Corner of Window
0x0054 132 Character Record: Cloud
0x00D8 132 Character Record: Barret
0x015C 132 Character Record: Tifa
0x01E0 132 Character Record: Aerith
0x0264 132 Character Record: Red XIII
0x02E8 132 Character Record: Yuffie
0x036C 132 Character Record: Cait Sith
0x03F0 132 Character Record: Vincent
0x0474 132 Character Record: Cid
0x04F8 1 Party Portrait 1
0x04F9 1 Party Portrait 2
0x04FA 1 Party Portrait 3
0x04FB 1 Blank 1 (0xFF)
0x04FC 640 Item Stock (2 bytes/slot, 320 slots)
0x077C 800 Materia Stock (4 bytes/slot, 200 slots)
0x0A9C 192 Materia Stolen by Yuffie (4 bytes/slot, 48 slots)
0x0A9C 32 Unknown 4 (all 0xFF?)
0x0B7C 4 Total Gil
0x0B80 4 Total Playtime (seconds)
0x0B84 4 Countdown (seconds)
0x0B88 4 Total Playtime Seconds Fraction (1/65535 seconds)
0x0B8C 4 Countdown Seconds Fraction (1/65535 seconds)
0x0B90 6 Current Module (0x000000000100: Field, 0x020000000300: World Map)
0x0B96 2 Current Location
0x0B98 2 Blank 2 (0xFFFF)
0x0B9A 2 Map Location: X-Coordinate (signed)
0x0B9C 2 Map Location: Y-Coordinate (signed)
0x0B9E 2 Map Location: Triangle ID
0x0BA0 1 Direction of Player Model on Map
0x0BA1 1 Encounter Timer: Step ID / Seed
0x0BA2 1 Encounter Timer: Offset
0x0BA3 1 Blank 3 (0x00)
0x0BA4 2 Plot Progression Variable
0x0BA6 1 Yuffie's Initial Level (must be 0 before she joins the party)
0x0BA7 1 Love Points: Aerith
0x0BA8 1 Love Points: Tifa
0x0BA9 1 Love Points: Yuffie
0x0BAA 1 Love Points: Barret
0x0BAB 1 Temporary Party Placeholder: Character 1
0x0BAC 1 Temporary Party Placeholder: Character 2
0x0BAD 1 Temporary Party Placeholder: Character 3
0x0BAE 6 Unknown 9 (all 0x00?)
0x0BB4 1 Game Timer: Hours (0-255)
0x0BB5 1 Game Timer: Minutes (0-60)
0x0BB6 1 Game Timer: Seconds (0-60)
0x0BB7 1 Game Timer: Frames (0-30)
0x0BB8 1 Countdown Timer: Hours (0-255)
0x0BB9 1 Countdown Timer: Minutes (0-60)
0x0BBA 1 Countdown Timer: Seconds (0-60)
0x0BBB 1 Countdown Timer: Frames (0-30)
0x0BBC 2 Number of Battles
0x0BBE 2 Number of Escapes
0x0BC0 2 Visible Menu Items
0x0BC2 2 Locked Menu Items
0x0BC4 4 Unknown 10 (always 0x00?)
0x0BC8 1 Field Items 1
0x0BC9 1 Field Items 2
0x0BCA 10 Unknown 11 (all 0x00?)
0x0BD4 1 Field Items 3
0x0BD5 1 Field Items 4
0x0BD6 14 Unknown 12
TODO TODO TODO

Note: "Preview" Items

Note that items starting with "Preview:" are purely cosmetic (they appear in the preview in the save menu), and only changing these will not impact the game.

Computing the Checksum

Recall that the first 4 bytes of a save slot are the checksum. The checksum is computed as follows, where slot_data is the raw bytes of a save slot, excluding the checksum (i.e., excluding the aforementioned first 4 bytes). I learned this algorithm from the code in this forum post by dziugo.

def checksum(slot_data):
    r = 0xFFFF
    pbit = 0x8000
    for t in slot_data:
        r ^= (t << 8)
        for _ in range(8):
            if r & pbit:
                r = (r << 1) ^ 0x1021
            else:
                r <<= 1
        r &= 0xFFFF
    return (r ^ 0xFFFF) & 0xFFFF

To fix the checksums of every save slot in a Final Fantasy VII save file, you can use this tool, which was originally written by dziugo and was updated by me.

Character Record Data

Every character has a character record in the following format, and it is always exactly 132 bytes in size. All of the following offsets are given such that 0x00 denotes the start of the character record.

Offset (bytes) Size (bytes) Description
0x00 1 Vincent → Sephiroth Flag
0x01 1 Level (0-99)
0x02 1 Strength (0-255)
0x03 1 Vitality (0-255)
0x04 1 Magic (0-255)
0x05 1 Spirit (0-255)
0x06 1 Dexterity (0-255)
0x07 1 Luck (0-255)
0x08 1 Strength Bonus (from Power Source)
0x09 1 Vitality Bonus (from Guard Source)
0x0A 1 Magic Bonus (from Magic Source)
0x0B 1 Spirit Bonus (from Mind Source)
0x0C 1 Dexterity Bonus (from Speed Source)
0x0D 1 Luck Bonus (from Luck Source)
0x0E 1 Current Limit Level (1-4)
0x0F 1 Limit Bar (0 = empty, 255 = Limit Break)
0x10 12 Character Name
0x1C 1 Equipped Weapon
0x1D 1 Equipped Armor
0x1E 1 Equipped Accessory
0x1F 1 Character Flags (0x10: Sadness, 0x20: Fury)
0x20 1 Character Order (0xFF: Normal, 0xFE: Back)
0x21 1 Level Progress (0-63; <4 hidden by game GUI)
0x22 2 Learned Limit Skills
0x24 2 Number of Kills
0x26 2 Number of Limit 1-1 Uses
0x28 2 Number of Limit 2-1 Uses
0x2A 2 Number of Limit 3-1 Uses
0x2C 2 Current HP
0x2E 2 Base HP (before materia)
0x30 2 Current MP
0x32 2 Base MP (before materia)
0x34 4 Unknown 2
0x38 2 Maximum HP (after materia)
0x3A 2 Maximum HP (after materia)
0x3C 4 Current Experience
0x40 32 Weapon Materia (4 bytes/slot, 8 slots)
0x60 32 Armor Materia (4 bytes/slot, 8 slots)
0x80 4 Experience Until Next Level

Learned Limit Skills

The learned limit skills are stored in 16 bits (i.e., 2 bytes) in the following format:

 MSB                                                                        LSB
[ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][4-1][ 0 ][3-2][3-1][ 0 ][2-2][2-1][ 0 ][1-2][1-1]
  • MSB = Most Significant Bit
  • LSB = Least Significant Bit
  • [A-B] = Limit A-B (i.e., the B-th limit in level A)
    • For example, [3-1] denotes Limit 3-1: the first limit in Limit Level 3
    • 1 = learned, 0 = not learned
  • [ 0 ] = 0 bit

Item Stock

Each record in the Item Stock has 2 bytes, and there are 320 item slots, so the Item Stock is 640 bytes total. For each item record, the first byte denotes the item ID, and the second byte denotes the item quantity. However, because there are more than 256 items in the game (there are 319, excluding key items), some items share the same ID byte, and the quantity byte is leveraged to identify which of the two possible items it is.

For ID bytes between 0x00 and 0x3F, if the quantity byte is even, the slot contains the "even item" corresponding to that ID byte, and if the quantity byte is odd, the slot contains the "odd item" corresponding to that ID byte. The actual quantity of the item is the quantity byte divided by 2 (ignore remainder). For ID bytes larger than 0x3F, the approach is the same, but only "even items" exist.

For example, for the ID byte 0x03, the "even item" is Ether, and the "odd item" is Mythril Armlet. Thus, if the 2-byte item slot is 0x03 0x07, the quantity byte (7) is odd, meaning we have the "odd item" (Mythril Armlet), and the actual quantity is floor(7/2) = 3. Thus, 0x03 0x07 means we have 3 Mythril Armlets.

A database of Final Fantasy VII items can be found in PyFF7.

Materia Stock

Each record in the Materia Stock has 4 bytes, and there are 200 materia slots, so the Materia Stock is 800 bytes total. For each materia record, the first byte denotes the materia ID, and the remaining 3 bytes are an unsigned integer representing the materia's AP. A database of Final Fantasy VII materia can be found in PyFF7.

Menu Items

At various points in the game, menu items can be (in)visible or (un)locked. Specifically, the Materia and PHS menu items are invisible at the beginning of the game (Materia is made visible first, followed later by PHS), and at parts of the game in which you can't switch characters, the PHS menu item is visible but is locked. For the Visible Menu Items bytes, 1 = visible and 0 = invisible. For the Locked Menu Items bytes, 1 = locked and 0 = unlocked. The order of the bits is as follows (for both Visible Menu Items and Locked Menu Items):

 MSB                                                                                            LSB
[ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][Save][PHS][Config][Limit][Order][Status][Equip][Materia][Magic][Item]
  • MSB = Most Significant Bit
  • LSB = Least Significant Bit
  • [ 0 ] = 0 bit

Field Items

The field items flags for any location are a single byte, where each bit represents a specific item that can be found. A bit value of 1 means the item has been picked up, and a bit value of 0 means it has not been picked up. This is the format for all field items bytes:

 MSB                                LSB
[ H ][ G ][ F ][ E ][ D ][ C ][ B ][ A ]
  • MSB = Most Significant Bit
  • LSB = Least Significant Bit

Field Items 1

  • This seems to be the Train Graveyard
  • [ A ] = Hi-Potion (mds7st1 / Barrel 1)
  • [ B ] = Echo Screen (mds7st1 / Barrel 2)
  • [ C ] = Potion (mds7st2 / Floor 2)
  • [ D ] = Ether (mds7st2 / Floor 3)
  • [ E ] = Hi-Potion (mds7st1 / Roof Train 1)
  • [ F ] = Potion (mds7st1 / Inside Train 2)
  • [ G ] = Potion (mds7st1 / Floor 1)
  • [ H ] = Hi-Potion (mds7st2 / Roof Train 2)

Field Items 2

  • This seems to be the Great Glacier
  • [ A ] = Elixir (hyou8_2/tr00/s1)
  • [ B ] = Potion (hyou5_1/tr00/s1)
  • [ C ] = Safety Bit (hyou5_3/trbox/s1)
  • [ D ] = Mind Source (hyou2/trbox/s1)
  • [ E ] = Sneak Glove (mkt_w/event/s1)
  • [ F ] = Premium Heart (mkt_ia/event/s3, mkt_ia/line00/s4)
  • [ G ] = 0x00 (None)
  • [ H ] = 0x00 (None)

Field Items 3

  • This seems to include Aerith's home, the farm, and parts of the Midgar slums
  • [ A ] = Potion (md8_3/p/s1)
  • [ B ] = Potion + Phoenix Down (ealin_2/zu/s1)
  • [ C ] = Ether (eals_1/p/s1)
  • [ D ] = Cover Materia (eals_1/mp/s1)
  • [ E ] = Choco-Mog Summon (farm/dancer/s1)
  • [ F ] = Sense Materia (mds6_22/mat/s1)
  • [ G ] = Ramuh Summon (crcin_2/mat/s1)
  • [ H ] = Mythril Key Item (zz1/m1/s1)

Field Items 4

  • This seems to be the Materia Cave and Northern Cave
  • [ A ] = Mime Materia (zz5/l1,l2,l3,l4/s1)
  • [ B ] = HP<->MP Materia (zz6/mat/s1)
  • [ C ] = Quadra Magic Materia (zz7/l1,l2,l3,l4/s1)
  • [ D ] = Knights of the Round Summon (zz8/l1,l2,l3,l4/s1)
  • [ E ] = Elixir (las3_1/hako1/s1, las4_0/cid/s1)
  • [ F ] = X-Potion (las3_1/hako2/s1)
  • [ G ] = Turbo Ether (las3_2/hako1/s1, las4_0/tifa/s1, las4_0/cait/s1)
  • [ H ] = Vaccine (las3_2/hako2/s1, las4_0/yufi/s1)

Save Slot Footer

With the exception of the PC version of Final Fantasy VII, all save slots end with a 3,340 byte footer, the contents of which I don't know. The PC version has no save slot footers.

Version/Format Differences

Format File (bytes) Header (bytes) Slots Slot Header (bytes) Slot Footer (bytes)
DEX 134,976 12,096 15 512 3,340
Mem Card 131,072 8,192 15 512 3,340
PC Version 65,109 9 15 0 0
PSP Version 131,200 8,320 15 512 3,340
PSV Version 8,324 132 1 512 3,340
PSX Version 8,192 0 1 512 3,340
VGM Version 131,136 8,256 15 512 3,340

Summary

  • File Header
  • Save Slot(s)
    • Save Slot 1
      • 0 or 512 bytes (Save Slot Header)
      • 4,340 bytes (Save Slot Data)
        • TODO
      • 0 or 3,340 bytes (Save Slot Footer)
    • ...