Oblivion Mod:Save File Format/Properties
The Properties structure appears in a couple different places. Within ACHR, ACRE, and REFR change records it can appear as a section containing several possible subrecords; in this case, the described properties are those of the overall change record's item. In addition, every item listed in an Inventory can also be accompanied by one or more property structures. The overall format of the Properties structure is the same in each of these cases, as are the values and structures of the individual property flags (although some flags have only been seen in limited locations).
The following table summarizes the overall Properties structure. This represents the entire contents of the Properties section found in ACHR, ACRE, and REFR change records. Within an Inventory, one of these structures will appear for each listing in changeEntries (i.e., this structure is already listed within the overall Inventory data structure).
Name | Type/Size | Info |
---|---|---|
propertiesNum | short | Number of properties changed in this structure. |
property | struct[propertiesNum] | Structure detailing an individual property change. |
|
byte | Flag indicating which property has been changed The following table lists known values for the flag. |
|
var | Changed property value, The type of value and its length depends upon the flag; see the following table. (Value is not present for flags with zero-length data) |
A large number of property flags have been encountered so far, as summarized in the following table. However, the actual meanings of many flags are unknown. The emphasis has been on determining the size/structure associated with each flag, since this must be known before the rest of the property structure (and generally the rest of the change record) can be processed. The provided information has been sufficient to completely parse all of the analyzed save files. Furthermore, the table is probably incomplete: it seems likely that all gaps in the table are just uncommon flags that have not yet been seen.
flag | value | Type/Size | Seen in | #Seen | Info |
---|---|---|---|---|---|
0x11 | Worldspace | iref | ACHR, ACRE | 30969 | iref points to a WRLD record |
0x12 | Script | variable | Inv, ACHR, ACRE, REFR | 140223 | |
|
iref | 4520 | iref points to a script (SCPT) record | ||
|
ushort | Number of values set | |||
|
struct[varNum] | values of changed script variables | |||
|
ushort | Variable index | |||
|
ushort | Variable type flag: 0x0000 = Local (8-byte double); 0xF000 = Reference (iref) | |||
|
iref | Reference Variable Value (only appears if varType=0xF0000) | |||
|
double (8 bytes) | Local Variable (only appears if varType=0x0000). Note that, according to SCPT quote: "...savegames store all numbers (despite their short, long, float designation) as doubles (64 bit floats)..." | |||
|
byte | ?indicates records end? | |||
0x1b | Equipped | 0 | Inv | 286587 | Item is currently equipped. Appears to be used for weapons, armor, and most types of clothing (except rings and amulets). |
0x1c | Equipped | 0 | Inv | 145 | Item is currently equipped. Appears to only be used for rings and amulets. |
0x1e | xMarkerHeadingRef | byte[20] | ACHR, ACRE | 84778 | Details of structure are speculative. |
|
iref | iref points to a WRLD or CELL record | |||
|
float | ||||
|
float | ||||
|
float | ||||
|
ulong | ||||
0x1f | AIPack | byte[14] | ACHR, ACRE | 1503 | Property was originally documented as being 8 bytes; the 6 extra bytes seem to always be empty (0x00) |
|
iref | iref points to an AI package (PACK record) | |||
|
ubyte[4] | It seems that only the first byte is essential | |||
|
iref | unknown | |||
|
ubyte[2] | Mostly both bytes are zero, but at least one occasion was encountered where these bytes where [0x1, 0x1] | |||
0x20 | Trespass | byte[63] | ACHR | 33 | The first 4 bytes have special significance, since they are repeated in the text dump file. They appear to be the formID of a temporary object. Considered part of "Trespass" subrecord. |
0x21 | unknown | variable | ACHR, ACRE | 5162 | |
|
ushort | ||||
|
byte[5][dataNum] | 5 bytes are possibly iref+byte; iref points to a PACK record | |||
0x22 | unknown | iref | Inv, REFR | 5776 | iref points to a REFR, ACHR, or ACRE record. Considered part of All Extra subrecord. |
0x23 | unknown | variable | Inv, ACHR, ACRE | 1013 | |
|
ushort | ||||
|
iref[dataNum] | iref always points to an ACHR record | |||
0x25 | Disabled | 0 | ACHR, ACRE | 441 | Corresponds to flag 30 being set, and textdumps listing status as Disabled. Used for quest NPCs after they've transformed and quest done (Peryite's souls, Forlorn Watchman) |
0x27 | Owner | iref | Inv, ACHR, ACRE, REFR | 11796 | iref points to the NPC_ or FACT (faction) record that owns this item. Signals that item is stolen when found in an inventory record. Used for ACRE records in cases of owned horses. |
0x28 | globVar | iref | 0 | iref points to a global variable (GLOB record); see XGLB subrecord under REFR mod file format. Information has not been confirmed from actual save files. | |
0x29 | factRank | ulong | 0 | Faction rank; see XRNK subrecord under REFR mod file format. Information has not been confirmed from actual save files. | |
0x2a | affectedItemsNum | ushort | Inv, REFR | 217490 | Number of items affected by this properties record. Considered part of "All Extra" subrecord. |
0x2b | itemHealth | float | Inv, REFR | 17503 | Item's current health. Considered part of "All Extra" subrecord. |
0x2c | uses | ubyte | number of uses for this item | ||
0x2d | time | float | Inv | 85 | Length of time that item (e.g., a torch) has been used. |
0x2e | enchPoints | float | Inv, REFR | 1910 | Current enchantment points. Whereas the ANAM subrecord for a WEAP record provides the maximum possible enchantment, this is the available enchantment points (0 if the weapon is completely discharged). Considered part of "All Extra" subrecord. |
0x2f | soul | byte | Inv | 223 | Type of soul contained in a soul gem (SLGM, see SOUL subrecord) |
0x31 | Lock | struct[6] | REFR | 23410 | Lock level and key that opens lock; see XLOC subrecord under REFR mod file format. |
|
ubyte | 0-100; 100 means key required | |||
|
iref | iref points to key (KEYM record) that opens lock; 0x00000000 if there is no key | |||
|
ubyte | 0x04 means lock is leveled | |||
0x32 | Teleport | struct[28] | REFR | 18 | Appears to provide the same information as the XTEL subrecord under REFR mod file format, although the data is provided in a different order than in XTEL. Considered part of "Teleport" subrecord. |
|
float | ||||
|
float | ||||
|
float | ||||
|
float | ||||
|
float | ||||
|
float | ||||
|
iref | iref points to a REFR record (with a DOOR base object) | |||
0x33 | Map Marker Flag | ubyte | REFR | Considered part of the "Map Marker Flag" subrecord | |
0x35 | Leveled Creature | - | ACHR, ACRE, REFR | 69907 | |
0x36 | Leveled Item | byte[5] | Inv | 600520 | |
0x37 | Scale | float | Inv | 3076 | Item scale; see XSCL subrecord under REFR mod file format. This property is not considered part of the "Scale" subrecord. |
0x39 | Non Actor Magic Caster | byte[12] | REFR | 2684 | Considered part of "Extra Magic" subrecord. The last 4 bytes always seem to be an iref pointing to the record containing this property. |
0x3a | unknown | variable | REFR | 7295 | Considered part of "Extra Magic" subrecord. Meaning of contents unknown. |
|
iref | Always appears to be an iref pointing to the record containing this property | |||
|
ushort | ||||
|
byte[61][dataNum] | ||||
0x3c | unknown | long? | Identified load code for this property just skips 4 bytes | ||
0x3d | Crime gold | float | Inv, ACHR, ACRE | 77 | Considered part of the "Crime Gold" subrecord. |
0x3e | Oblivion Entry | struct[16] | Inv, ACHR | 3 | Considered part of the "Oblivion Entry" subrecord. |
|
iref | iref points to the REFR record for the Oblivion end of a gate to Oblivion | |||
|
float | ||||
|
float | ||||
|
float | ||||
0x41 | unknown | float? | REFR | 140 | Considered part of the "All Extra" subrecord |
0x47 | Cant Wear | 0 | Inv | 83 | Only seen on items that are also equipped, for example on Ulrich Leland's prison clothes (Sack Cloth Shirt, etc.), and on Mythic Dawn assassin's bound armor/weapons. Seems to be for items that can't be worn by the player. |
0x48 | Poison | iref | Inv | 48 | iref points to the poison (ALCH record) that has been applied to a weapon |
0x4a | Animation | bstring | ACHR, ACRE, REFR | 40026 | Considered part of the "Animation" subrecord (although additional "Animation" data may also be provided outside of the property structure). Meaning of contents is unknown. |
0x4b | Movement Extra | variable | ACHR, ACRE, REFR | 134338 | Considered part of the "Movement Extra" subrecord (although additional "Movement Extra" data may also be provided outside of the property structure). Meaning of contents is unknown. |
|
ulong | ||||
|
ushort | ||||
|
ubyte[dataNum] | ||||
|
byte[2] | 2 extra bytes (always 0x00) appear after the 0x4b property but only if 0x4b is not the last property in the structure. Although their presence seems to be an anomaly, they are definitely there, and the two blank bytes do not count as a separate property. Conversely, there are countless cases where 0x4b is the last entry in the properties structure and the two bytes are clearly not there. | |||
0x4e | unknown | variable | ACHR, ACRE | 121 | Originally documented as always being 2 bytes in length, but cases have been confirmed with both dataNum=0 (2 byte length) and dataNum=1 (12 byte length). |
|
ushort | ||||
|
byte[10][dataNum] | ||||
0x4f | unknown | bytes[4] | Inv, ACHR, ACRE | 75535 | |
0x50 | boundItem? | 0 | Inv | 15 | Seen on Mythic Dawn Assassin's bound armor and weapons (along with flags 0x1b and 0x47) |
0x52 | investmentGold | ulong | ACHR | 32 | amount of gold player has invested in merchant. Considered part of the "Investment Gold" subrecord. |
0x53 | unknown | ulong? | REFR | 230 | Considered part of the "All Extra" subrecord. |
0x55 | shortcutKey | byte | Inv | 489 | User defined shortcut key |
0x59 | Conversation | variable | ACHR | 276 | |
|
bzstring | Topic Text, last byte (0x0) terminates string and is not included in the string length | |||
|
ushort | ||||
|
|||||
|
ubyte | consecutive number | |||
|
iref | iref points to a QUST record | |||
|
iref | iref points to a DIAL record | |||
|
iref | iref points to an INFO record | |||
0x5a | Essential? | ubyte | ACHR | 19 | Appears to be 0/1 value corresponding to last setEssential call on the character. |
0x5c | unknown | float | ACHR | 991 | Property seems to only be set for merchants; observed values in range 0-38. Number of items bought/sold from merchant? |
Notes:
- The "#Seen" column is the total number of times each property has been seen within a set of analyzed save files. This column provides an indication of the confidence in the property's size and structure -- although some of the rarely-seen properties are also the ones that have been examined most closely. In addition, this column may help programmers know which flags they must be prepared to encounter. For example, even though the Script flag (0x12) is one of the most annoying to parse, it's also one of the most common flags and therefore cannot be avoided.
- The "Seen In" column shows where, to date, each property flag has been seen, "Inv" meaning within an Inventory. However, just because a flag has not yet been seen in a given location does not mean that it can never appear there. For example, if a filled soul gem were dropped on the ground, it seems very likely that flag 0x2f would be set on the new REFR item, even though the above table only lists 0x2f for Inventory items.
- Many of the properties are considered to be parts of specific subrecords within the ACRE/ACHR/REFR change records. Although such associations are listed in the Notes, the information is not needed when processing save files. They are only relevant when interpreting the (often inaccurate) subrecord sizes listed in text file dumps. The subrecord names may also hint at the property's meaning, for otherwise unknown properties.