Savegame Structure

Fallout and Fallout 2 savegames are slot directories, not a single archive file. The central file is SAVE.DAT, but visited maps, automap data, companion prototype overrides, backups, and sfall/CE extension files can live beside it in the same SAVEGAME\SLOT## folder.

SAVE.DAT is not a normal Fallout DAT archive. It is a big-endian binary stream written as a header followed by 27 save/load handler sections. The handler sections have no section id or length prefix in the file; the engine knows the order from its save/load handler table.

Slot Directory

Save slots are stored below SAVEGAME\SLOT01 through SAVEGAME\SLOT10. Paths are relative to the configured master patches/data directory in the original engine and Fallout 2 CE.

PathDescription
SAVEGAME\SLOT##\SAVE.DATMain save stream: header, player/global state, worldmap state, party state, queue state, and module-owned runtime data.
SAVEGAME\SLOT##\*.SAVCompressed saved-map files copied from temporary MAPS\*.SAV files. Names match the map save names listed inside handler 3 of SAVE.DAT.
SAVEGAME\SLOT##\AUTOMAP.SAVCompressed copy of MAPS\AUTOMAP.DB. The size of the uncompressed automap database is also written in handler 3.
SAVEGAME\SLOT##\proto\critters\*.proCompressed saved prototype overrides for party-member critter PIDs.
SAVEGAME\SLOT##\proto\items\*.proCompressed saved prototype overrides for party-member item PIDs, when a party entry points at an item prototype.
SAVEGAME\SLOT##\sfallgv.savFallout 2 CE/sfall-compatible sidecar for sfall global variables and extension sections.
*.BAKTemporary backup files made while overwriting a slot. They are normally removed after a successful save.

The engine also uses temporary working files outside the slot. Before saving, it writes the current map state under MAPS\*.SAV, then compresses those files into the selected slot. When loading, it clears the working MAPS\*.SAV files and decompresses the slot's saved maps back into MAPS\ before loading the current map.

Compression

The map and prototype sidecar files in a save slot are gzip-compressed. The decompressed map .SAV data has the same broad structure as a saved MAP file. Saved party prototype files decompress to normal PRO data.

SAVE.DAT itself is not gzip-compressed and is not a DAT archive. It should be read directly as a binary stream. Most numbers in the engine-owned save stream use the same big-endian file helpers as other Fallout binary formats.

SAVE.DAT Header

The header is fixed-size: 0x7563 bytes, or decimal 30051. After the header, the 27 handler sections follow immediately.

OffsetSizeFieldDescription
0x000024Signature bufferContains FALLOUT SAVE FILE. Fallout 2 CE writes a 24-byte buffer and validates only the first 18 bytes.
0x00182Version word 0CE writes the major version word and expects 1 when loading normal Fallout 2 saves.
0x001A2Version word 1CE writes the minor version word and expects 2.
0x001C1Release byteCE expects ASCII R. Together the version check is effectively 1.2R.
0x001D32Character nameCurrent dude/player name, fixed buffer.
0x003D30Save descriptionUser-entered slot description, fixed buffer. The UI limits input to 29 characters plus terminator.
0x005B2Real dayLocal real-world day of month when saved.
0x005D2Real monthLocal real-world month, 1..12.
0x005F2Real yearLocal real-world year.
0x00614Real time fieldCE writes hour + minute, matching the original odd field rather than a normal clock encoding.
0x00652Game monthGame date month from the game-time system.
0x00672Game dayGame date day.
0x00692Game yearGame date year.
0x006B4Game timeCurrent game time in engine ticks.
0x006F2ElevationCurrent elevation when saved.
0x00712Map indexCurrent map index from the map system.
0x007316Current map save filenameCurrent map header name converted to a .SAV filename.
0x008329792Preview imageLoad/save thumbnail: 224 * 133 bytes of 8-bit indexed pixels.
0x7503128ReservedCE writes zero bytes and skips them when loading.

The preview is captured from the isometric window and stored as raw indexed pixels. It is not an FRM, RIX, or image file with its own header.

SAVE.DAT Handler Order

After the header, SAVE.DAT contains 27 sections in hardcoded order. The file does not store section names or sizes. Fallout 2 CE logs the size read/written for each handler during debug builds, but those sizes are diagnostic output, not part of the format.

#Save handlerLoad handlerContents
0_DummyFunc_PrepLoadNo bytes are saved. Loading resets game state, sets the wait cursor, clears the current map name, and restores game time from the header.
1_SaveObjDudeCid_LoadObjDudeCidOne int32: the player's current combat id (gDude->cid).
2scriptsSaveGameGlobalVarsscriptsLoadGameGlobalVarsAll game global variables from the active GAM global table.
3_GameMap2Slot_SlotMap2GameVisited map list, map sidecar compression/decompression, companion PRO sidecar copying, and uncompressed automap DB size.
4scriptsSaveGameGlobalVarsscriptsSkipGameGlobalVarsDuplicate copy of the game global variables. Loading reads and discards this second copy.
5_obj_save_dude_obj_load_dudeThe player object in normal object serialization format, followed by the current center tile.
6critterSavecritterLoadPlayer critter state: sneak flag plus the dude's critter prototype data.
7killsSavekillsLoadKill counts by kill type.
8skillsSaveskillsLoadFour tagged skill ids.
9randomSaverandomLoadNo real random generator state in CE; both handlers call the roll reset helper.
10perksSaveperksLoadPerk ranks for each PARTY.TXT description slot and each perk id.
11combatSavecombatLoadCombat state. If not in combat, only the combat-state word is present. In combat, turn/list/combat AI tracking data follows.
12aiSaveaiLoadMutable AI.TXT packet records for party-member critter prototypes whose AI packet disposition is custom/mutable.
13statsSavestatsLoadPlayer character stats array: unspent skill points, level, experience, and related PC stat fields.
14itemsSaveitemsLoadIn CE this shared handler returns without storing meaningful bytes. Older notes list this as unused.
15traitsSavetraitsLoadTwo selected trait ids, with -1 for unused slots.
16automapSaveautomapLoadOne int32 automap flag word. Detailed automap map data is handled separately through AUTOMAP.SAV.
17preferencesSavepreferencesLoadGameplay/UI/audio preferences such as difficulty, violence, highlighting, volumes, brightness, and mouse sensitivity.
18characterEditorSavecharacterEditorLoadLevel-up UI state: last character-editor level and whether a free perk is available.
19wmWorldMap_savewmWorldMap_loadSerialized worldmap state, also used by worldmap.dat.
20pipboySavepipboyLoadNo meaningful bytes in CE; the shared helper is effectively empty.
21gameMoviesSavegameMoviesLoadMVE movie-seen flags for Pip-Boy video archives and movie availability.
22skillsUsageSaveskillsUsageLoadSkill-use timestamps: SKILL_COUNT * SKILLS_MAX_USES_PER_DAY int32 values.
23partyMembersSavepartyMembersLoadActive party length, party inventory-count helper, party member object ids, and companion level-up tracking data.
24queueSavequeueLoadTimed event queue: count, event time, event type, owner object id, and event-type-specific payload.
25interfaceSaveinterfaceLoadInterface bar enabled/hidden state, active hand slot, and combat/end button visibility.
26_DummyFunc_EndLoadNo bytes are saved. Loading restarts worldmap music, restores the dude name, refreshes UI, and requests combat if loaded into combat.

Handler Details

Global Variables

Handlers 2 and 4 both write the entire global variable array from the game scripts module. CE's load path reads handler 2 into the active array and skips handler 4 into a temporary buffer. The duplicate exists in the original format and should be preserved by writers that want save compatibility.

The number of global variables is the active GAM global count. If a mod changes vault13.gam or the global variable list, old saves can become difficult to interpret because these sections are raw arrays without names.

Map Sidecars

Handler 3 starts by preparing party members for save, saving the current map into the working MAPS\ directory, and copying party-member PRO files into the slot. It then scans MAPS\*.SAV, writes the count, writes each null-terminated filename, and gzip-compresses each working map save into the slot.

int32 map_save_count
repeat map_save_count:
    char filename[] including trailing NUL
int32 automap_db_uncompressed_size

The matching load handler clears working saved maps and saved party PRO overrides, decompresses the slot's party PRO sidecars into proto\critters or proto\items, decompresses each listed map save into MAPS\, decompresses AUTOMAP.SAV into MAPS\AUTOMAP.DB, reads the stored automap DB size, and finally calls mapLoadSaved for the current map filename stored in the header.

The filename reader used by CE's load path accepts at most 14 bytes before the terminator. This matches short DOS-style map save names such as ARROYO.SAV. Long saved-map names are unsafe even if the filesystem allows them.

Player Object

Handler 5 serializes the player object using the same object serializer used by MAP object lists. Before saving, CE temporarily clears the dude object's OBJECT_NO_SAVE flag and temporarily sets the dude script id to -1. After object serialization it restores those runtime fields and writes one extra int32: gCenterTile.

On load, CE reads a temporary object, copies it over the global dude object, restores the persistent object id, recreates the dude script, restores placement, and reads the center tile. This makes the section closely related to MAP object serialization, but with player-specific fixups around scripts and object identity.

Critter, Perk, Trait, Skill, and Stat State

Handlers 6, 8, 10, 13, 15, 18, and 22 together describe much of the player and companion character state:

HandlerFields
6 critterSaveOne sneak flag plus the dude's critter prototype data. Older docs describe this as matching critter PRO data beginning at the critter-stat payload.
8 skillsSaveNUM_TAGGED_SKILLS, normally four int32 skill ids.
10 perksSavegPartyMemberDescriptionsLength * PERK_COUNT int32 rank values.
13 statsSavePC_STAT_COUNT int32 values. In normal Fallout 2 this includes unspent skill points, level, experience, and derived PC-level bookkeeping.
15 traitsSaveTwo int32 trait ids.
18 characterEditorSaveOne int32 last-level value plus one byte free-perk flag.
22 skillsUsageSaveSkill-use history array, used for per-day limitations such as First Aid and Doctor use.

Many visible stats are not stored in just one place. For example, level and experience are PC stat values, base and bonus SPECIAL values are part of critter prototype data, perk ranks are stored per party-member description slot, and temporary radiation/poison/drug behavior can also involve queued events.

Combat

Handler 11 always writes the combat-state word. If the game is not in combat, that is the whole section. If combat is active, CE writes turn/free-move/experience fields, combatant counts, the dude combat id, each combatant's combat id, and per-combatant AI tracking ids for friendly-dead, last-target, last-item, and last-move state.

On load, if the combat-state word says the game is not in combat, CE only clears invalid whoHitMe pointers for critters. If it is in combat, it rebuilds the combat list from current-elevation critters and resolves saved combat ids back to objects.

Party AI

Handler 12 serializes mutable AI packets associated with party-member critter prototypes. CE iterates gPartyMemberPids, finds critter PIDs, gets the prototype's AI packet, and writes the packet only when its disposition marks it as mutable/custom.

Each stored AI packet is the same field sequence described by the AI.TXT page: packet number, distance/to-hit/HP/aggression settings, combat-message ranges, called-shot preferences, weapon/distance/target/drug/run modes, and three chem desire values. The saved data has no per-record count; the reader must reproduce the same party-member iteration to know how many packets to read.

Worldmap State

Handler 19 writes the same worldmap state handled by worldmap.dat. CE writes the Frank Horrigan flag, current area, world coordinates, visible encounter icon state, encounter ids, car state, city records, entrance visibility states, tile/subtile fog states, and special encounter records.

The save stream does not include the whole editable worldmap text config trio. It stores runtime state over the configuration data loaded from worldmap.txt, city.txt, and related message/list files.

Party Members

Before map sidecars are written, CE prepares party members by clearing OBJECT_NO_REMOVE and OBJECT_NO_SAVE on non-player party objects and clearing removed/no-save script flags. After copying the map and prototype sidecars, CE restores those flags.

Handler 23 itself writes:

int32 active_party_member_count
int32 party_member_item_count
repeat active_party_member_count - 1:
    int32 party_member_object_id
repeat party_description_count - 1:
    int32 level
    int32 num_level_ups
    int32 is_early

The player is party member 0 and is not written in the object-id loop. On load, object ids are resolved against loaded map objects. If an object cannot be found, CE has fallback/recovery behavior, but missing party objects are still a strong sign that the saved map/object sidecars and the party section disagree.

Queue Events

Handler 24 stores the event queue as a count followed by queue records:

int32 event_count
repeat event_count:
    uint32 event_time
    int32 event_type
    int32 owner_object_id_or_-2
    event-specific payload

The payload depends on the event type's registered write/read functions. This is where delayed script events, radiation/poison/drug events, explosion actions, and other scheduled runtime behavior can be preserved. An external parser that cannot decode a particular event type cannot safely skip it unless it knows that event type's payload size.

Interface, Movies, Preferences, Automap Flags

These handlers are small but useful for save editors:

HandlerStored data
16 automapSaveOne automap flag word. The heavy automap database is AUTOMAP.SAV.
17 preferencesSave13 int32 gameplay/UI settings, one float text-base-delay, four int32 volume values, one float brightness, and one float mouse sensitivity.
21 gameMoviesSaveMOVIE_COUNT bytes of movie-seen flags.
25 interfaceSaveTwo booleans for interface bar state, one int32 current hand, and one boolean for combat/end button visibility.

sfallgv.sav

Fallout 2 CE writes an optional sfallgv.sav file after SAVE.DAT. In CE, the file begins with sfall global-variable data through sfall_gl_vars_save. CE then writes placeholder zero sections for several sfall-compatible extension blocks: next object id, added years, fake traits, fake perks, fake selectable perks, old array data, new array data, and drug pid data.

When loading, CE only reads the sfall global variables and silently ignores the remaining sections. Full sfall builds may use more of this file. Treat it as a sidecar extension format, not as a section inside SAVE.DAT.

Save Overwrite and Backups

When overwriting an existing slot, CE first backs up SAVE.DAT as SAVE.BAK, renames existing slot .SAV files to .BAK, and copies AUTOMAP.SAV to AUTOMAP.BAK if it exists. If the save fails, it erases the partial save and restores the backups. If the save succeeds, the backup .BAK files are removed.

This means a slot can briefly contain both current and backup files during an interrupted save. Tools should avoid treating stray .BAK files as authoritative save content unless they are deliberately implementing recovery.

Clean MAP vs Saved SAV

A saved map sidecar is a compressed runtime map snapshot. It preserves live objects, inventories, script records, map variables, local script variables, object flags, queued state, door/container state, critter combat data, and other values described on the MAP page. Clean mapper-authored .MAP files describe initial state; saved .SAV maps describe state after gameplay.

The main SAVE.DAT map handler only lists and copies those sidecar files. The actual object/script/tile/map-variable payload is inside the decompressed saved MAP data.

Compatibility Notes

Practical Parser Strategy

  1. Open SAVE.DAT as an uncompressed binary file.
  2. Read and validate the fixed 0x7563-byte header.
  3. Decode handler sections in exact engine order.
  4. For handler 3, collect the saved map filenames and inspect the corresponding compressed .SAV files in the slot.
  5. Decompress saved map files before parsing them with the MAP format.
  6. Decompress saved party PRO files before parsing them with the PRO format.
  7. Load or model the same supporting tables as the game: GAM, PARTY.TXT, AI.TXT, SCRIPTS.LST, worldmap config, and message files.
  8. Treat unknown or module-owned sections as runtime state, not as independent named resources.

Source Code Map

Source symbolRole
LOAD_SAVE_SIGNATURE, LoadSaveSlotDataHeader signature and UI/header metadata fields.
lsgSaveHeaderInSlot, lsgLoadHeaderInSlotExact fixed header layout.
_master_save_list, _master_load_listHardcoded 27-section SAVE.DAT handler order.
lsgPerformSaveGame, lsgLoadGameInSlotTop-level save/load flow, backup handling, and sfallgv.sav sidecar handling.
_GameMap2Slot, _SlotMap2GameMap sidecar list, gzip copy/decompress behavior, party PRO sidecars, and automap DB sidecar.
_obj_save_dude, _obj_load_dudePlayer object serialization and player-specific fixups.
scriptsSaveGameGlobalVars, scriptsLoadGameGlobalVars, scriptsSkipGameGlobalVarsGlobal variable sections and duplicate skip behavior.
wmWorldMap_save, wmWorldMap_loadWorldmap runtime state section.
queueSave, queueLoadTimed event queue section.
partyMembersSave, partyMembersLoadParty roster and companion level-up state.
aiSave, aiLoadMutable party AI packet state.

References

History

2026-05-07 - Added slot-level savegame structure, SAVE.DAT header, handler order, map/proto sidecars, sfall sidecar notes, and source-backed compatibility guidance.