Saves (GTA SA)
Contents
- 1 Introduction
- 2 Location and Format Overview
- 3 Format Details
- 3.1 Data Blocks
- 3.1.1 Block 0: Miscellaneous
- 3.1.2 Block 1: Script
- 3.1.3 Block 2: Objects
- 3.1.4 Block 3: Garages
- 3.1.5 Block 4: (Unknown)
- 3.1.6 Block 5: Disabled Pathnode Cubes
- 3.1.7 Block 6: Pickups
- 3.1.8 Block 7: (Unknown)
- 3.1.9 Block 8: Restart Locations
- 3.1.10 Block 9: Radar Blips
- 3.1.11 Block 10: Zones
- 3.1.12 Block 11: (Unknown)
- 3.1.13 Block 12: Car Generators
- 3.1.14 Block 13: (Unknown)
- 3.1.15 Block 14: (Unknown)
- 3.1.16 Block 15: (Unknown)
- 3.1.17 Block 16: Player Stats
- 3.1.18 Block 17: (Unknown)
- 3.1.19 Block 18: (Unknown)
- 3.1.20 Block 19: (Unknown)
- 3.1.21 Block 20: (Unknown)
- 3.1.22 Block 21: (Unknown)
- 3.1.23 Block 22: (Unknown)
- 3.1.24 Block 23: (Unknown)
- 3.1.25 Block 24: (Unknown)
- 3.1.26 Block 25: ENEX Connections
- 3.1.27 Block 26: (Unknown)
- 3.1.28 Block 27: (Unknown)
- 3.2 Padding
- 3.3 Checksum
- 3.1 Data Blocks
Introduction
This article deals with the format of a saved game file for Grand Theft Auto: San Andreas (GTASA). It is specifically geared towards the PC version(s) but much of it may be applicable to console versions too.
Location and Format Overview
By default, GTASA places its saved game files into the folder "GTA San Andreas User Files" which is located in the current user's Documents folder. The location of this folder varies depending upon the version of Windows installed. Some typical locations for a user with an account named "Fred" would be:
- C:\My Documents\GTA San Andreas User Files -- Windows 98 Example
- C:\Documents and Settings\Fred\My Documents\GTA San Andreas User Files -- Windows XP Example
- C:\Users\Fred\Documents\GTA San Andreas User Files -- Windows Vista Example
Obviously those locations can vary based upon different Windows configurations or installation options. Note also that the executable can be modified to use a different file location through the use of a hex editor and special registry key in a process outlined at GTAForums
The save files themselves are named in the format GTASAsfX.b where X represents the in-game slot number. So, the game saved in slot 1 will be stored in the save file GTASAsf1.b and the game saved in slot 5 will be stored in the save file GTASAsf5.b. There are 8 slots available in the game (1-8). GTASA save files are always 0x31800 bytes long (202,752 in decimal) and are not compressed or encoded in any way.
Format Details
A GTASA save file consists of 28 "blocks" of data followed by some duplicated data for padding and then ending with a checksum value. Each of these elements is described below.
Data Blocks
Each data block consists of the 5 characters BLOCK followed by a variable amount of data; in general, each block has its own unique internal format. The format descriptions in this article only deal with those internal block formats which follow the initial BLOCK identifier and all offsets start at the byte following the BLOCK identifier for the given block.
Block 0: Miscellaneous
Game "meta-information" giving the overall state of things. This block has a constant length of 0x138 bytes
OFFSET TYPE DESCRIPTION 0x000 dword Version ID String (Checksum of a string describing the time of compilation. See note 1 below) 0x004 char[100] Save Name String (Long names are truncated on the save/load screen. See note 2 below) 0x068 byte Current Missionpack 0x069 byte[7] (Unknown) 0x070 float[3] Camera Coordinates (x,y,z) 0x07C dword Length (ms) of in-game minute 0x080 dword Weather Timer 0x084 byte[2] (Unknown) 0x086 byte Game Hour 0x087 byte Game Minute 0x088 byte[12] (Unknown) 0x094 dword Global Timer 0x098 float Game Speed 0x09C byte[32] (Unknown) 0x0BC dword Current Camera View 0x0C0 byte[36] (Unknown) 0x0E4 dword Max Wanted Level 0x0E8 dword Possible Police Aggression Level 0x0EC byte[50] (Unknown) 0x11E word SYSTEMTIME year 0x120 word SYSTEMTIME month 0x122 word SYSTEMTIME wkday 0x124 word SYSTEMTIME day 0x126 word SYSTEMTIME hour 0x128 word SYSTEMTIME min 0x12A word SYSTEMTIME sec 0x12C word SYSTEMTIME ms 0x12E byte[10] (Unknown)
Notes:
- Version 2.0 of GTASA will not load a save file if the Version ID String does not match its own Version ID String. Thus if a game was played on a version 1.x exe using the exact same set of mission scripts as a version 2.0 installation, the version 2.0 game will refuse to load the save unless this ID is changed. Version 1.x exes make no Version ID String check and will attempt to load any non-corrupted save. Some known Version ID String values (listed as consecutive bytes):
- 0x75 0x81 0xDA 0x35 -- Version 1.00 Unmodified EXE
- 0x83 0xE5 0xF3 0x65 -- Version 1.00 Modified EXE
- 0x58 0xBE 0x6E 0x9A -- Version 1.01 Unmodified EXE
- 0x5E 0x76 0x45 0x93 -- Version 1.01 Modified EXE
- 0xF6 0x8D 0x14 0xFD -- Version 2.00 Unmodified EXE
- While the save name can be changed here to pretty much anything that name will not persist the next time the game is saved, even if no missions were completed during that play session; at each save this name string is reset based upon the Last Mission Passed GXT key stored in Block 15.
Block 1: Script
---- global vars: 0 dword size of global var space 4 global var space ---- misc info from various opcodes and such: 0 unknown 902 end ---- threads: 0 dword number of threads ?? word + other info ?? 4 threads Thread structure: 0 word index/handle 2 end ---- memory dump: 0 dword next pointer 4 dword prev pointer 8 char[8] name 10 dword absolute base address 14 dword absolute ip 18 dword[8] return stack 38 word stack pointer 3c dword[32] local vars bc dword[2] local timers c4 byte c5 byte if result c6 byte c7 byte is extern c8 byte c9 byte cc dword wakeup time d0 word if parameter d2 byte not flag d3 byte wb check flag d4 byte d8 dword new script ip (0 if absolute ip has been calculated from this) dc byte is mission e0 end ---- the absolute addresses depend on memory layout, so the savegame also contains relative addresses: 0 dword relative ip 4 dword[8] relative return stack 24 end
Block 2: Objects
0 unknown bytes 228 end ---- objects 0 dword object count 4 objects Object structure: 4 dword model c float[3] coords 3c end
Block 3: Garages
0 dword garage count 27 GrgCar[20][4] car entries 1427 garages
GrgCar structure: 0 float[3] coords 12 word model 40 end
Garage structure: 0 byte type 4 float[3] coords 10 float[4] rotation 20 float[3] top z, width, depth 2c float[4] 3c float[2] 44 char[8] name 4c word original type ? 50 end
Block 4: (Unknown)
0 dword count b entries (16-byte structures)
Block 5: Disabled Pathnode Cubes
0 dword count 4 entries Entry structure: 0 float[6] x1,x2,y1,y2,z1,z2 18 byte[4] bools that somehow indicate which pathtypes are enabled 1c end
Block 6: Pickups
0 Pickup[620] pickups 4d80 word 4d82 byte 4d83 dword[20] 4dd3 end
Pickup structure: 8 dword ammo 10 word[3] x,y,z, all multiplied by 8 18 word model 1c byte type 20 end
Block 7: (Unknown)
(Usually empty)
Block 8: Restart Locations
---- wasted: 0 word count 2 restart structures ---- busted: 0 word count 2 restart structures ---- unknown things: 0 some bytes, floats, and dwords 37 end Restart structure: 0 float[3] coords c float heading 10 dword island 14 end
Block 9: Radar Blips
0 Blip[175] blips
Blip structure: 8 float[3] coords 28 end
Block 10: Zones
4 word count for first array 6 word count for second array 8 word count for third array a end ---- the three arrays: See structure descriptions below. First = info.zon, third = map.zon. ---- unknown: 68 end
First and third array structure: 0 char[8] zone name 8 char[8] zone group name 10 word[6] x1,y1,z1,x2,y2,z2 (rounded to ints) 1c word id 1e byte type 1f byte island 20 end Second array structure: 11 end
Block 11: (Unknown)
0 dword[4][10] a0 end
Block 12: Car Generators
0 dword count 6 car generators ---- numberplates: 0 dword num entries used 4 Numplate[15] number plates f4 end
Car generator structure: 0 word handle (0..499) 2 word model 4 byte[2] colors 6 word[3] x,y,z, all multiplied by 8 c byte heading/360*256 d byte alarm chance e byte locked chance f byte flags: bit 1 = belongs to player 12 word monetary value 16 dword timer 1c word cars to generate 22 end Numplate structure: 0 dword car generator handle 4 char[8] numberplate string 10 end
Block 13: (Unknown)
(Usually Empty)
Block 14: (Unknown)
(Usually Empty)
Block 15: (Unknown)
0 dword size of block (always 28h) 4 some dwords, floats and bytes from the player structure 2c end
Block 16: Player Stats
0 float[82] float stats (numbered 0..81 in scm) 148 dword[223] int stats (numbered 120..342 in scm) 4c4 dword[32] 544 char[8] last mission passed (gxt key) 54c byte[56] 584 dword[100] 714 byte[128] 794 end
Block 17: (Unknown)
0 dword entries used 4 byte[32][210] entries 1a44 end
Block 18: (Unknown)
66cc end
Block 19: (Unknown)
280 end
Block 20: (Unknown)
0 dword size 4 bytes
Block 21: (Unknown)
0 dword 4 byte[255] 103 end
Block 22: (Unknown)
0 dword count 4 entries (8 bytes each) ---- 0 dword size 4 bytes
Block 23: (Unknown)
0 dword size of block (always 58h) 5c end
Block 24: (Unknown)
0 dword count 4 entries (68 bytes each)
Block 25: ENEX Connections
0 dword count 4 array of words ---- Followed by a weird array: 1. Read a word. 2. If it is -1, you've reached the end of this block. 3. Otherwise, it's an index. Read two more words for this entry and go back to 1.
Block 26: (Unknown)
0 Structure[14] ee0 byte[28] efc end
Structure: 0 byte[20] 14 dword[8] 34 dword[40] d4 dword[15] 110 end
Block 27: (Unknown)
0 byte[28][5] structures from opcode 0a40 8c end
Padding
Following the last data block is a variable amount of padding. Since every save file is exactly 0x31800 bytes in length this padding is necessary to fill the space between the data blocks which start the file and the checksum value which ends it. Because GTASA internally uses a buffer of 0xC800 bytes for writing a save, each byte of padding data is simply a repetition of the data located 0xC800 bytes before it. While it is not strictly necessary to follow this convention for the padding when writing a modified save file, it is consistent with the original game and makes modifications harder to detect.
Checksum
The final four bytes of a save file are an unsigned integer checksum value. This checksum is simply the sum of all the preceding 0x317FC bytes. If the checksum value does not match the calculated sum of those bytes, the game will consider the save file to be "corrupted" and refuse to load it. Thus, any time you make any changes to a save file you must remember to update the checksum when you are finished.