Difference between revisions of "Saves (GTA 4)"

From GTAMods Wiki
Jump to navigation Jump to search
(Block 0: SimpleVars)
(Block 9: Radar: adding version difference note (I didn't want to duplicate the whole table))
 
(42 intermediate revisions by 6 users not shown)
Line 4: Line 4:
  
 
==Location==
 
==Location==
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.
 
  
The save files themselves are named in the format '''SGTA4XX''' where '''XX''' represents the in-game slot number. There are 12 slots available in the game (1-12) plus an additional auto-save slot (SGTA400).
+
===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==
Line 49: Line 56:
 
|0x00 ||char[5]      ||a "BLOCK" string
 
|0x00 ||char[5]      ||a "BLOCK" string
 
|-
 
|-
|0x04 ||dword         ||size of block in bytes (always 0xB9)
+
|0x05 ||dword         ||size of block in bytes (always 0xB9)
 
|-
 
|-
 
|0x09 ||dword         ||start of data; see below
 
|0x09 ||dword         ||start of data; see below
Line 61: Line 68:
 
!DESCRIPTION
 
!DESCRIPTION
 
|-
 
|-
|0x00 ||byte[32]      ||unknown data
+
| 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
 
|-
 
|-
|0x20 ||dword         ||length (ms) of in-game minute
+
| 0x0050 || uint32 || forced weather
 
|-
 
|-
|0x24 ||dword         ||weather timer (?)
+
| 0x0054 || uint32 || game hour fraction
 
|-
 
|-
|0x28 ||dword         ||in-game month
+
| 0x0060 || int || vehicle camera mode
 
|-
 
|-
|0x2C ||dword         ||in-game day
+
| 0x0064 || int || ped camera mode
 
|-
 
|-
|0x30 ||dword         ||in-game hours
+
| 0x0068 || int || don't zoom on aim
 
|-
 
|-
|0x34 ||dword         ||in-game minutes
+
| 0x0080 || int || max wanted level
 
|-
 
|-
|0x38 ||dword         ||in-game day of week
+
| 0x0084 || uint32 || max chaos level
 
|-
 
|-
|0x3C ||byte[116]    ||unknown data
+
| 0x0094 || uint32_t || waypoint blip
 
|-
 
|-
 
|0xB0 ||end ||
 
|0xB0 ||end ||
Line 84: Line 119:
  
 
==== Block 1: PlayerInfo ====
 
==== Block 1: PlayerInfo ====
 +
 
This block has a constant length of 0xD4 bytes.
 
This block has a constant length of 0xD4 bytes.
 +
 
{|class="wikitable"
 
{|class="wikitable"
 
!OFFSET
 
!OFFSET
Line 90: Line 127:
 
!DESCRIPTION
 
!DESCRIPTION
 
|-
 
|-
|0x00 ||dword ||Size of block
+
| 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
 
|-
 
|-
|0x04 ||byte[18] || unknown
+
| 0x0058 || uint32 || (current weapon slot?)
 
|-
 
|-
|0x1C ||dword ||Player money
+
| 0x005c || uint32[10] || weapon slots
 
|-
 
|-
|0x20 ||byte[4] || unknown
+
| 0x0084 || uint16[10] || weapons ammo
 
|-
 
|-
|0x24 ||dword ||Player money (Again. Perhaps one is amount shown on screen.)
+
| 0x00a4 || uint32 || [[SET_CHAR_PROP_INDEX|prop variation]]
 
|-
 
|-
|0x28 ||byte[172] ||unknown
+
| 0x00a8 || uint8[11] || [[GET_CHAR_DRAWABLE_VARIATION|drawable variation]]
 
|-
 
|-
|0xD4 ||end ||
+
| 0x00b3 || uint8[11] || [[GET_CHAR_TEXTURE_VARIATION|texture variation]]
 
|}
 
|}
 +
 +
</div>
  
 
==== Block 2: ExtraContent ====
 
==== Block 2: ExtraContent ====
==== Block 3: Scripts ====
 
==== Block 4: Garages ====
 
==== Block 5: GameLogic ====
 
==== Block 6: PathFind ====
 
==== Block 7: Pickups ====
 
==== Block 8: Restart ====
 
==== Block 9: Radar ====
 
==== Block 10: Zones ====
 
==== Block 11: Gangs ====
 
==== Block 12: CarGenerators ====
 
  
====Block 13: Stats====
+
 
This block has a constant length of 0x1724 bytes and stores [[List_of_statistics_(GTA4)|various statistics]]; most of which can be viewed the game's Stats menu.
 
 
{|class="wikitable"
 
{|class="wikitable"
 
!OFFSET
 
!OFFSET
Line 124: Line 199:
 
!DESCRIPTION
 
!DESCRIPTION
 
|-
 
|-
|0x00 ||dword ||Size of block
+
| 0x0000 || uint32 || block size
 
|-
 
|-
|0x04 ||byte[80] ||unknown stats
+
| 0x0004 || uint64 || flags (bit set for the active episode(s))
 
|-
 
|-
|0x54 ||float ||game_progress (GTA IV main story only. TLAD and TBoGT variables are below.)
+
| 0x000C || Episode[64] || episodes array
 +
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+Episode (65 bytes)
 
|-
 
|-
|0x58 ||float ||roman_like
+
| 0x0000 || uint8 || episode id
 
|-
 
|-
|0x5C ||float ||roman_respect
+
| 0x0001 || char[64] || episode name
 +
|}
 +
 
 +
</div>
 +
 
 +
==== Block 3: Scripts ====
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x60 ||float ||roman_mission_progress
+
|0x0000 || uint32 || size of block
 
|-
 
|-
|0x64 ||float ||vlad_mission_progress
+
|0x0004 || - || start of block (data below)
 +
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x65 ||float ||jacob_like
+
| 0x0000 || MissionCleanupEntry[456] || mission cleanup entries
 
|-
 
|-
|0x6C ||float ||jacob_respect
+
| 0x4E60 || uint32 || global variables size (size)
 
|-
 
|-
|0x70 ||float ||jacob_mission_progress
+
| 0x4E64 || uint32[size] || global variables array
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x74 ||float ||faustin_mission_progress
+
| 0x0000 || uint32 || unknown (value used for padding below) {{Note|unknown number}}
 
|-
 
|-
|0x78 ||float ||manny_mission_progress
+
| 0x0004 || int32 || xlive globals buffer size (n) {{Note|xlive buffers}}
 
|-
 
|-
|0x7C ||float ||elizabeta_mission_progress
+
| 0x0008 || uint8[n] || xlive globals buffer
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x80 ||float ||dwayne_like
+
| 0x0000 || uint32 || threads count
 
|-
 
|-
|0x84 ||float ||dwayne_respect
+
| 0x0004 || uint8[24][77] || thread names
 
|-
 
|-
|0x88 ||float ||dwayne_mission_progress
+
| 0x073C || uint32 || threads count
 
|-
 
|-
|0x8C ||float ||brucie_like
+
| 0x0740 || Thread[77] || threads
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x90 ||float ||brucie_respect
+
| ? || 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}}
 
|-
 
|-
|0x94 ||float ||brucie_mission_progress
+
| 0x0000 || uint32 || unknown
 
|-
 
|-
|0x98 ||float ||playboy_mission_progress
+
| 0x0004 || uint32 || last mission pass time
 
|-
 
|-
|0x9C ||float ||francis_mission_progress
+
| 0x0008 || Unknown[140] (Unknown is 44 bytes long) || unknown array (script store names)
 
|-
 
|-
|0xA0 ||float ||ulpc_mission_progress
+
| 0x17B0 || BuildingSwap[25] || building swap array
 
|-
 
|-
|0xA4 ||float ||packie_like
+
| 0x18DC || InvisibleObject[10] || invisible objects array
 
|-
 
|-
|0xA8 ||float ||packie_respect
+
| 0x192C || uint32 || ped queue membership size
 
|-
 
|-
|0xAC ||float ||packie_mission_progress
+
| 0x1930 || Unknown[8] (88 bytes each) || ped queue membership
 
|-
 
|-
|0xB0 ||float ||ray_mission_progress
+
| 0x1BF0 || uint32[10] || suppressed car models
 
|-
 
|-
|0xB4 ||float ||gerry_mission_progress
+
| 0x1C18 || ConnectedLOD[10] || connected lods
 
|-
 
|-
|0xB8 ||float ||derrick_mission_progress
+
| 0x1C68 || Unknown[16] (32 bytes each) || unknown (related to TXDs)
 
|-
 
|-
|0xBC ||float ||bernie_mission_progress
+
| 0x1E68 || Unknown[100] (48 bytes each) || unknown (related to textures)
 +
|}
 +
 
 +
<div style="margin-left: 5em;">
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+ConnectedLOD (8 bytes)
 
|-
 
|-
|0xC0 ||float ||bell_mission_progress
+
| 0x0000 || uint32 || object 1 pool index
 
|-
 
|-
|0xC4 ||float ||gambetti_mission_progress
+
| 0x0004 || uint32 || object 2 pool index
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+Invisibility Settings (8 bytes)
 
|-
 
|-
|0xC8 ||float ||jimmy_mission_progress
+
| 0x0000 || uint32 || type (0 = none, 2 = building, 3 = object, 4 = dummy object)
 
|-
 
|-
|0xCC ||float ||carmen_ortiz_fondness
+
| 0x0004 || uint32 || index in the respective pool
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+BuildingSwap (16 bytes)
 
|-
 
|-
|0xD0 ||float ||carmen_trust
+
| 0x0000 || uin32 || type (2 if building swap, 0 if empty)
 
|-
 
|-
|0xD4 ||float ||alex_chilton_fondness
+
| 0x0004 || uint32 || index of building in pool (0 if type is 0)
 
|-
 
|-
|0xD8 ||float ||alex_trust
+
| 0x0008 || uint32 || new model
 
|-
 
|-
|0xDC ||float ||kiki_jenkins_fondness
+
| 0x000C || uint32 || old model
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+Thread
 
|-
 
|-
|0xE0 ||float ||kiki_trust
+
| 0x0000 || uint8[24] || thread name
 
|-
 
|-
|0xE4 ||float ||michelle_fondness
+
| 0x0018 || uint32[2] || (unknown)
 
|-
 
|-
|0xE8 ||float ||michelle_trust
+
| 0x0020 || uint32 || saved death arrest stack off
 
|-
 
|-
|0xEC ||float ||kate_fondness
+
| 0x0024 || uint8 || (unknown)
 
|-
 
|-
|0xF0 ||float ||kate_trust
+
| 0x0025 || uint8 || is script safe for network game
 
|-
 
|-
|0xF4 ||byte[93] || unknown stats
+
| 0x0026 || uint8 || should the script be saved
 
|-
 
|-
|0x268 ||float ||tlad_game_progress
+
| 0x0027 || uint8 || is a minigame script
 
|-
 
|-
|0x26C ||byte[53] || unknown stats
+
| 0x0028 || uint8 || can remove blips created by any script
 
|-
 
|-
|0x340 ||float ||tbogt_game_progress
+
| 0x0029 || uint8 || (unknown)
 
|-
 
|-
|0x344 ||byte[65] || unknown stats
+
| 0x002A || uint32 || (unknown)
 
|-
 
|-
|0x448 ||dword ||DWORD missions_passed
+
| 0x002E || ThreadContext || script context
 
|-
 
|-
|0x44C ||dword ||missions_failed
+
| 0x0082 || uint32 || constant zero
 
|-
 
|-
|0x450 ||dword ||missions_attempted
+
| 0x0086 || uint32[] || script stack
 +
|}
 +
 
 +
<div style="margin-left: 5em;">
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x454 ||dword ||replays_used
+
| 0x0000 || uint32 || xlive buffer last index (n)
 
|-
 
|-
|0x458 ||dword ||people_killed
+
| 0x0004 || uint8[4 * n + 4] ||
 +
* xlive buffer data
 +
* only if (n) if greater than 0
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x45C ||dword ||taxi_fares_completed
+
| 0x0000 || uint32[] || unknown array (size is (1 + unknown last index{{ref|unknowns}}))
 +
|}
 +
 
 +
</div>
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+ThreadContext (84 bytes)
 
|-
 
|-
|0x460 ||dword ||times_cheated
+
| 0x0000 || uint32 || thread id
 
|-
 
|-
|0x464 ||dword ||days_passed
+
| 0x0004 || uint32 || script hash
 
|-
 
|-
|0x468 ||dword ||times_died
+
| 0x0008 || uint32 || state
 
|-
 
|-
|0x46C ||dword ||people_run_down
+
| 0x000C || uint32 || instruction pointer
 
|-
 
|-
|0x470 ||dword ||vehicles_exploded
+
| 0x0010 || uint32 || number of stack pointers {{Note|stack pointer}}
 
|-
 
|-
|0x474 ||dword ||flips_done_in_vehicle
+
| 0x0014 || uint32[3] || timers
 
|-
 
|-
|0x478 ||dword ||most_vehicle_air_spins
+
| 0x0024 || float || wait time
 
|-
 
|-
|0x47C ||dword ||air_launches
+
| 0x0050 || uint32 || unknown data last index {{Note|unknowns}}
 +
|}
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 +
|+MissionCleanupEntry (44 bytes)
 
|-
 
|-
|0x480 ||dword ||helicopter_tours_taken
+
| 0x0000 || byte || type
 
|-
 
|-
|0x484 ||dword ||taxis_hailed
+
| 0x0004 || uint32 || handle
 
|-
 
|-
|0x488 ||dword ||stunt_jumps_found
+
| 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
 
|-
 
|-
|0x48C ||dword ||stunt_jumps_completed
+
| 0x0000 || uint32 || garage count
 
|-
 
|-
|0x490 ||dword ||kills_since_last_save
+
| 0x0004 || uint8 || (unknown)
 
|-
 
|-
|0x494 ||dword ||fires_started
+
| 0x0005 || uint8 || resprays are free
 
|-
 
|-
|0x498 ||dword ||criminals_killed
+
| 0x0006 || uint8 || resprays are disabled
 
|-
 
|-
|0x49C ||dword ||cars_stolen
+
| 0x0007 || uint32 || (unknown)
 
|-
 
|-
|0x4A0 ||dword ||bikes_stolen
+
| 0x000B || uint32 || safehouse garage count
 
|-
 
|-
|0x4A4 ||dword ||boats_stolen
+
| 0x000F || StoredCar[20] || stored cars array
 
|-
 
|-
|0x4A8 ||dword ||helicopters_stolen
+
| 0x05AF || Garage[40] || garages array
 
|-
 
|-
|0x4AC ||dword ||stars_attained
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ StoredCar (72 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x4B0 ||dword ||stars_evaded
+
| 0x0000 || float[3] || position (x, y, z)
 
|-
 
|-
|0x4B4 ||dword ||vehicles_exported
+
| 0x000C || uint32 || handling flags
 
|-
 
|-
|0x4B8 ||dword ||bridges_flown_under
+
| 0x0010 || uint16 || model index
 
|-
 
|-
|0x4BC ||dword ||paynspray_visits
+
| 0x0032 || uint8[4] || colors
 
|-
 
|-
|0x4C0 ||dword ||times_got_drunk
+
| 0x0038 || uint32 || extras
 
|-
 
|-
|0x4C4 ||dword ||drug_packages_delivered
+
| 0x003C || uint32 || livery
 
|-
 
|-
|0x4C8 ||dword ||cars_sold_to_stevie
+
| 0x0043 || uint8[3] || rotation (x, y, z)
 
|-
 
|-
|0x4CC ||dword ||random_characters_met
+
| 0x0048 || uint16 || flags (see below)
 
|-
 
|-
|0x4D0 ||dword ||bullets_fired
+
|}
 +
 
 +
''' 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
 
|-
 
|-
|0x4D4 ||dword ||bullets_hit
+
| 0x0000 || uint8 || type
 
|-
 
|-
|0x4D8 ||dword ||kills_by_headshot
+
| 0x0001 || uint8 || open state
 
|-
 
|-
|0x4DC ||dword ||melee_kills
+
| 0x0002 || uint8 || door flags
 
|-
 
|-
|0x4E0 ||dword ||armed_kills
+
| 0x0004 || float[3] || position (x, y, z)
 
|-
 
|-
|0x4E4 ||dword ||__stat
+
| 0x0010 || float[2] || direction a (x, y)
 
|-
 
|-
|0x4E8 ||dword ||__stat
+
| 0x0018 || float[2] || direction b (x, y)
 
|-
 
|-
|0x4EC ||dword ||cars_exploded
+
| 0x0020 || float || top z
 
|-
 
|-
|0x4F0 ||dword ||bikes_exploded
+
| 0x0024 || float || (unknown)
 
|-
 
|-
|0x4F4 ||dword ||boats_exploded
+
| 0x0028 || float || (unknown)
 
|-
 
|-
|0x4F8 ||dword ||helicopters_exploded
+
| 0x002C || float || left coordinate
 
|-
 
|-
|0x4FC ||dword ||tires_popped_by_gunshot
+
| 0x0030 || float || right coordinate
 
|-
 
|-
|0x500 ||dword ||weapons_pickedup
+
| 0x0034 || float || front coordinate
 
|-
 
|-
|0x504 ||dword ||texts_received
+
| 0x0038 || float || back coordinate
 
|-
 
|-
|0x508 ||dword ||calls_made_on_phone
+
| 0x003C || uint32 || (unknown)
 
|-
 
|-
|0x50C ||dword ||calls_received_on_phone
+
| 0x0040 || uint32 || garage name hash
 
|-
 
|-
|0x510 ||dword ||prostitute_visits
+
| 0x0044 || uint8 || original type
 
|-
 
|-
|0x514 ||dword ||tramps_given_money_to
+
| 0x0045 || uint8 || safehouse garage index (if safehouse)
 
|-
 
|-
|0x518 ||dword ||emails_sent
+
|}
 +
</div>
 +
 
 +
==== Block 5: GameLogic ====
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x51C ||dword ||meals_eaten
+
| 0x0000 || uint32 || size of block
 
|-
 
|-
|0x520 ||dword ||hotdogs_eaten
+
| 0x0004 || uint8 || lose money on being wasted
 
|-
 
|-
|0x524 ||dword ||burgers_eaten
+
| 0x0005 || uint8 || lose weapons on getting busted
 
|-
 
|-
|0x528 ||dword ||nuts_eaten
+
| 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
 
|-
 
|-
|0x52C ||dword ||binoculars_used
+
|0x00 ||char[5]      || a "BLOCK" string
 
|-
 
|-
|0x530 ||dword ||player_died_by_melee
+
|0x04 ||dword         || size of block in bytes (always 0xD55A)
 
|-
 
|-
|0x534 ||dword ||player_shot_to_death
+
|0x08 ||int         || total number of pickups
 
|-
 
|-
|0x538 ||dword ||player_was_blown_up
+
|0x0C ||Pickup[650]  || pickups array
 
|-
 
|-
|0x53C ||dword ||player_was_roadkill
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ Pickup
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x540 ||dword ||scored_with_girl
+
|0x00 ||int32_t    || index (-1 indicates unused pickup)
 
|-
 
|-
|0x544 ||dword ||pool_wins
+
|0x04 ||dword       || unknown
 
|-
 
|-
|0x548 ||dword ||pool_defeats
+
|0x08 ||dword       || unknown
 
|-
 
|-
|0x54C ||dword ||pool_clearances_from_break
+
|0x0C ||dword       || amount (ammo, etc.)
 
|-
 
|-
|0x550 ||dword ||darts_wins
+
|0x10 ||dword       || unknown
 
|-
 
|-
|0x554 ||dword ||darts_defeats
+
|0x14 ||dword       || unknown
 
|-
 
|-
|0x558 ||dword ||darts_180s_hit
+
|0x18 ||int32      || blip
 
|-
 
|-
|0x55C ||dword ||darts_bullseyes
+
|0x1C ||dword       || timer
 
|-
 
|-
|0x560 ||dword ||darts_shortest_checkout
+
|0x20 ||Vector3    || location (x,y,z)
 
|-
 
|-
|0x564 ||dword ||bowling_high_score
+
|0x2C ||dword       || unknown
 
|-
 
|-
|0x568 ||dword ||bowling_wins
+
|0x30 ||dword       || unknown
 
|-
 
|-
|0x56C ||dword ||bowling_draws
+
|0x34 ||Vector3    || rotation
 
|-
 
|-
|0x570 ||dword ||bowling_defeats
+
|0x40 ||dword       || unknown
 
|-
 
|-
|0x574 ||dword ||bowling_spares
+
|0x44 ||int16      || object ID
 
|-
 
|-
|0x578 ||dword ||bowling_perfects
+
|0x46 ||int16      || reference number
 
|-
 
|-
|0x57C ||dword ||bowling_strikes
+
|0x48 ||byte        || pickup type
 
|-
 
|-
|0x580 ||dword ||total_races_lost
+
|0x49  ||byte        || flags
 
|-
 
|-
|0x584 ||dword ||total_races_won
+
|0x4A  ||byte        || flags
 
|-
 
|-
|0x588 ||dword ||south_broken_wins
+
|0x4B  ||byte        || pickup type (HiddenPackage = 3)
 
|-
 
|-
|0x58C ||dword ||south_broker_races
+
|0x4C  ||dword       || unknown
 
|-
 
|-
|0x590 ||dword ||airport_run_wins
+
|0x50  ||dword       || unknown
 
|-
 
|-
|0x594 ||dword ||airport_run_races
+
|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
 
|-
 
|-
|0x598 ||dword ||dukes_blvd_wins
+
| 0x0000 || uint32 || wasted restart point count
 
|-
 
|-
|0x59C ||dword ||dukes_blvd_races
+
| 0x0004 || RestartPoint[10] || [[ADD_HOSPITAL_RESTART|wasted restart points array]]
 
|-
 
|-
|0x5A0 ||dword ||south_algonquin_wins
+
| 0x00F4 || uint32 || busted restart point count
 
|-
 
|-
|0x5A4 ||dword ||south_algonquin_races
+
| 0x00F8 || RestartPoint[20] || [[ADD_POLICE_RESTART|busted restart points array]]
 
|-
 
|-
|0x5A8 ||dword ||star_junction_wins
+
| 0x02D8 || uint32 || safehouse count
 
|-
 
|-
|0x5AC ||dword ||star_junction_races
+
| 0x02DC || Safehouse[6] || [[REGISTER_SAVE_HOUSE|safehouses array]]
 
|-
 
|-
|0x5B0 ||dword ||road_to_bohan_wins
+
| 0x0432 || uint8 || [[OVERRIDE_NEXT_RESTART|override next restart]]
 
|-
 
|-
|0x5B4 ||dword ||road_to_bohan_races
+
| 0x0433 || float[4] || overridden restart point coordinates (x, y, z, w)
 
|-
 
|-
|0x5B8 ||dword ||north_alderny_wins
+
| 0x0443 || float || overriden restart point heading
 
|-
 
|-
|0x5BC ||dword ||north_alderny_races
+
| 0x0447 || uint8 || [[SUPPRESS_FADE_IN_AFTER_DEATH_ARREST|supress fade in after death arrest]]
 
|-
 
|-
|0x5C0 ||dword ||elevated_wins
+
| 0x0448 || RestartPoint || [[SET_EXTRA_HOSPITAL_RESTART_POINT|extra wasted restart point]]
 
|-
 
|-
|0x5C4 ||dword ||elevated_races
+
| 0x0460 || RestartPoint || [[SET_EXTRA_POLICE_STATION_RESTART_POINT|extra busted restart point]]
 
|-
 
|-
|0x5C8 ||dword ||south_alderny_wins
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ RestartPoint (24 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x5CC ||dword ||south_alderny_races
+
| 0x0000 || float[4] || coordinates (x, y, z, w)
 
|-
 
|-
|0x5D0 ||dword ||qub3d_high_score
+
| 0x0010 || float || heading
 
|-
 
|-
|0x5D4 ||dword ||boating_destinations
+
| 0x0014 || uint32 || town (0 = Broker and Dukes, 1 = Algonquin, 2 = Alderney)
 
|-
 
|-
|0x5D8 ||dword ||heli_ride_destinations
+
|}
 +
 
 +
{|class="wikitable"
 +
|+ Safehouse (57 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x5DC ||dword ||activities_with_roman
+
| 0x0000 || float[4] || coordintaes (x, y, z, w)
 
|-
 
|-
|0x5E0 ||dword ||activities_with_jacob
+
| 0x0010 || float || heading
 
|-
 
|-
|0x5E4 ||dword ||activities_with_brucie
+
| 0x0014 || char[32] || name
 
|-
 
|-
|0x5E8 ||dword ||activities_with_dwayne
+
| 0x0034 || uint32 || town (see above)
 
|-
 
|-
|0x5EC ||dword ||activities_with_packie
+
| 0x0038 || uint8 || [[ENABLE_SAVE_HOUSE|enabled]]
 
|-
 
|-
|0x5F0 ||dword ||vigilante_levels_done
+
|}
 +
 
 +
</div>
 +
 
 +
==== Block 9: Radar ====
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x5F4 ||dword ||most_wanted_completed
+
| 0x0000 || uint32 || block size
 
|-
 
|-
|0x5F8 ||dword ||pigeons_exterminated
+
| 0x0004 || uint32 || "centre blip" index/id
 
|-
 
|-
|0x5FC ||dword ||first_aid_collected
+
| 0x0008 || uint32 || "north blip" index/id
 
|-
 
|-
|0x600 ||dword ||islands_unlocked
+
| 0x000C || uint32 || "simple blip" index/id
 
|-
 
|-
|0x604 ||dword ||total_dates
+
| 0x0010 || uint32 || saved blips count
 
|-
 
|-
|0x608 ||dword ||successful_dates
+
| 0x0014 || Blip[150] || blips array
 
|-
 
|-
|0x60C ||dword ||bad_dates
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ Blip (100 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x610 ||dword ||girls_dumped
+
| 0x0000 || uint32 || blip index
 
|-
 
|-
|0x614 ||dword ||emails_received
+
| 0x0004 || bool || not a simple blip
 
|-
 
|-
|0x618 ||dword ||photos_taken
+
| 0x0005 || uint16 || flags
 
|-
 
|-
|0x61C ||dword ||mocap_cutscenes_skipped
+
| 0x0007 || float[4] || position (x, y, z, w)
 
|-
 
|-
|0x620 ||dword ||mocap_cutscenes_watched
+
| 0x001F || char[30] || sprite name * <sup>see note below</sup>
 
|-
 
|-
|0x624 ||dword ||cutscenes_skipped
+
| 0x003D || uint16 || blip id?
 
|-
 
|-
|0x628 ||dword ||cutscenes_watched
+
| 0x003F || uint32 || mission cleanup handle
 
|-
 
|-
|0x62C ||dword ||sodas_drunk
+
| 0x0043 || uint32 || priority
 
|-
 
|-
|0x630 ||dword ||kills_with_unarmed
+
| 0x0047 || uint32 || type (only type 4, 8 and 5 are saved)
 
|-
 
|-
|0x634 ||dword ||kills_with_baseball_bat
+
| 0x004B || uint32 || display
 
|-
 
|-
|0x638 ||dword ||kills_with_poolcue
+
| 0x004F || float || scale
 
|-
 
|-
|0x63C ||dword ||kills_with_knife
+
| 0x0053 || uint32 || colour id
 
|-
 
|-
|0x640 ||dword ||kills_with_grenade
+
| 0x0057 || uint8 || alpha
 
|-
 
|-
|0x644 ||dword ||kills_with_molotov
+
| 0x0058 || uint32 || sprite hash?
 
|-
 
|-
|0x648 ||dword ||kills_with_rocket
+
| 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
 
|-
 
|-
|0x64C ||dword ||kills_with_pistol
+
| 0x0000 || uint32 || block size
 
|-
 
|-
|0x650 ||dword ||kills_with_combat_pistol
+
| 0x0004 || uint32 || zone count
 
|-
 
|-
|0x654 ||dword ||kills_with_pump_shotgun
+
| 0x0008 || Zone[300] || zones
 
|-
 
|-
|0x658 ||dword ||kills_with_combat_shotgun
+
| 0x2EE0 || char[100] || (unknown) (likely unused)
 
|-
 
|-
|0x65C ||dword ||kills_with_micro_smg
+
| 0x2F44 || uint32 || (unknown) (likely unused)
 
|-
 
|-
|0x660 ||dword ||kills_with_smg
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ Zone (40 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x664 ||dword ||kills_with_assault_rifle
+
| 0x0000 || char[8] || name
 
|-
 
|-
|0x668 ||dword ||kills_with_carbine_rifle
+
| 0x0008 || char[8] || gxt entry (also used for audio)
 
|-
 
|-
|0x66C ||dword ||kills_with_combat_sniper
+
| 0x0010 || float[6] || bounds (x1, y1, z1, x2, y2, z2)
 
|-
 
|-
|0x670 ||dword ||kills_with_sniper_rifle
+
| 0x0020 || uint8 || population type (bitfield)
 
|-
 
|-
|0x674 ||dword ||kills_with_rpg
+
| 0x0021 || uint8 || scumminess (bitfield)
 
|-
 
|-
|0x678 ||dword ||kills_with_flame_thrower
+
|}
 +
</div>
 +
 
 +
==== Block 11: Gangs ====
 +
 
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x67C ||dword ||kills_with_minigun
+
| 0x0000 || uint32 || block size
 
|-
 
|-
|0x680 ||dword ||kills_with_episodic_1
+
| 0x0004 || CGang[11] || gangs
 
|-
 
|-
|0x684 ||dword ||kills_with_episodic_2
+
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ CGang (20 bytes)
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x688 ||dword ||kills_with_episodic_3
+
| 0x0000 || char[4] || unknown (possibly unused)
 
|-
 
|-
|0x68C ||dword ||kills_with_episodic_4
+
| 0x0008 || int[3] || [[List_of_Weapons_(GTA4)|weapons]]
 
|-
 
|-
|0x690 ||dword ||kills_with_episodic_5
+
| 0x0010 || byte[3] || decides the chances for the weapons above
 
|-
 
|-
|0x694 ||dword ||kills_with_episodic_6
+
| 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
 
|-
 
|-
|0x698 ||dword ||kills_with_episodic_7
+
| 0x0000 || CarGenerator[25] || Car Generators array (see below)
 
|-
 
|-
|0x69C ||dword ||kills_with_episodic_8
+
| 0x044C || Unknown[15] || Unknown is 16 bytes each
 +
|}
 +
 
 +
<div style="margin-left: 3em;">
 +
{|class="wikitable"
 +
|+ CarGenerator
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x6A0 ||dword ||kills_with_episodic_9
+
| 0x0000 || float[3] || Position of the Parked Vehicle
 
|-
 
|-
|0x6A4 ||dword ||kills_with_episodic_10
+
| 0x000C || float[2] || Rotation (X,Y)
 
|-
 
|-
|0x6A8 ||dword ||kills_with_episodic_11
+
| 0x0014 || float[2] || Unknown (has something to do with Z rotation)
 
|-
 
|-
|0x6AC ||dword ||kills_with_episodic_12
+
| 0x001C || uint16_t || Model ID
 
|-
 
|-
|0x6B0 ||dword ||kills_with_episodic_13
+
| 0x001E || uint16_t || Pool index (normally always 0)
 
|-
 
|-
|0x6B4 ||dword ||kills_with_episodic_14
+
| 0x0022 || uint8_t || Color 1
 
|-
 
|-
|0x6B8 ||dword ||kills_with_episodic_15
+
| 0x0023 || uint8_t || Color 2
 
|-
 
|-
|0x6BC ||dword ||kills_with_episodic_16
+
| 0x0024 || uint8_t || Color 3
 
|-
 
|-
|0x6C0 ||dword ||kills_with_episodic_17
+
| 0x0025 || uint8_t || Color 4
 
|-
 
|-
|0x6C4 ||dword ||kills_with_episodic_18
+
| 0x0026 || uint8_t[5] || Unknown (flags)
 
|-
 
|-
|0x6C8 ||dword ||kills_with_episodic_19
+
| 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
 
|-
 
|-
|0x6CC ||dword ||kills_with_episodic_20
+
|0x00 ||dword ||Size of block
 
|-
 
|-
|0x6D0 ||dword ||kills_with_episodic_21
+
|0x04 ||byte[80] ||unknown radio-related stats
 
|-
 
|-
|0x6D4 ||dword ||kills_with_episodic_22
+
|0x54 ||float[]/int[] ||Start of [[List_of_statistics_(GTA4)|statistics by id]]
 
|-
 
|-
|0x6D8 ||dword ||kills_with_episodic_23
+
|0x1724 ||end ||
 +
|}
 +
 
 +
1.2.0.43 CE and newer
 +
{|class="wikitable"
 +
!OFFSET
 +
!TYPE
 +
!DESCRIPTION
 
|-
 
|-
|0x6DC ||dword ||kills_with_episodic_24
+
|0x00 ||dword ||Size of block
 
|-
 
|-
|0x6E0 ||dword ||times_busted
+
|0x04 ||dword[3] ||unknown integers
 
|-
 
|-
|0x6E4 ||dword ||saves_made
+
|0x10 ||byte[92] ||unknown radio-related stats
 
|-
 
|-
|0x6E8 ||byte[4156] ||unknown stats
+
|0x6C ||float[]/int[] ||Start of [[List_of_statistics_(GTA4)|statistics by id]]
 
|-
 
|-
|0x1724 ||end ||
+
|0x173C ||end ||
 
|}
 
|}
  
 
==== Block 14: IplStore ====
 
==== 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 ====
 
==== Block 15: StuntJumps ====
 
{|class="wikitable"
 
{|class="wikitable"
Line 568: Line 985:
 
|0x00 ||dword         ||Size of block
 
|0x00 ||dword         ||Size of block
 
|-
 
|-
|0x04 ||byte[5] ||unknown
+
|0x04 ||byte ||whether stunt jumps are enabled
 
|-
 
|-
|0x09 ||dword         ||number of stunt jumps
+
|0x05  || dword || number of stunt jumps completed
 
|-
 
|-
|0x0E ||byte[4] ||unknown
+
|0x09 ||dword         ||number of stunt jumps
 
|-
 
|-
|0x11 || ||start of stunt jump structs (0x64 bytes each; see below)
+
|0x0E ||byte[4] ||total stunt jumps
 +
|-
 +
|0x11 || StuntJump[64] || start of stunt jump structs (0x64 bytes each; see below)
 
|}
 
|}
  
Line 584: Line 1,003:
 
!DESCRIPTION
 
!DESCRIPTION
 
|-
 
|-
|0x00 ||byte ||unknown
+
|0x00 ||dword || pool index
 
|-
 
|-
|0x01 ||byte ||id
+
|0x04 ||float[4] ||Start zone point 1 (x,y,z,w)
 
|-
 
|-
|0x02 ||byte[2] ||unknown, maybe padding/align
+
|0x14 ||float[4] ||Start zone point 2 (x,y,z,w)
 
|-
 
|-
|0x04 ||float[3] ||Start zone point 1 (x,y,z)
+
|0x24 ||float[4] ||Land zone point 1 (x,y,z,w)
 
|-
 
|-
|0x10 ||byte[4] ||unknown
+
|0x34 ||float[4] ||Land zone point 2 (x,y,z,w)
 
|-
 
|-
|0x14 ||float[3] ||Start zone point 2 (x,y,z)
+
|0x44 ||float[4] ||Camera coordinates (x,y,z,w)
 
|-
 
|-
|0x20 ||byte[4] ||unknown
+
|0x54 ||dword ||reward amount
 
|-
 
|-
|0x24 ||float[3] ||Land zone point 1 (x,y,z)
+
|0x58 ||byte ||is completed
 
|-
 
|-
|0x30 ||byte[4] ||unknown
+
|0x59 ||byte ||is found
 
|-
 
|-
|0x34 ||float[3] ||Land zone point 2 (x,y,z)
+
|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
 
|-
 
|-
|0x40 ||byte[4] ||unknown
+
| 0x0000 || bool || [[LOCK_LAZLOW_STATION|is lazlow station locked]]
 
|-
 
|-
|0x44 ||float[3] ||Camera coordinates (x,y,z)
+
| 0x0001 || uint8 || unknown
 
|-
 
|-
|0x50 ||byte[4] ||unknown
+
| 0x0002 || bool || [[SET_TAXI_GARAGE_RADIO_STATE|taxi garage radio state]]
 
|-
 
|-
|0x54 ||dword ||Reward ammount
+
| 0x0003 || RadioStation[n] || radio station save data
 
|-
 
|-
|0x58 ||byte ||is completed
+
|}
 +
{|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
 
|-
 
|-
|0x59 ||byte ||is found
+
| 0x0000 || uint8 || current position in the array
 
|-
 
|-
|0x5A ||byte[10] ||unknown, maybe align/padding
+
| 0x0001 || uint[10] || track hash (as defined in GAME.DAT16)
 
|}
 
|}
 +
 
</div>
 
</div>
  
==== Block 16: Radio ====
+
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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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 ====
 
==== 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===
 
===Checksum===
After the last data block the checksum value goes. The checksum appears to be the sum of most of the bytes preceding it, however, which bytes exactly is unknown (See [[Talk:Saves_(GTA_4)#Block_32:_Checksum|discussion]]).
+
 
 +
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===
 
===End Block===

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
SimpleVars
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
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 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
Episode (65 bytes)
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
ConnectedLOD (8 bytes)
0x0000 uint32 object 1 pool index
0x0004 uint32 object 2 pool index
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
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
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
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
OFFSET TYPE DESCRIPTION
0x0000 uint32[] unknown array (size is (1 + unknown last index[unknowns]))
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 ^
0x0014 uint32[3] timers
0x0024 float wait time
0x0050 uint32 unknown data last index ^
OFFSET TYPE DESCRIPTION
MissionCleanupEntry (44 bytes)
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
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

  • 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.
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)

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
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)

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
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)
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 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
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 * 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)
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)

Block 11: Gangs

OFFSET TYPE DESCRIPTION
0x0000 uint32 block size
0x0004 CGang[11] gangs
CGang (20 bytes)
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
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)

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)
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

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
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
RecentTracks (41 bytes)
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
Object (72 bytes)
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
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

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 to 1977922 (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