Tes4Mod:Save File Format

The format used for save files (.ess files) in Oblivion is a binary format, different from that used for mod files.  The overall structure of the save file format is largely understood, but in many cases the specifics of the data contents have not yet been decoded. 

You can make a text dump overview of a save game's contents by using the   ( ) or   ( ) console commands. Simply append a non-zero value to the command arguments, eg:   or  . It will generate a text file named with the same filename as your save game, but with .txt appended, eg:   will generate a "test.ess.txt" file.  The dump file contains a list of all the save file's Change Records (sorted by type and length).

Within a save file, most object references use iref values, instead of FormIDs.  An iref can be translated into a FormID using the FormIDs Array.  However, iref values greater than 0xFF000000 are actual FormIDs, and refer to objects created within the save file.  These created objects are detailed either in the Change Records section of the save file (for individual object references, i.e. ACHR, ACRE and REFR record types) or in the createdData array (for other record types).

See File Format Conventions for conventions used to document variables and datatypes.

File Header
If the first four characters of a save game file are "CON ", then the file is from an Xbox 360, and the Xbox 360 File Container has not been removed.  The real game data starts after 53248 bytes.  However, simply skipping the first 53248 bytes of the file is not sufficient.  The File Container format also inserts other chunks of information into the Oblivion save file, independent of the Oblivion save file format.  These are 4-16 KB pieces that typically appear somewhere after the first 600KB or so of "real" game data.  Therefore any file starting with a "CON " record needs to have the container information removed (for example, using WxPirs) before it can be parsed according to the format on the rest of this page (and before it can be read by the PC version of Oblivion).  See Xbox 360 for more information on accessing Xbox 360 save files.



Save Game Header


Plugins


Global


Change Records
This section consists of a collection of records documenting changes to data objects supplied by the master mods, and new objects added during game play.  The number of records is provided by recordsNum.  The total size of a record is provided in dataSize, so records can be skipped past relatively easily.

However, processing any record details requires a fairly comprehensive understanding of the record format, dictated by the record type, the flags for that record, and then further influenced by the contents of the sub-records.  The record type controls which sub-records may appear and their order and the flags (roughly) list which sub-records appear.  Unlike sub-records in mod files, the individual sub-records are not clearly demarcated, nor are their sizes provided.  Therefore, each sub-record needs to be processed, in order, before subsequent records can be read.  Separate subarticles describe the format of each record type; those articles are linked under the list of types.

Newly-created types of objects (custom spells, enchantments, etc.) are listed in the createdData section.  For example, if the player creates a custom-enchanted ring, the ENCH record detailing the enchantment and the CLOT record detailing the ring are both listed under createdData.  Any individual instances of that ring are listed in Change Records -- whether as REFR objects, or as inventory entries for the player's ACHR object, or inventory entries for a container's REFR object.



|-
| 
:flags
| ulong
| Flags indicating what has been changed.  The meaning of each flag depends upon the type of record; all known values are documented on the individual record subpages (see above table).  Most flags have a corresponding sub-record in the record data.

For example, an NPC_ record might have 0x1000027c as the flags, indicating that the following changes have been made to the record
2: Form Flags
3: Base Health
4: Base Attributes
5: Spell List
6: Factions
9: Skills
28: Base Modifiers
Note that these flags values do not indicate the order used to list the corresponding change sub-records.   The sub-record Overview provides the order of the sub-records, showing, for example that Base Health (3) is detailed after the Spell List (5).

|-
| 
:version
| ubyte
| Version of change record; value is 125.  See minorVersion for details
|-
| 
:dataSize
| ushort
| Total size of the data section (of all the change sub-records).
|-   
| 
:data
| ubyte[dataSize]
| Collection of change sub-records.  The format of the change sub-records depends upon the type of record; see the individual record type subpages for details.
|}

Temporary Effects
The temporary effects listed in this section are effect shaders (EFSH objects).  Temporary magic effects, such as the effects listed in the player Journal's Active Effects sections, are listed within the appropriate ACHR change record.



FormIds Array
The FormIds array is located at formIdsOffset.  It allows iref values to be deferenced into FormIds.  Although the formIds array starts at index 0, iref 0 is always empty (0x00000000); 1 is the smallest valid value for an iref, and the corresponding formid is the second entry in the formIds array.  Iref=0 is used in cases where the value is unchanged relative to the original.

FormIds for objects created in-game are not included in the FormIds array. "irefs" are only dereferenced using the FormId array if they are less than 0xFF000000; otherwise, the iref is actually a FormID.



World Spaces Array
''Probably an array that maps internal references to world space formIds. But if that's so, doesn't it duplicate functionality of FormId array?''