Difference between revisions of "Saves (GTA 4)"
m (wchar_t takes 2 bytes, 128*2=256) |
(→Block 9: Radar: adding version difference note (I didn't want to duplicate the whole table)) |
||
(49 intermediate revisions by 7 users not shown) | |||
Line 4: | Line 4: | ||
==Location== | ==Location== | ||
− | |||
− | The save files themselves are named in the format | + | ===1.0.8.0 IV / 1.1.3.0 EFLC and older=== |
+ | By default, the game places its save game files into the "%LocalAppData%\Rockstar Games\GTA IV\savegames\user_XXXXXXXXXXXXXXXX\" folder where XXXXXXXXXXXXXXXX is a 16-character string tied to the user's Games for Windows Live account.<br> | ||
+ | Players using Xliveless or downgrade patches may find the save files in "%HomePath%\Documents\Rockstar Games\XXXX\savegames\" folder where XXXX is either "GTA IV" (base game), "TLAD", or "TBoGT". | ||
+ | |||
+ | ===1.2.x CE and newer=== | ||
+ | Save files for the Complete Edition can be found in "%HomePath%\Documents\Rockstar Games\GTA IV\Profiles\XXXXXXXX\" where XXXXXXXX is a 8-character string tied to the user's Rockstar Social Club account. | ||
+ | |||
+ | ===Save Slots=== | ||
+ | The save files themselves are named in the format "SGTA4XX" where XX represents the in-game slot number minus 1. There are 12 slots available in the game (1-12) plus additional auto-save slots (SGTA412 for the base game, SGTA413 for TLAD, and SGTA414 for TBoGT). | ||
==Format Details== | ==Format Details== | ||
* Save file size varies but is typically just under 2 megabytes. | * Save file size varies but is typically just under 2 megabytes. | ||
* Byte order is little endian. For example, the number 3452 (0x0D7C) is represented as as 0x7C 0x0D. | * Byte order is little endian. For example, the number 3452 (0x0D7C) is represented as as 0x7C 0x0D. | ||
+ | * A savegame consists of 32 [[#Data Blocks|data blocks]], two blocks with metadata and a checksum number. | ||
− | === | + | ====Savegame Metadata==== |
− | + | A savegame file starts with this block, which has a constant length of 0x110 bytes. | |
− | |||
− | |||
− | |||
{|class="wikitable" | {|class="wikitable" | ||
!OFFSET | !OFFSET | ||
Line 22: | Line 27: | ||
!DESCRIPTION | !DESCRIPTION | ||
|- | |- | ||
− | |0x00 || | + | |0x00 ||dword ||savegame version number |
+ | |- | ||
+ | |0x04 ||dword ||savegame size in bytes | ||
+ | |- | ||
+ | |0x08 ||dword ||global variables size (?) | ||
|- | |- | ||
− | |0x0C ||char[4] ||"SAVE" | + | |0x0C ||char[4] ||"SAVE" string |
|- | |- | ||
|0x10 ||wchar_t[128] ||Name of last mission passed | |0x10 ||wchar_t[128] ||Name of last mission passed | ||
Line 30: | Line 39: | ||
|0x110 ||end || | |0x110 ||end || | ||
|} | |} | ||
− | |||
− | |||
− | ====Block | + | Notes: |
− | + | * Savegame version number value is set under the [SAVEGAME_VERSION_NUMBER] section in the GTA IV/common/data/version.txt file | |
+ | * Last mission name is prefixed with either "TLAD - " or "TBoGT - " for Episodes From Liberty City saves | ||
+ | |||
+ | ===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. Following the '''BLOCK''' character is always a dword specifying the size of the block, starting at the beginning of '''BLOCK''' characters. | ||
+ | |||
+ | ==== Block 0: SimpleVars ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | |0x00 ||char[5] ||a "BLOCK" string | ||
+ | |- | ||
+ | |0x05 ||dword ||size of block in bytes (always 0xB9) | ||
+ | |- | ||
+ | |0x09 ||dword ||start of data; see below | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
{|class="wikitable" | {|class="wikitable" | ||
+ | |+SimpleVars | ||
!OFFSET | !OFFSET | ||
!TYPE | !TYPE | ||
!DESCRIPTION | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || closest safehouse index |
+ | |- | ||
+ | | 0x0004 || bool || fade in after load | ||
+ | |- | ||
+ | | 0x0010 || Vector4 || camera coordinates (x, y, z, w) | ||
+ | |- | ||
+ | | 0x0020 || uint32 || length of ingame timer (ms) | ||
+ | |- | ||
+ | | 0x0024 || uint32 || weather timer (?) | ||
+ | |- | ||
+ | | 0x0028 || uint32 || in-game month | ||
+ | |- | ||
+ | | 0x002c || uint32 || in-game day | ||
+ | |- | ||
+ | | 0x0030 || uint32 || in-game hours | ||
+ | |- | ||
+ | | 0x0034 || uint32 || in-game minutes | ||
+ | |- | ||
+ | | 0x0038 || uint32 || in-game day of the week | ||
+ | |- | ||
+ | | 0x003c || bool || whether the player has cheated | ||
+ | |- | ||
+ | | 0x0040 || uint32 || game timer | ||
+ | |- | ||
+ | | 0x0044 || uint32 || frame count | ||
+ | |- | ||
+ | | 0x0048 || uint32 || weather 2 | ||
+ | |- | ||
+ | | 0x004c || uint32 || weather 1 | ||
+ | |- | ||
+ | | 0x0050 || uint32 || forced weather | ||
+ | |- | ||
+ | | 0x0054 || uint32 || game hour fraction | ||
+ | |- | ||
+ | | 0x0060 || int || vehicle camera mode | ||
|- | |- | ||
− | | | + | | 0x0064 || int || ped camera mode |
|- | |- | ||
− | | | + | | 0x0068 || int || don't zoom on aim |
|- | |- | ||
− | | | + | | 0x0080 || int || max wanted level |
|- | |- | ||
− | | | + | | 0x0084 || uint32 || max chaos level |
|- | |- | ||
− | | | + | | 0x0094 || uint32_t || waypoint blip |
|- | |- | ||
− | | | + | |0xB0 ||end || |
|} | |} | ||
+ | </div> | ||
+ | |||
+ | ==== Block 1: PlayerInfo ==== | ||
+ | |||
+ | This block has a constant length of 0xD4 bytes. | ||
− | |||
− | |||
{|class="wikitable" | {|class="wikitable" | ||
!OFFSET | !OFFSET | ||
Line 62: | Line 127: | ||
!DESCRIPTION | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || size of block |
|- | |- | ||
− | | | + | | 0x0004 || float[3] || player coordinates |
|- | |- | ||
− | | | + | | 0x0010 || uint32 || constant 192 (size of PlayerInfo) |
|- | |- | ||
− | | | + | | 0x0014 || PlayerInfo || player info |
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+PlayerInfo (192 bytes) | ||
|- | |- | ||
− | | | + | | 0x0008 || uint32 || player money |
|- | |- | ||
− | | | + | | 0x0010 || uint32 || player display money |
|- | |- | ||
− | | | + | | 0x0020 || uint8 || never tired |
|- | |- | ||
− | | | + | | 0x0021 || uint8 || fast reload |
|- | |- | ||
− | | | + | | 0x0022 || uint8 || fire proof |
|- | |- | ||
− | | | + | | 0x0024 || uint16 || max health |
|- | |- | ||
− | | | + | | 0x0026 || uint16 || max armour |
|- | |- | ||
− | | | + | | 0x0028 || uint8 || keep weapons after busted |
|- | |- | ||
− | | | + | | 0x0029 || uint8 || free health care |
|- | |- | ||
− | | | + | | 0x002a || uint8 || can drive by |
|- | |- | ||
− | | | + | | 0x002b || uint8 || can be hassled by gangs |
|- | |- | ||
− | | | + | | 0x0030 || uint32 || max wanted level |
|- | |- | ||
− | | | + | | 0x0034 || uint32 || max chaos |
|- | |- | ||
− | | | + | | 0x0040 || float[4] || player coordinates (x,y,z,w) |
|- | |- | ||
− | | | + | | 0x0050 || float || health |
|- | |- | ||
− | | | + | | 0x0054 || float || armour |
|- | |- | ||
− | | | + | | 0x0058 || uint32 || (current weapon slot?) |
|- | |- | ||
− | | | + | | 0x005c || uint32[10] || weapon slots |
|- | |- | ||
− | | | + | | 0x0084 || uint16[10] || weapons ammo |
|- | |- | ||
− | | | + | | 0x00a4 || uint32 || [[SET_CHAR_PROP_INDEX|prop variation]] |
|- | |- | ||
− | | | + | | 0x00a8 || uint8[11] || [[GET_CHAR_DRAWABLE_VARIATION|drawable variation]] |
|- | |- | ||
− | | | + | | 0x00b3 || uint8[11] || [[GET_CHAR_TEXTURE_VARIATION|texture variation]] |
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Block 2: ExtraContent ==== | ||
+ | |||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || block size |
|- | |- | ||
− | | | + | | 0x0004 || uint64 || flags (bit set for the active episode(s)) |
|- | |- | ||
− | | | + | | 0x000C || Episode[64] || episodes array |
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+Episode (65 bytes) | ||
|- | |- | ||
− | | | + | | 0x0000 || uint8 || episode id |
|- | |- | ||
− | | | + | | 0x0001 || char[64] || episode name |
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Block 3: Scripts ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | |0x0000 || uint32 || size of block |
|- | |- | ||
− | | | + | |0x0004 || - || start of block (data below) |
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || MissionCleanupEntry[456] || mission cleanup entries |
|- | |- | ||
− | | | + | | 0x4E60 || uint32 || global variables size (size) |
|- | |- | ||
− | | | + | | 0x4E64 || uint32[size] || global variables array |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || unknown (value used for padding below) {{Note|unknown number}} |
|- | |- | ||
− | | | + | | 0x0004 || int32 || xlive globals buffer size (n) {{Note|xlive buffers}} |
|- | |- | ||
− | | | + | | 0x0008 || uint8[n] || xlive globals buffer |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || threads count |
|- | |- | ||
− | | | + | | 0x0004 || uint8[24][77] || thread names |
|- | |- | ||
− | | | + | | 0x073C || uint32 || threads count |
|- | |- | ||
− | | | + | | 0x0740 || Thread[77] || threads |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | ? || uint32[] || padding (sum of the following values) |
+ | * (68604 - total stack pointers written{{ref|stack pointer}}) | ||
+ | * (77 * 2048 - unknowns written{{ref|unknowns}}) | ||
+ | * 2049 - xlive buffers written{{ref|xlive buffers}} | ||
+ | * 1024 - unknown number{{ref|unknown number}} | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || unknown |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || last mission pass time |
|- | |- | ||
− | | | + | | 0x0008 || Unknown[140] (Unknown is 44 bytes long) || unknown array (script store names) |
|- | |- | ||
− | | | + | | 0x17B0 || BuildingSwap[25] || building swap array |
|- | |- | ||
− | | | + | | 0x18DC || InvisibleObject[10] || invisible objects array |
|- | |- | ||
− | | | + | | 0x192C || uint32 || ped queue membership size |
|- | |- | ||
− | | | + | | 0x1930 || Unknown[8] (88 bytes each) || ped queue membership |
|- | |- | ||
− | | | + | | 0x1BF0 || uint32[10] || suppressed car models |
|- | |- | ||
− | | | + | | 0x1C18 || ConnectedLOD[10] || connected lods |
|- | |- | ||
− | | | + | | 0x1C68 || Unknown[16] (32 bytes each) || unknown (related to TXDs) |
|- | |- | ||
− | | | + | | 0x1E68 || Unknown[100] (48 bytes each) || unknown (related to textures) |
+ | |} | ||
+ | |||
+ | <div style="margin-left: 5em;"> | ||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+ConnectedLOD (8 bytes) | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || object 1 pool index |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || object 2 pool index |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+Invisibility Settings (8 bytes) | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || type (0 = none, 2 = building, 3 = object, 4 = dummy object) |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || index in the respective pool |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+BuildingSwap (16 bytes) | ||
|- | |- | ||
− | | | + | | 0x0000 || uin32 || type (2 if building swap, 0 if empty) |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || index of building in pool (0 if type is 0) |
|- | |- | ||
− | | | + | | 0x0008 || uint32 || new model |
|- | |- | ||
− | | | + | | 0x000C || uint32 || old model |
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+Thread | ||
+ | |- | ||
+ | | 0x0000 || uint8[24] || thread name | ||
+ | |- | ||
+ | | 0x0018 || uint32[2] || (unknown) | ||
+ | |- | ||
+ | | 0x0020 || uint32 || saved death arrest stack off | ||
+ | |- | ||
+ | | 0x0024 || uint8 || (unknown) | ||
+ | |- | ||
+ | | 0x0025 || uint8 || is script safe for network game | ||
+ | |- | ||
+ | | 0x0026 || uint8 || should the script be saved | ||
+ | |- | ||
+ | | 0x0027 || uint8 || is a minigame script | ||
+ | |- | ||
+ | | 0x0028 || uint8 || can remove blips created by any script | ||
+ | |- | ||
+ | | 0x0029 || uint8 || (unknown) | ||
+ | |- | ||
+ | | 0x002A || uint32 || (unknown) | ||
+ | |- | ||
+ | | 0x002E || ThreadContext || script context | ||
+ | |- | ||
+ | | 0x0082 || uint32 || constant zero | ||
+ | |- | ||
+ | | 0x0086 || uint32[] || script stack | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 5em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || uint32 || xlive buffer last index (n) | ||
+ | |- | ||
+ | | 0x0004 || uint8[4 * n + 4] || | ||
+ | * xlive buffer data | ||
+ | * only if (n) if greater than 0 | ||
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32[] || unknown array (size is (1 + unknown last index{{ref|unknowns}})) |
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+ThreadContext (84 bytes) | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || thread id |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || script hash |
|- | |- | ||
− | | | + | | 0x0008 || uint32 || state |
|- | |- | ||
− | | | + | | 0x000C || uint32 || instruction pointer |
|- | |- | ||
− | | | + | | 0x0010 || uint32 || number of stack pointers {{Note|stack pointer}} |
+ | |- | ||
+ | | 0x0014 || uint32[3] || timers | ||
+ | |- | ||
+ | | 0x0024 || float || wait time | ||
+ | |- | ||
+ | | 0x0050 || uint32 || unknown data last index {{Note|unknowns}} | ||
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+MissionCleanupEntry (44 bytes) | ||
+ | |- | ||
+ | | 0x0000 || byte || type | ||
+ | |- | ||
+ | | 0x0004 || uint32 || handle | ||
+ | |- | ||
+ | | 0x0008 || uint32 || thread id | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 5em;"> | ||
+ | |||
+ | ''' Types: ''' | ||
+ | |||
+ | * 1 = vehicle | ||
+ | * 2 = character | ||
+ | * 3 = dummy character | ||
+ | * 4 = object | ||
+ | * 5 = ptfx | ||
+ | * 6 = fire | ||
+ | * 7 = group | ||
+ | * 8 = ped queue | ||
+ | * 9 = sequence task | ||
+ | * 10 = decision maker | ||
+ | * 11 = checkpoint | ||
+ | * 12 = texture | ||
+ | * 13 = txd | ||
+ | * 14 = streamed txd | ||
+ | * 15 = cover point | ||
+ | * 16 = anim | ||
+ | * 17 = model | ||
+ | * 18 = blip | ||
+ | * 18 = blip | ||
+ | * 19 = onscreen timer | ||
+ | * 20 = onscreen counter | ||
+ | * 21 = camera | ||
+ | * 22 = viewport | ||
+ | |||
+ | </div> | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | ==== Block 4: Garages ==== | ||
+ | |||
+ | Stores garages defined in the game along with their stored vehicles. | ||
+ | |||
+ | The block starts with a 4 byte integer containing the size of it. The below data follows. | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || garage count |
|- | |- | ||
− | | | + | | 0x0004 || uint8 || (unknown) |
|- | |- | ||
− | | | + | | 0x0005 || uint8 || resprays are free |
|- | |- | ||
− | | | + | | 0x0006 || uint8 || resprays are disabled |
|- | |- | ||
− | | | + | | 0x0007 || uint32 || (unknown) |
|- | |- | ||
− | | | + | | 0x000B || uint32 || safehouse garage count |
|- | |- | ||
− | | | + | | 0x000F || StoredCar[20] || stored cars array |
|- | |- | ||
− | | | + | | 0x05AF || Garage[40] || garages array |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ StoredCar (72 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || float[3] || position (x, y, z) |
|- | |- | ||
− | | | + | | 0x000C || uint32 || handling flags |
|- | |- | ||
− | | | + | | 0x0010 || uint16 || model index |
|- | |- | ||
− | | | + | | 0x0032 || uint8[4] || colors |
|- | |- | ||
− | | | + | | 0x0038 || uint32 || extras |
|- | |- | ||
− | | | + | | 0x003C || uint32 || livery |
|- | |- | ||
− | | | + | | 0x0043 || uint8[3] || rotation (x, y, z) |
|- | |- | ||
− | | | + | | 0x0048 || uint16 || flags (see below) |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | ''' flags - Bitfield ''' | ||
+ | * 0b00000000'''1''' = Valid | ||
+ | * 0b00000'''1'''000 = Bullet proof | ||
+ | * 0b0000'''1'''0000 = Fire proof | ||
+ | * 0b000'''1'''00000 = Explosion proof | ||
+ | * 0b00'''1'''000000 = Collision proof | ||
+ | * 0b0'''1'''0000000 = Melee proof | ||
+ | |||
+ | Note: | ||
+ | * There can be leftover stored cars from previous save games in empty slots. Check if the "Valid" flag is set to see if it will be loaded in game. | ||
+ | |||
+ | </div> | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ Garage (72 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint8 || type |
|- | |- | ||
− | | | + | | 0x0001 || uint8 || open state |
|- | |- | ||
− | | | + | | 0x0002 || uint8 || door flags |
|- | |- | ||
− | | | + | | 0x0004 || float[3] || position (x, y, z) |
|- | |- | ||
− | | | + | | 0x0010 || float[2] || direction a (x, y) |
|- | |- | ||
− | | | + | | 0x0018 || float[2] || direction b (x, y) |
|- | |- | ||
− | | | + | | 0x0020 || float || top z |
|- | |- | ||
− | | | + | | 0x0024 || float || (unknown) |
|- | |- | ||
− | | | + | | 0x0028 || float || (unknown) |
|- | |- | ||
− | | | + | | 0x002C || float || left coordinate |
|- | |- | ||
− | | | + | | 0x0030 || float || right coordinate |
|- | |- | ||
− | | | + | | 0x0034 || float || front coordinate |
|- | |- | ||
− | | | + | | 0x0038 || float || back coordinate |
|- | |- | ||
− | | | + | | 0x003C || uint32 || (unknown) |
|- | |- | ||
− | | | + | | 0x0040 || uint32 || garage name hash |
|- | |- | ||
− | | | + | | 0x0044 || uint8 || original type |
|- | |- | ||
− | | | + | | 0x0045 || uint8 || safehouse garage index (if safehouse) |
|- | |- | ||
− | | | + | |} |
+ | </div> | ||
+ | |||
+ | ==== Block 5: GameLogic ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || size of block |
|- | |- | ||
− | | | + | | 0x0004 || uint8 || lose money on being wasted |
|- | |- | ||
− | | | + | | 0x0005 || uint8 || lose weapons on getting busted |
|- | |- | ||
− | | | + | | 0x0006 || uint32 || unknown (subtracted from money for $500,000 achievement) |
+ | |} | ||
+ | |||
+ | ==== Block 6: PathFind ==== | ||
+ | ==== Block 7: Pickups ==== | ||
+ | This block contains an array of 650 Pickup structures plus 9 bytes of padding. Each Pickup structure is a constant 0x54 bytes. | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | |0x00 ||char[5] || a "BLOCK" string |
|- | |- | ||
− | | | + | |0x04 ||dword || size of block in bytes (always 0xD55A) |
|- | |- | ||
− | | | + | |0x08 ||int || total number of pickups |
|- | |- | ||
− | | | + | |0x0C ||Pickup[650] || pickups array |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ Pickup | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | |0x00 ||int32_t || index (-1 indicates unused pickup) |
|- | |- | ||
− | | | + | |0x04 ||dword || unknown |
|- | |- | ||
− | | | + | |0x08 ||dword || unknown |
|- | |- | ||
− | | | + | |0x0C ||dword || amount (ammo, etc.) |
|- | |- | ||
− | | | + | |0x10 ||dword || unknown |
|- | |- | ||
− | | | + | |0x14 ||dword || unknown |
|- | |- | ||
− | | | + | |0x18 ||int32 || blip |
|- | |- | ||
− | | | + | |0x1C ||dword || timer |
|- | |- | ||
− | | | + | |0x20 ||Vector3 || location (x,y,z) |
|- | |- | ||
− | | | + | |0x2C ||dword || unknown |
|- | |- | ||
− | | | + | |0x30 ||dword || unknown |
|- | |- | ||
− | | | + | |0x34 ||Vector3 || rotation |
|- | |- | ||
− | | | + | |0x40 ||dword || unknown |
|- | |- | ||
− | | | + | |0x44 ||int16 || object ID |
|- | |- | ||
− | | | + | |0x46 ||int16 || reference number |
|- | |- | ||
− | | | + | |0x48 ||byte || pickup type |
|- | |- | ||
− | | | + | |0x49 ||byte || flags |
|- | |- | ||
− | | | + | |0x4A ||byte || flags |
|- | |- | ||
− | | | + | |0x4B ||byte || pickup type (HiddenPackage = 3) |
|- | |- | ||
− | | | + | |0x4C ||dword || unknown |
|- | |- | ||
− | | | + | |0x50 ||dword || unknown |
|- | |- | ||
− | | | + | |0x54 ||(end) || |
+ | |} | ||
+ | </div> | ||
+ | |||
+ | ==== Block 8: Restart ==== | ||
+ | |||
+ | This block stores where the player respawns on dying or getting busted. | ||
+ | |||
+ | It also stores the coordinates for the safehouse spawns | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || wasted restart point count |
|- | |- | ||
− | | | + | | 0x0004 || RestartPoint[10] || [[ADD_HOSPITAL_RESTART|wasted restart points array]] |
|- | |- | ||
− | | | + | | 0x00F4 || uint32 || busted restart point count |
|- | |- | ||
− | | | + | | 0x00F8 || RestartPoint[20] || [[ADD_POLICE_RESTART|busted restart points array]] |
|- | |- | ||
− | | | + | | 0x02D8 || uint32 || safehouse count |
|- | |- | ||
− | | | + | | 0x02DC || Safehouse[6] || [[REGISTER_SAVE_HOUSE|safehouses array]] |
|- | |- | ||
− | | | + | | 0x0432 || uint8 || [[OVERRIDE_NEXT_RESTART|override next restart]] |
|- | |- | ||
− | | | + | | 0x0433 || float[4] || overridden restart point coordinates (x, y, z, w) |
|- | |- | ||
− | | | + | | 0x0443 || float || overriden restart point heading |
|- | |- | ||
− | | | + | | 0x0447 || uint8 || [[SUPPRESS_FADE_IN_AFTER_DEATH_ARREST|supress fade in after death arrest]] |
|- | |- | ||
− | | | + | | 0x0448 || RestartPoint || [[SET_EXTRA_HOSPITAL_RESTART_POINT|extra wasted restart point]] |
|- | |- | ||
− | | | + | | 0x0460 || RestartPoint || [[SET_EXTRA_POLICE_STATION_RESTART_POINT|extra busted restart point]] |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ RestartPoint (24 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || float[4] || coordinates (x, y, z, w) |
|- | |- | ||
− | | | + | | 0x0010 || float || heading |
|- | |- | ||
− | | | + | | 0x0014 || uint32 || town (0 = Broker and Dukes, 1 = Algonquin, 2 = Alderney) |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | {|class="wikitable" | ||
+ | |+ Safehouse (57 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || float[4] || coordintaes (x, y, z, w) |
|- | |- | ||
− | | | + | | 0x0010 || float || heading |
|- | |- | ||
− | | | + | | 0x0014 || char[32] || name |
|- | |- | ||
− | | | + | | 0x0034 || uint32 || town (see above) |
|- | |- | ||
− | | | + | | 0x0038 || uint8 || [[ENABLE_SAVE_HOUSE|enabled]] |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Block 9: Radar ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || block size |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || "centre blip" index/id |
|- | |- | ||
− | | | + | | 0x0008 || uint32 || "north blip" index/id |
|- | |- | ||
− | | | + | | 0x000C || uint32 || "simple blip" index/id |
|- | |- | ||
− | | | + | | 0x0010 || uint32 || saved blips count |
|- | |- | ||
− | | | + | | 0x0014 || Blip[150] || blips array |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ Blip (100 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || blip index |
|- | |- | ||
− | | | + | | 0x0004 || bool || not a simple blip |
|- | |- | ||
− | | | + | | 0x0005 || uint16 || flags |
|- | |- | ||
− | | | + | | 0x0007 || float[4] || position (x, y, z, w) |
|- | |- | ||
− | | | + | | 0x001F || char[30] || sprite name * <sup>see note below</sup> |
|- | |- | ||
− | | | + | | 0x003D || uint16 || blip id? |
|- | |- | ||
− | | | + | | 0x003F || uint32 || mission cleanup handle |
|- | |- | ||
− | | | + | | 0x0043 || uint32 || priority |
|- | |- | ||
− | | | + | | 0x0047 || uint32 || type (only type 4, 8 and 5 are saved) |
|- | |- | ||
− | | | + | | 0x004B || uint32 || display |
|- | |- | ||
− | | | + | | 0x004F || float || scale |
|- | |- | ||
− | | | + | | 0x0053 || uint32 || colour id |
|- | |- | ||
− | | | + | | 0x0057 || uint8 || alpha |
|- | |- | ||
− | | | + | | 0x0058 || uint32 || sprite hash? |
|- | |- | ||
− | | | + | | 0x005C || char[8] || unknown ("0000000") |
+ | |} | ||
+ | ''* In 1.2.x CE and newer versions, the sprite name has changed to wchar_t[60]. Add 30 (0x1E) bytes to the offsets after it for this version.'' | ||
+ | |||
+ | ''' flags - Bitfield ''' | ||
+ | * 0b00000000'''1'''0 = Friendly Blip (0x2) | ||
+ | * 0b0000000'''1'''00 = Flashing Blip (0x4) | ||
+ | * 0b000000'''1'''000 = Short Ranged blip (0x8) | ||
+ | * 0b00000'''1'''0000 = A route is displayed to the blip (0x10) | ||
+ | * 0b00'''1'''0000000 = Is a weapon pickup (multiplayer only) (0x80) | ||
+ | * 0b0'''1'''00000000 = Alternative Flashing Blip (0x100) | ||
+ | * 0b'''1'''000000000 = Long Distance blip (0x200) | ||
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Block 10: Zones ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || block size |
|- | |- | ||
− | | | + | | 0x0004 || uint32 || zone count |
|- | |- | ||
− | | | + | | 0x0008 || Zone[300] || zones |
|- | |- | ||
− | | | + | | 0x2EE0 || char[100] || (unknown) (likely unused) |
|- | |- | ||
− | | | + | | 0x2F44 || uint32 || (unknown) (likely unused) |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ Zone (40 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || char[8] || name |
|- | |- | ||
− | | | + | | 0x0008 || char[8] || gxt entry (also used for audio) |
|- | |- | ||
− | | | + | | 0x0010 || float[6] || bounds (x1, y1, z1, x2, y2, z2) |
|- | |- | ||
− | | | + | | 0x0020 || uint8 || population type (bitfield) |
|- | |- | ||
− | | | + | | 0x0021 || uint8 || scumminess (bitfield) |
|- | |- | ||
− | | | + | |} |
+ | </div> | ||
+ | |||
+ | ==== Block 11: Gangs ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || uint32 || block size |
|- | |- | ||
− | | | + | | 0x0004 || CGang[11] || gangs |
|- | |- | ||
− | | | + | |} |
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ CGang (20 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || char[4] || unknown (possibly unused) |
|- | |- | ||
− | | | + | | 0x0008 || int[3] || [[List_of_Weapons_(GTA4)|weapons]] |
|- | |- | ||
− | | | + | | 0x0010 || byte[3] || decides the chances for the weapons above |
|- | |- | ||
− | | | + | | 0x0013 || byte || unknown (possibly unused) |
+ | |} | ||
+ | |||
+ | Note: The game will not give gangs the 2nd weapon in the array until the maximum wanted level reaches 5, and the 3rd weapon until the maximum wanted level reaches 6 | ||
+ | </div> | ||
+ | |||
+ | ==== Block 12: CarGenerators ==== | ||
+ | This block stores Car Generators managed by scripts in GTA 4. This includes mission rewards and boats or helicopters disabled before Algonquin and Alderney are unlocked. | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || CarGenerator[25] || Car Generators array (see below) |
|- | |- | ||
− | | | + | | 0x044C || Unknown[15] || Unknown is 16 bytes each |
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ CarGenerator | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | | 0x0000 || float[3] || Position of the Parked Vehicle |
|- | |- | ||
− | | | + | | 0x000C || float[2] || Rotation (X,Y) |
|- | |- | ||
− | | | + | | 0x0014 || float[2] || Unknown (has something to do with Z rotation) |
|- | |- | ||
− | | | + | | 0x001C || uint16_t || Model ID |
|- | |- | ||
− | | | + | | 0x001E || uint16_t || Pool index (normally always 0) |
|- | |- | ||
− | | | + | | 0x0022 || uint8_t || Color 1 |
|- | |- | ||
− | | | + | | 0x0023 || uint8_t || Color 2 |
|- | |- | ||
− | | | + | | 0x0024 || uint8_t || Color 3 |
|- | |- | ||
− | | | + | | 0x0025 || uint8_t || Color 4 |
|- | |- | ||
− | | | + | | 0x0026 || uint8_t[5] || Unknown (flags) |
|- | |- | ||
− | | | + | | 0x002B || uint8_t || Enabled (0 = disabled, 101 = enabled) |
+ | |} | ||
+ | </div> | ||
+ | |||
+ | ====Block 13: Stats==== | ||
+ | This block has a constant length of 0x1724 or 0x173C bytes depending on the game version, and stores [[List_of_statistics_(GTA4)|various statistics]]; most of which can be viewed the game's Stats menu. | ||
+ | To get the offset of a stat from its ID, multiply the ID by 4 and add the offset for Start of stats (0x54 or 0x6C). | ||
+ | |||
+ | 1.2.0.32 CE and older | ||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
|- | |- | ||
− | | | + | |0x00 ||dword ||Size of block |
|- | |- | ||
− | | | + | |0x04 ||byte[80] ||unknown radio-related stats |
|- | |- | ||
− | | | + | |0x54 ||float[]/int[] ||Start of [[List_of_statistics_(GTA4)|statistics by id]] |
|- | |- | ||
|0x1724 ||end || | |0x1724 ||end || | ||
|} | |} | ||
− | + | 1.2.0.43 CE and newer | |
− | |||
− | |||
{|class="wikitable" | {|class="wikitable" | ||
!OFFSET | !OFFSET | ||
Line 507: | Line 954: | ||
|0x00 ||dword ||Size of block | |0x00 ||dword ||Size of block | ||
|- | |- | ||
− | |0x04 ||dword || | + | |0x04 ||dword[3] ||unknown integers |
+ | |- | ||
+ | |0x10 ||byte[92] ||unknown radio-related stats | ||
+ | |- | ||
+ | |0x6C ||float[]/int[] ||Start of [[List_of_statistics_(GTA4)|statistics by id]] | ||
+ | |- | ||
+ | |0x173C ||end || | ||
+ | |} | ||
+ | |||
+ | ==== Block 14: IplStore ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || uint32 || block size | ||
+ | |- | ||
+ | | 0x0004 || uint32 || length of the following array (500) | ||
+ | |- | ||
+ | | 0x0008 || bool[500] || an array of boolean (the wpl of that index will be loaded if true) | ||
+ | |} | ||
+ | |||
+ | ==== Block 15: StuntJumps ==== | ||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | |0x00 ||dword ||Size of block | ||
+ | |- | ||
+ | |0x04 ||byte ||whether stunt jumps are enabled | ||
+ | |- | ||
+ | |0x05 || dword || number of stunt jumps completed | ||
+ | |- | ||
+ | |0x09 ||dword ||number of stunt jumps | ||
+ | |- | ||
+ | |0x0E ||byte[4] ||total stunt jumps | ||
|- | |- | ||
− | | | + | |0x11 || StuntJump[64] || start of stunt jump structs (0x64 bytes each; see below) |
|} | |} | ||
− | ====Block | + | <div style="margin-left: 3em;"> |
− | This block has a constant length of 0x16C bytes | + | {|class="wikitable" |
+ | |+StuntJump | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | |0x00 ||dword || pool index | ||
+ | |- | ||
+ | |0x04 ||float[4] ||Start zone point 1 (x,y,z,w) | ||
+ | |- | ||
+ | |0x14 ||float[4] ||Start zone point 2 (x,y,z,w) | ||
+ | |- | ||
+ | |0x24 ||float[4] ||Land zone point 1 (x,y,z,w) | ||
+ | |- | ||
+ | |0x34 ||float[4] ||Land zone point 2 (x,y,z,w) | ||
+ | |- | ||
+ | |0x44 ||float[4] ||Camera coordinates (x,y,z,w) | ||
+ | |- | ||
+ | |0x54 ||dword ||reward amount | ||
+ | |- | ||
+ | |0x58 ||byte ||is completed | ||
+ | |- | ||
+ | |0x59 ||byte ||is found | ||
+ | |- | ||
+ | |0x5A ||byte[10] ||unknown, maybe align/padding | ||
+ | |} | ||
+ | </div> | ||
+ | |||
+ | ==== Block 16: Radio ==== | ||
+ | |||
+ | The radio station block stores the recently played tracks for radio stations in the game. It's used for music weights and to ensure two random tracks (like the weather reports) don't play right after each other. | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || bool || [[LOCK_LAZLOW_STATION|is lazlow station locked]] | ||
+ | |- | ||
+ | | 0x0001 || uint8 || unknown | ||
+ | |- | ||
+ | | 0x0002 || bool || [[SET_TAXI_GARAGE_RADIO_STATE|taxi garage radio state]] | ||
+ | |- | ||
+ | | 0x0003 || RadioStation[n] || radio station save data | ||
+ | |- | ||
+ | |} | ||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || RecentTracks || recently played news tracks | ||
+ | |- | ||
+ | | 0x0029 || RecentTracks || recently played weather reports | ||
+ | |- | ||
+ | | 0x0052 || RecentTracks || recently played adverts | ||
+ | |- | ||
+ | | 0x007b || uint8[256] || news stories state | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | {|class="wikitable" | ||
+ | |+ RadioStation (144 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || RecentTracks || recently played ident tracks | ||
+ | |- | ||
+ | | 0x0029 || RecentTracks || recently played music tracks | ||
+ | |- | ||
+ | | 0x0052 || RecentTracks || recently played dj solo tracks | ||
+ | |- | ||
+ | | 0x007b || uint8 || unknown | ||
+ | |- | ||
+ | | 0x007c || short[10] || unknown array | ||
+ | |} | ||
+ | |||
+ | {|class="wikitable" | ||
+ | |+ RecentTracks (41 bytes) | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || uint8 || current position in the array | ||
+ | |- | ||
+ | | 0x0001 || uint[10] || track hash (as defined in GAME.DAT16) | ||
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | Note: | ||
+ | |||
+ | * n is the number of radio stations defined in the game. That's 20 for versions before Complete Edition, and 23 for Complete Edition. | ||
+ | |||
+ | ==== Block 17: Objects ==== | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || uint32 || block size | ||
+ | |- | ||
+ | | 0x0004 || uint32 || object count | ||
+ | |- | ||
+ | | 0x0008 || Object[10] || objects (only mission cleanup objects are saved) | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+Object (72 bytes) | ||
+ | |- | ||
+ | | 0x0000 || uint32 || pool handle | ||
+ | |- | ||
+ | | 0x0004 || uint32 || model hash | ||
+ | |- | ||
+ | | 0x0008 || float[4] || coordinates (x,y,z,w) | ||
+ | |- | ||
+ | | 0x0018 || Matrix || compressed rotation matrix | ||
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | ==== Block 18: Relationships ==== | ||
+ | |||
+ | This block stores the [[Ped_type#Relationship_groups| relationship groups]] defined in Relations.dat. | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |- | ||
+ | | 0x0000 || uint32 || block size | ||
+ | |- | ||
+ | | 0x0004 || Relationships[70] || Relationship groups | ||
+ | |} | ||
+ | |||
+ | <div style="margin-left: 3em;"> | ||
+ | |||
+ | {|class="wikitable" | ||
+ | !OFFSET | ||
+ | !TYPE | ||
+ | !DESCRIPTION | ||
+ | |+Relationship (72 bytes) | ||
+ | |- | ||
+ | | 0x0000 || uint96 || respect bitfield | ||
+ | |- | ||
+ | | 0x000C || uint96 || like bitfield | ||
+ | |- | ||
+ | | 0x0018 || uint96 || ? bitfield | ||
+ | |- | ||
+ | | 0x0024 || uint96 || dislike bitfield | ||
+ | |- | ||
+ | | 0x0030 || uint96 || ? bitfield | ||
+ | |- | ||
+ | | 0x003C || uint96 || hate bitfield | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | </div> | ||
+ | |||
+ | Note: | ||
+ | |||
+ | * uint96 is a 12 byte (96 bits) integer. | ||
+ | * The array index corresponds to the [[Ped_type#GTA_IV|ped type]], so array index 1 will be the relations for [[Ped_type#GTA_IV|ped type]] 1 (CIVMALE) | ||
+ | * The bits also correspond to the [[Ped_type#GTA_IV|ped type]], so the first bit in the bitfield will be for [[Ped_type#GTA_IV|ped type]] 0 (PLAYER) and so on. | ||
+ | |||
+ | ==== Block 19: Inventory ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 20: Pools ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 21: PhoneInfo ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 22: AudioScriptObject ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 23: SetPieces ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 24: Streaming ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 25: PedType ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 26: Tags ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 27: Shopping ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 28: GangWars ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 29: EntryExits ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 30: 3dMarkers ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ==== Block 31: Vehicles ==== | ||
+ | |||
+ | This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9) | ||
+ | |||
+ | ===Checksum=== | ||
+ | |||
+ | The checksum follows the last data block. | ||
+ | |||
+ | * The <code>savegame size in bytes</code> in the meta data should be set to <code>1977922</code> (0x1E2E42), before calculating the checksum. | ||
+ | * It is the sum of all the bytes preceding the checksum value. | ||
+ | * Implementation Example: [https://pastebin.com/DvZPNDh5 A Python script] for calculating the checksum value | ||
+ | |||
+ | Note: | ||
+ | * The reason is that the game adds the GFLW data size to the metadata after it has calculated the checksum. | ||
+ | * The checksum value is ignored by the game. An incorrect checksum will not prevent a save file from being loaded. | ||
+ | |||
+ | ===End Block=== | ||
+ | This block has a constant length of 0x16C bytes. | ||
Data in this block appears to relate to Games For Windows Live data. | Data in this block appears to relate to Games For Windows Live data. | ||
{|class="wikitable" | {|class="wikitable" |
Latest revision as of 15:05, 25 January 2024
This article deals with the format of a save game file for the PC version of GTA 4.
Location
1.0.8.0 IV / 1.1.3.0 EFLC and older
By default, the game places its save game files into the "%LocalAppData%\Rockstar Games\GTA IV\savegames\user_XXXXXXXXXXXXXXXX\" folder where XXXXXXXXXXXXXXXX is a 16-character string tied to the user's Games for Windows Live account.
Players using Xliveless or downgrade patches may find the save files in "%HomePath%\Documents\Rockstar Games\XXXX\savegames\" folder where XXXX is either "GTA IV" (base game), "TLAD", or "TBoGT".
1.2.x CE and newer
Save files for the Complete Edition can be found in "%HomePath%\Documents\Rockstar Games\GTA IV\Profiles\XXXXXXXX\" where XXXXXXXX is a 8-character string tied to the user's Rockstar Social Club account.
Save Slots
The save files themselves are named in the format "SGTA4XX" where XX represents the in-game slot number minus 1. There are 12 slots available in the game (1-12) plus additional auto-save slots (SGTA412 for the base game, SGTA413 for TLAD, and SGTA414 for TBoGT).
Format Details
- Save file size varies but is typically just under 2 megabytes.
- Byte order is little endian. For example, the number 3452 (0x0D7C) is represented as as 0x7C 0x0D.
- A savegame consists of 32 data blocks, two blocks with metadata and a checksum number.
Savegame Metadata
A savegame file starts with this block, which has a constant length of 0x110 bytes.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | dword | savegame version number |
0x04 | dword | savegame size in bytes |
0x08 | dword | global variables size (?) |
0x0C | char[4] | "SAVE" string |
0x10 | wchar_t[128] | Name of last mission passed |
0x110 | end |
Notes:
- Savegame version number value is set under the [SAVEGAME_VERSION_NUMBER] section in the GTA IV/common/data/version.txt file
- Last mission name is prefixed with either "TLAD - " or "TBoGT - " for Episodes From Liberty City saves
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. Following the BLOCK character is always a dword specifying the size of the block, starting at the beginning of BLOCK characters.
Block 0: SimpleVars
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | char[5] | a "BLOCK" string |
0x05 | dword | size of block in bytes (always 0xB9) |
0x09 | dword | start of data; see below |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | closest safehouse index |
0x0004 | bool | fade in after load |
0x0010 | Vector4 | camera coordinates (x, y, z, w) |
0x0020 | uint32 | length of ingame timer (ms) |
0x0024 | uint32 | weather timer (?) |
0x0028 | uint32 | in-game month |
0x002c | uint32 | in-game day |
0x0030 | uint32 | in-game hours |
0x0034 | uint32 | in-game minutes |
0x0038 | uint32 | in-game day of the week |
0x003c | bool | whether the player has cheated |
0x0040 | uint32 | game timer |
0x0044 | uint32 | frame count |
0x0048 | uint32 | weather 2 |
0x004c | uint32 | weather 1 |
0x0050 | uint32 | forced weather |
0x0054 | uint32 | game hour fraction |
0x0060 | int | vehicle camera mode |
0x0064 | int | ped camera mode |
0x0068 | int | don't zoom on aim |
0x0080 | int | max wanted level |
0x0084 | uint32 | max chaos level |
0x0094 | uint32_t | waypoint blip |
0xB0 | end |
Block 1: PlayerInfo
This block has a constant length of 0xD4 bytes.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | size of block |
0x0004 | float[3] | player coordinates |
0x0010 | uint32 | constant 192 (size of PlayerInfo) |
0x0014 | PlayerInfo | player info |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0008 | uint32 | player money |
0x0010 | uint32 | player display money |
0x0020 | uint8 | never tired |
0x0021 | uint8 | fast reload |
0x0022 | uint8 | fire proof |
0x0024 | uint16 | max health |
0x0026 | uint16 | max armour |
0x0028 | uint8 | keep weapons after busted |
0x0029 | uint8 | free health care |
0x002a | uint8 | can drive by |
0x002b | uint8 | can be hassled by gangs |
0x0030 | uint32 | max wanted level |
0x0034 | uint32 | max chaos |
0x0040 | float[4] | player coordinates (x,y,z,w) |
0x0050 | float | health |
0x0054 | float | armour |
0x0058 | uint32 | (current weapon slot?) |
0x005c | uint32[10] | weapon slots |
0x0084 | uint16[10] | weapons ammo |
0x00a4 | uint32 | prop variation |
0x00a8 | uint8[11] | drawable variation |
0x00b3 | uint8[11] | texture variation |
Block 2: ExtraContent
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | uint64 | flags (bit set for the active episode(s)) |
0x000C | Episode[64] | episodes array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint8 | episode id |
0x0001 | char[64] | episode name |
Block 3: Scripts
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | size of block |
0x0004 | - | start of block (data below) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | MissionCleanupEntry[456] | mission cleanup entries |
0x4E60 | uint32 | global variables size (size) |
0x4E64 | uint32[size] | global variables array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | unknown (value used for padding below) ^ |
0x0004 | int32 | xlive globals buffer size (n) ^ |
0x0008 | uint8[n] | xlive globals buffer |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | threads count |
0x0004 | uint8[24][77] | thread names |
0x073C | uint32 | threads count |
0x0740 | Thread[77] | threads |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
? | uint32[] | padding (sum of the following values)
|
0x0000 | uint32 | unknown |
0x0004 | uint32 | last mission pass time |
0x0008 | Unknown[140] (Unknown is 44 bytes long) | unknown array (script store names) |
0x17B0 | BuildingSwap[25] | building swap array |
0x18DC | InvisibleObject[10] | invisible objects array |
0x192C | uint32 | ped queue membership size |
0x1930 | Unknown[8] (88 bytes each) | ped queue membership |
0x1BF0 | uint32[10] | suppressed car models |
0x1C18 | ConnectedLOD[10] | connected lods |
0x1C68 | Unknown[16] (32 bytes each) | unknown (related to TXDs) |
0x1E68 | Unknown[100] (48 bytes each) | unknown (related to textures) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | object 1 pool index |
0x0004 | uint32 | object 2 pool index |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | type (0 = none, 2 = building, 3 = object, 4 = dummy object) |
0x0004 | uint32 | index in the respective pool |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uin32 | type (2 if building swap, 0 if empty) |
0x0004 | uint32 | index of building in pool (0 if type is 0) |
0x0008 | uint32 | new model |
0x000C | uint32 | old model |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint8[24] | thread name |
0x0018 | uint32[2] | (unknown) |
0x0020 | uint32 | saved death arrest stack off |
0x0024 | uint8 | (unknown) |
0x0025 | uint8 | is script safe for network game |
0x0026 | uint8 | should the script be saved |
0x0027 | uint8 | is a minigame script |
0x0028 | uint8 | can remove blips created by any script |
0x0029 | uint8 | (unknown) |
0x002A | uint32 | (unknown) |
0x002E | ThreadContext | script context |
0x0082 | uint32 | constant zero |
0x0086 | uint32[] | script stack |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | xlive buffer last index (n) |
0x0004 | uint8[4 * n + 4] |
|
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32[] | unknown array (size is (1 + unknown last index[unknowns])) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | thread id |
0x0004 | uint32 | script hash |
0x0008 | uint32 | state |
0x000C | uint32 | instruction pointer |
0x0010 | uint32 | number of stack pointers ^ |
0x0014 | uint32[3] | timers |
0x0024 | float | wait time |
0x0050 | uint32 | unknown data last index ^ |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | byte | type |
0x0004 | uint32 | handle |
0x0008 | uint32 | thread id |
Types:
- 1 = vehicle
- 2 = character
- 3 = dummy character
- 4 = object
- 5 = ptfx
- 6 = fire
- 7 = group
- 8 = ped queue
- 9 = sequence task
- 10 = decision maker
- 11 = checkpoint
- 12 = texture
- 13 = txd
- 14 = streamed txd
- 15 = cover point
- 16 = anim
- 17 = model
- 18 = blip
- 18 = blip
- 19 = onscreen timer
- 20 = onscreen counter
- 21 = camera
- 22 = viewport
Block 4: Garages
Stores garages defined in the game along with their stored vehicles.
The block starts with a 4 byte integer containing the size of it. The below data follows.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | garage count |
0x0004 | uint8 | (unknown) |
0x0005 | uint8 | resprays are free |
0x0006 | uint8 | resprays are disabled |
0x0007 | uint32 | (unknown) |
0x000B | uint32 | safehouse garage count |
0x000F | StoredCar[20] | stored cars array |
0x05AF | Garage[40] | garages array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | float[3] | position (x, y, z) |
0x000C | uint32 | handling flags |
0x0010 | uint16 | model index |
0x0032 | uint8[4] | colors |
0x0038 | uint32 | extras |
0x003C | uint32 | livery |
0x0043 | uint8[3] | rotation (x, y, z) |
0x0048 | uint16 | flags (see below) |
flags - Bitfield
- 0b000000001 = Valid
- 0b000001000 = Bullet proof
- 0b000010000 = Fire proof
- 0b000100000 = Explosion proof
- 0b001000000 = Collision proof
- 0b010000000 = Melee proof
Note:
- There can be leftover stored cars from previous save games in empty slots. Check if the "Valid" flag is set to see if it will be loaded in game.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint8 | type |
0x0001 | uint8 | open state |
0x0002 | uint8 | door flags |
0x0004 | float[3] | position (x, y, z) |
0x0010 | float[2] | direction a (x, y) |
0x0018 | float[2] | direction b (x, y) |
0x0020 | float | top z |
0x0024 | float | (unknown) |
0x0028 | float | (unknown) |
0x002C | float | left coordinate |
0x0030 | float | right coordinate |
0x0034 | float | front coordinate |
0x0038 | float | back coordinate |
0x003C | uint32 | (unknown) |
0x0040 | uint32 | garage name hash |
0x0044 | uint8 | original type |
0x0045 | uint8 | safehouse garage index (if safehouse) |
Block 5: GameLogic
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | size of block |
0x0004 | uint8 | lose money on being wasted |
0x0005 | uint8 | lose weapons on getting busted |
0x0006 | uint32 | unknown (subtracted from money for $500,000 achievement) |
Block 6: PathFind
Block 7: Pickups
This block contains an array of 650 Pickup structures plus 9 bytes of padding. Each Pickup structure is a constant 0x54 bytes.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | char[5] | a "BLOCK" string |
0x04 | dword | size of block in bytes (always 0xD55A) |
0x08 | int | total number of pickups |
0x0C | Pickup[650] | pickups array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | int32_t | index (-1 indicates unused pickup) |
0x04 | dword | unknown |
0x08 | dword | unknown |
0x0C | dword | amount (ammo, etc.) |
0x10 | dword | unknown |
0x14 | dword | unknown |
0x18 | int32 | blip |
0x1C | dword | timer |
0x20 | Vector3 | location (x,y,z) |
0x2C | dword | unknown |
0x30 | dword | unknown |
0x34 | Vector3 | rotation |
0x40 | dword | unknown |
0x44 | int16 | object ID |
0x46 | int16 | reference number |
0x48 | byte | pickup type |
0x49 | byte | flags |
0x4A | byte | flags |
0x4B | byte | pickup type (HiddenPackage = 3) |
0x4C | dword | unknown |
0x50 | dword | unknown |
0x54 | (end) |
Block 8: Restart
This block stores where the player respawns on dying or getting busted.
It also stores the coordinates for the safehouse spawns
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | wasted restart point count |
0x0004 | RestartPoint[10] | wasted restart points array |
0x00F4 | uint32 | busted restart point count |
0x00F8 | RestartPoint[20] | busted restart points array |
0x02D8 | uint32 | safehouse count |
0x02DC | Safehouse[6] | safehouses array |
0x0432 | uint8 | override next restart |
0x0433 | float[4] | overridden restart point coordinates (x, y, z, w) |
0x0443 | float | overriden restart point heading |
0x0447 | uint8 | supress fade in after death arrest |
0x0448 | RestartPoint | extra wasted restart point |
0x0460 | RestartPoint | extra busted restart point |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | float[4] | coordinates (x, y, z, w) |
0x0010 | float | heading |
0x0014 | uint32 | town (0 = Broker and Dukes, 1 = Algonquin, 2 = Alderney) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | float[4] | coordintaes (x, y, z, w) |
0x0010 | float | heading |
0x0014 | char[32] | name |
0x0034 | uint32 | town (see above) |
0x0038 | uint8 | enabled |
Block 9: Radar
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | uint32 | "centre blip" index/id |
0x0008 | uint32 | "north blip" index/id |
0x000C | uint32 | "simple blip" index/id |
0x0010 | uint32 | saved blips count |
0x0014 | Blip[150] | blips array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | blip index |
0x0004 | bool | not a simple blip |
0x0005 | uint16 | flags |
0x0007 | float[4] | position (x, y, z, w) |
0x001F | char[30] | sprite name * see note below |
0x003D | uint16 | blip id? |
0x003F | uint32 | mission cleanup handle |
0x0043 | uint32 | priority |
0x0047 | uint32 | type (only type 4, 8 and 5 are saved) |
0x004B | uint32 | display |
0x004F | float | scale |
0x0053 | uint32 | colour id |
0x0057 | uint8 | alpha |
0x0058 | uint32 | sprite hash? |
0x005C | char[8] | unknown ("0000000") |
* In 1.2.x CE and newer versions, the sprite name has changed to wchar_t[60]. Add 30 (0x1E) bytes to the offsets after it for this version.
flags - Bitfield
- 0b0000000010 = Friendly Blip (0x2)
- 0b0000000100 = Flashing Blip (0x4)
- 0b0000001000 = Short Ranged blip (0x8)
- 0b0000010000 = A route is displayed to the blip (0x10)
- 0b0010000000 = Is a weapon pickup (multiplayer only) (0x80)
- 0b0100000000 = Alternative Flashing Blip (0x100)
- 0b1000000000 = Long Distance blip (0x200)
Block 10: Zones
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | uint32 | zone count |
0x0008 | Zone[300] | zones |
0x2EE0 | char[100] | (unknown) (likely unused) |
0x2F44 | uint32 | (unknown) (likely unused) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | char[8] | name |
0x0008 | char[8] | gxt entry (also used for audio) |
0x0010 | float[6] | bounds (x1, y1, z1, x2, y2, z2) |
0x0020 | uint8 | population type (bitfield) |
0x0021 | uint8 | scumminess (bitfield) |
Block 11: Gangs
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | CGang[11] | gangs |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | char[4] | unknown (possibly unused) |
0x0008 | int[3] | weapons |
0x0010 | byte[3] | decides the chances for the weapons above |
0x0013 | byte | unknown (possibly unused) |
Note: The game will not give gangs the 2nd weapon in the array until the maximum wanted level reaches 5, and the 3rd weapon until the maximum wanted level reaches 6
Block 12: CarGenerators
This block stores Car Generators managed by scripts in GTA 4. This includes mission rewards and boats or helicopters disabled before Algonquin and Alderney are unlocked.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | CarGenerator[25] | Car Generators array (see below) |
0x044C | Unknown[15] | Unknown is 16 bytes each |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | float[3] | Position of the Parked Vehicle |
0x000C | float[2] | Rotation (X,Y) |
0x0014 | float[2] | Unknown (has something to do with Z rotation) |
0x001C | uint16_t | Model ID |
0x001E | uint16_t | Pool index (normally always 0) |
0x0022 | uint8_t | Color 1 |
0x0023 | uint8_t | Color 2 |
0x0024 | uint8_t | Color 3 |
0x0025 | uint8_t | Color 4 |
0x0026 | uint8_t[5] | Unknown (flags) |
0x002B | uint8_t | Enabled (0 = disabled, 101 = enabled) |
Block 13: Stats
This block has a constant length of 0x1724 or 0x173C bytes depending on the game version, and stores various statistics; most of which can be viewed the game's Stats menu. To get the offset of a stat from its ID, multiply the ID by 4 and add the offset for Start of stats (0x54 or 0x6C).
1.2.0.32 CE and older
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | dword | Size of block |
0x04 | byte[80] | unknown radio-related stats |
0x54 | float[]/int[] | Start of statistics by id |
0x1724 | end |
1.2.0.43 CE and newer
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | dword | Size of block |
0x04 | dword[3] | unknown integers |
0x10 | byte[92] | unknown radio-related stats |
0x6C | float[]/int[] | Start of statistics by id |
0x173C | end |
Block 14: IplStore
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | uint32 | length of the following array (500) |
0x0008 | bool[500] | an array of boolean (the wpl of that index will be loaded if true) |
Block 15: StuntJumps
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | dword | Size of block |
0x04 | byte | whether stunt jumps are enabled |
0x05 | dword | number of stunt jumps completed |
0x09 | dword | number of stunt jumps |
0x0E | byte[4] | total stunt jumps |
0x11 | StuntJump[64] | start of stunt jump structs (0x64 bytes each; see below) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | dword | pool index |
0x04 | float[4] | Start zone point 1 (x,y,z,w) |
0x14 | float[4] | Start zone point 2 (x,y,z,w) |
0x24 | float[4] | Land zone point 1 (x,y,z,w) |
0x34 | float[4] | Land zone point 2 (x,y,z,w) |
0x44 | float[4] | Camera coordinates (x,y,z,w) |
0x54 | dword | reward amount |
0x58 | byte | is completed |
0x59 | byte | is found |
0x5A | byte[10] | unknown, maybe align/padding |
Block 16: Radio
The radio station block stores the recently played tracks for radio stations in the game. It's used for music weights and to ensure two random tracks (like the weather reports) don't play right after each other.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | bool | is lazlow station locked |
0x0001 | uint8 | unknown |
0x0002 | bool | taxi garage radio state |
0x0003 | RadioStation[n] | radio station save data |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | RecentTracks | recently played news tracks |
0x0029 | RecentTracks | recently played weather reports |
0x0052 | RecentTracks | recently played adverts |
0x007b | uint8[256] | news stories state |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | RecentTracks | recently played ident tracks |
0x0029 | RecentTracks | recently played music tracks |
0x0052 | RecentTracks | recently played dj solo tracks |
0x007b | uint8 | unknown |
0x007c | short[10] | unknown array |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint8 | current position in the array |
0x0001 | uint[10] | track hash (as defined in GAME.DAT16) |
Note:
- n is the number of radio stations defined in the game. That's 20 for versions before Complete Edition, and 23 for Complete Edition.
Block 17: Objects
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | uint32 | object count |
0x0008 | Object[10] | objects (only mission cleanup objects are saved) |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | pool handle |
0x0004 | uint32 | model hash |
0x0008 | float[4] | coordinates (x,y,z,w) |
0x0018 | Matrix | compressed rotation matrix |
Block 18: Relationships
This block stores the relationship groups defined in Relations.dat.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint32 | block size |
0x0004 | Relationships[70] | Relationship groups |
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x0000 | uint96 | respect bitfield |
0x000C | uint96 | like bitfield |
0x0018 | uint96 | ? bitfield |
0x0024 | uint96 | dislike bitfield |
0x0030 | uint96 | ? bitfield |
0x003C | uint96 | hate bitfield |
Note:
- uint96 is a 12 byte (96 bits) integer.
- The array index corresponds to the ped type, so array index 1 will be the relations for ped type 1 (CIVMALE)
- The bits also correspond to the ped type, so the first bit in the bitfield will be for ped type 0 (PLAYER) and so on.
Block 19: Inventory
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 20: Pools
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 21: PhoneInfo
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 22: AudioScriptObject
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 23: SetPieces
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 24: Streaming
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 25: PedType
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 26: Tags
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 27: Shopping
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 28: GangWars
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 29: EntryExits
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 30: 3dMarkers
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Block 31: Vehicles
This block is empty; Data is neither stored nor read by the game in this block after the initial "BLOCK" string and the constant size (9)
Checksum
The checksum follows the last data block.
- The
savegame size in bytes
in the meta data should be set to1977922
(0x1E2E42), before calculating the checksum. - It is the sum of all the bytes preceding the checksum value.
- Implementation Example: A Python script for calculating the checksum value
Note:
- The reason is that the game adds the GFLW data size to the metadata after it has calculated the checksum.
- The checksum value is ignored by the game. An incorrect checksum will not prevent a save file from being loaded.
End Block
This block has a constant length of 0x16C bytes. Data in this block appears to relate to Games For Windows Live data.
OFFSET | TYPE | DESCRIPTION |
---|---|---|
0x00 | char[4] | END\0 |
0x04 | dword | Unknown, appears to always be 0x128 |
0x08 | byte[292] | Unknown, appears to always be a mix of 0x0, 0x1, 0x2 and 0x3 bytes |
0x12C | byte[64] | Unknown |
0x16C | end |
Savegame | |
---|---|
Formats | Saves (GTA 3) • Saves (GTA VC) • Saves (GTA SA) • Saves (GTA LCS) • Saves (GTA 4) |
Tools | GTASnP - Save File Sharing • GTAForums: GTASum Gamesave Checksum Calculator |
Resources | GTAForums: GTA III Save File Documentation • GTAForums: Vice City Save File Format • Savegames Formats Description |
Grand Theft Auto IV | |
---|---|
File Formats | .dat • .gxt • .ide • .img • .ipl • .nod • .sco • .rpf • .rrr • .wad • .wbd/.wbn • .wdd • .wdr • .wft • .whm • .wpl • .wtd |
Documentation | Audio • Bink Video • Cryptography • Cutscenes • GXT Text • Image listing • Keycodes • Map Listing • Native functions • Paths • Radar Blips • Radio Stations • Saves • Scenarios • VTable • Weapons |
Tools | ASI Loader • ENBSeries • G-Texture • GIMS IV • Ingame WPL Editor • IV Needle • OpenIV • SparkIV • XLiveLess • WPL Manager • X Mod Installer Alice • C++ Script Hook • .NET Script Hook • Scocl |
Tutorials | Importing Textures with OpenIV • Importing Textures with SparkIV |
Modifications | GTA Connected • Gostown IV • Four Multiplayer • IV Multiplayer • CitizenMP:IV Reloaded |
Useful links | Community portal • Discussion forums • Modding forums • Mods on GTAGarage.com |