Layout of Daggerfall savetree.dat Files
AcknowledgementsEdit
The Quest Hacking guides on Dave Humphrey's Unofficial Elder Scrolls Pages and DaggerWeb (the hacking guide is now on Michael Schneider's site) started me looking into the format of the QBN files. I reached a point where I decided that a better understanding of the save file and its relation to the QBN files was required. My effort has gone in that direction, and I hope that what I find here will help those working on the QBN files. Further, I'd like to thank the many people that figured out most of the information for the character records and for the item records. A lot of what is in here is taken directly from what they found.
NotesEdit
All numbers given in this document are in hexadecimal. Numbers written as XX XX XX are in the same byte order as they would appear in the savetree.dat file. Numbers written as XXXX are short words, and the two bytes are reversed from their order in the file. Numbers written as XXXXXXXX are long words, and the four bytes are reversed from their order in the file.
Level One: Base StructureEdit
Savetree.dat has begins with a header record a 0x13 bytes in length. This is followed by a variable number of variable sized records( there does not appear to be any counts of records, or any offsets, or any other information useful to extracting records). Each record begins with an Int32 field indicating the length of the record's data, excluding this 4 byte field. Some records report 0 length, possibly used to separate the file into human-manageable blocks as per the following structure:
- 0x13 byte header
- Town record (zero length if not in town)
- Monster, character, and item records
- 0-sized record
- Quest records
- 0-sized record
- Dungeon info (Note: this size must be multiplied by 0x27!)
- 0-sized record
- End-of-file
Level Two: Record StructureEdit
With the exception of the Town record and the Dungeon info, each begins with a 1-byte field indicating the record's type. This is immediately followed by a 0x46 byte common structure that contains all sorts of interesting data, most of it uninterpretable by myself. The parts that are fairly clear are:
06 | 0c bytes of location data |
1e | 04 byte object ID |
25 | 01 byte quest ID |
26 | 04 byte parent object ID |
42 | 04 byte parent record type |
I don't know much about the location data, but I have a suspicion that it is interpreted as 3 Int32 values, where each value represents the X, Y, or Z position of the object in question. Some records don't have a location that makes sense, and some are contained within other records (e.g. objects carried by the character).
- The object ID is a unique eight-digit number for every item. Records start around 065636XX for the very first items you get in the game, which is your starting equipment. The ID numbers advance with every new item found in the game. Therefore all items owned by the player have an ID of the form 06XXXXXX, since it is very unlikely that anyone will ever play a single game long enough to acquire more than 500,000 items. Sometimes parchments (Letters of Credit ?) have identical object IDs.
Quest relevant objects, e.g. quest objects or inventory items of quest relevant enemies have a much higher numerical ID starting at about 458858XX. Like all items their IDs advance with every new item. The ID of any quest relevant item will turn to a 06XXXXXX ID when it is added permanently to the player's inventory.
- The parent object ID is the unique ID of the record the item belongs to. These are
- 00000700 for any quest object
- 00075541 for any weapon or armor
- 00075542 for any magic item, including the player's spellbook
- 00075543 for any clothing or miscellaneous item
- 00075544 for any ingredient
- A unique number of the form 000XXXXX for any item in the player's wagon, which is identical for all items
- 06XXXXXX for any item in the player's house and/or ship; for example 06613979 is the parent object ID of the first treasure pile in the house and/or ship, 06613980 for the second and so on, thus the parent object ID refers to the treasure pile the item is stored.
- The parent record type is (you guessed it!) the record type byte that the parent object ID references. It is a unique item specific number, which is identical for all items of a kind, e.g. all daggers have the same parent record ID.
- The Quest ID associates the record with a particular quest. Every quest that the character is involved in has a unique ID. These IDs start at 1 for the first active quest, 2 for the second active quest and so on. Numbers are recycled once a quest is over, but no ID lower than that of the latest active quest is used. Only quest relevant items e.g. quest objects, letters and rewards have this ID. For other items this ID is always 0.
Level Three: Record ContentsEdit
I have identified a number of record types and some of their contents, although the rest of the records remain a mystery to me.
Record TypesEdit
Hex Type | Item Description |
---|---|
01 | Player's Position |
02 | Item Records |
03 | Character Record - one per save file |
04 | Character Record parent - unknown purpose |
05 | Character Record parent - unknown purpose |
06 | Unknown |
08 | Unknown |
09 | Spells and Spell Effects |
0a | Guild Membership Records |
0e | QBN Records - slight differences between these records and the QBN files, but still recognizable. |
10 | Parent for QBN records |
12 | Parent for QBN records |
16 | Spellcasting creatures - spell list head |
17 | Control Setting Records - detail, volume |
18 | Location Names, possibly logbook entries |
19 | Bank Accounts |
1f | Potion mixing records |
20 | Unknown, Linked to TOWN record structure |
21 | Unknown, usually in dungeon saves |
22 | Creature record |
24 | Possibly items on store shelves |
27 | Mystery Record - referenced, but doesn't exist in file |
28 | Location names - possibly for quests |
29 | Location names - possibly for quests |
2b | Mystery Record - referenced, but doesn't exist in file |
2c | Creature record |
2d | NPC records |
2e | Generic NPC Records |
33 | Dungeon record? Huge, mostly zero filled |
34 | Container Records |
36 | Item left for repair |
40 | Unknown Records, all are part of a 'container' |
41 | Unknown, Possibly quest information |
Record ContentsEdit
Time StampsEdit
There are a few special fields that need interpretation. Time stamps are recorded in minutes of game time starting from point 0x0. Tamriel has 12 months per year, 30 days per month, 24 hours per day, and 60 minutes per hour. Point 0x0 is per definition 00:00, 1st of Morning Star, 3E 404. The actual game starts 0x07fd0a in-game minutes from this point which is 13:30, 4th of Morning Star, 3E 405. The first 4 bytes of any AMF- and ATF-file contain also a time stamp of this kind and indicate the date when the respective dungeon or town was last visited by the player.
File HeaderEdit
This is a 0x13-byte-long structure found in the beginning of the save file.
Offset | Description | Field Type |
---|---|---|
0x00 | Version | UInt32 |
0x04 | X-Coordinate | Int32 |
0x08 | Y-Coordinate | Int32 |
0x0c | Z-Coordinate | Int32 |
0x10 | Location code | UInt16 |
0x11 | Zone type | UInt8 |
Valid version values are 0x125 and 0x126. Location code is taken from MAPS.BSA.
Record type: Item (02)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Name | CHAR | 20 |
0020 | category | SHORT | 02 |
0024 | Value | LONG | 02 |
002c | Hits | SHORT | 03 |
0032 | Picture | SHORT | 02 |
0036 | Material | BYTE | 01 |
0037 | Construction | BYTE | 01 |
0038 | Colour | BYTE | 01 |
0039 | Weight | LONG | 01 |
003d | Enchant Pts | SHORT | 01 |
003f | Message | SHORT | 01 |
0041 | Magic | SHORT | 18 |
Record type: Character (03, ...)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | name | CHAR | 0x20 |
0020 | curstat | SHORT | 0x08 |
0030 | basstat | SHORT | 0x08 |
0040 | gender | BYTE | 0x01 |
0041 | transportation | BYTE | 0x01 |
0042 | material resistance | BYTE | 0x01 |
0043 | race | BYTE | 0x01 |
0044 | armor | BYTE | 0x07 |
0058 | start sum | LONG | 0x01 |
0070 | opponent | LONG | 0x01 |
007c | health | SHORT | 0x02 |
0080 | portrait | BYTE | 0x01 |
0081 | level | BYTE | 0x01 |
0083 | reflex | BYTE | 0x01 |
0085 | gold | LONG | 0x01 |
008d | mana | SHORT | 0x02 |
0091 | reputation | SHORT | 0x05 |
009d | Skills | SHORT+LONG | 0x23 |
016f | Equipped | LONG | 0x1b |
01fd | Last time fed | LONG | 0x01 |
0201 | Timestamp | LONG | 0x04 |
0230 | resist | BYTE | 0x01 |
0231 | immune | BYTE | 0x01 |
0232 | low tolerance | BYTE | 0x01 |
0233 | crit weakness | BYTE | 0x01 |
0234 | flags | SHORT | 1 |
0236 | rapid heal | BYTE | 1 |
0237 | regen health | BYTE | 1 |
0238 | unknown | BYTE | 1 |
0239 | spell absorb | BYTE | 1 |
023a | hit/phobia | BYTE | 1 |
023b | forb material | SHORT | 1 |
023d | crit weakness | BYTE | 1 |
023e | forbidden armor | SHORT | 1 |
0240 | Class Primary | BYTE | 3 |
0243 | Class Major | BYTE | 3 |
0246 | Class Minor | BYTE | 6 |
024c | Class Name | CHAR | 18 |
0264 | HP/Level | SHORT | 01 |
026a | Start stats | SHORT | 08 |
Record type: Unknown (06)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Unknown | SHORT | 10 |
0020 | Location | SHORT | 6 |
NOTE: This record type is referenced by what I think are the dungeon descriptions.
Record type: Spell (09)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | effects | BYTE | 0x06 |
0006 | Element | BYTE | 0x01 |
0007 | Range/AoE | BYTE | 0x01 |
0008 | cost | WORD | 0x03 |
000e | Duration | BYTE | 0x09 |
0017 | Probability | BYTE | 0x09 |
0020 | Strength1 | BYTE | 0x05 |
0025 | Strength2 | BYTE | 0x05 |
002a | Strength3 | BYTE | 0x05 |
002f | Name | CHAR | 0x14 |
0048 | Icon | BYTE | 0x01 |
0049 | Spell ID | BYTE | 0x01 |
004a | Remaining duration | WORD | 0x03 |
0050 | Actual magnitude | WORD | 0x03 |
0056 | Actual chance | BYTE | 0x03 |
NOTE: each spell can have 3 effects. Each effect is recorded as two bytes in the 'effects' field, an entry of FF FF indicates there is no effect. Each effect has its own 3-byte probability (base + chance/level) and a 3-byte duration (same). The strength for each effect is (low, high, low per level, high per level, and level) taken straight from the spell creation window.
Record type: Guild (0a)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Rank | LONG | 0x01 |
0002 | 0x01 | SHORT | 0x01 |
0003 | GuildID | LONG | 0x01 |
0005 | Timestamp (Date of last promotion) | LONG | 0x02 |
000A | Other |
Record type: Bank Accounts (19)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Total Sum in Account | LONG | 0x01 |
0004 | Sum Loaned + Interest | LONG | 0x01 |
0008 | Date Loan is payable | LONG | 0x01 |
000c | Unknown (always 0) | Unknown | 0x01 |
NOTE: Records start at offset 0x46 with the Bank of Alik'r Desert. Every 0x0d bytes the bank records for the next region begin. All 62 Regions of the Iliac Bay have a bank record, even these regions that don't exist.
Record type: "Destination" (28. 29)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Questor | SHORT | 1 |
0002 | LINK | LONG | 1 |
0006 | Destination | CHAR | 20 |
NOTE: This record can have multiple entries of Questor, LINK, and Destination. I don't know what provides the count or the terminating sentinel.
Record type: Item Group (34)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0000 | Unknown | unknown | unknown |
NOTE: All items owned by the character have a `parent link' back to a type 34 record. This appears to be the grouping of an item: whether it is on the character, in the cart, weapon list, etc. The type of group is determined by a value in the header for the record.
Record type: Item left for repair (36)Edit
Offset | Description | Field Type | Count |
---|---|---|---|
0030 | Town item is left | LONG | 0x01 |
NOTE: The location of the town corresponds with that location which is found in the MAPS.BSA file.
Other Goofy ThingsEdit
The Town and Dungeon records don't have an identifying type byte. I don't know much about them, but Ive been using the following fields to dump these records, which are in themselves a list of records of some type.
- TOWN (1a bytes)
- 1*SHORT, 0x10*BYTE, 2*BYTE, 1*LONG, 2*BYTE
- DUNGEON(27 bytes)
- 2*SHORT, 1f*BYTE, 1*LONG
The long values look to be record ID's, much as found in the common headers of all the other record types.
The records for Potions aren't simply enchanted items. In fact, the potion is a linked record of "glass bottle", indicating that the bottle itself isn't the magic, the contents are! The potion contains both a list of the ingredients that went into the mixture, and a spell effect list.
SAVEVARS.DATEdit
My small contribution to the savevars.dat file is that the current game date is saved at offset 0x3c9.
Faction ReputationEdit
All reputation relevant data is stored in this file. Reputation records for the various groups start at offset 0x17D0 (starting games saved with version 1.0.175). Each record has a size of 92 bytes.
Offset | Description | Field Type | Count |
---|---|---|---|
000 | Faction Type | BYTE | 0x01 |
001 | Region | BYTE | 0x01 |
002 | Ruler | BYTE | 0x01 |
003 | Name | CHAR | 0x26 |
01D | Reputation Value | SHORT | 0x01 |
01F | Faction Power | SHORT | 0x01 |
021 | Faction ID | SHORT | 0x01 |
023 | Vampire Clan ID | SHORT | 0x01 |
025 | Flags | SHORT | 0x01 |
027 | Unknown | BYTE | 0x08 |
02F | Image Index (male) | BYTE | 0x01 |
030 | Texture-File | BYTE | 0x01 |
031 | Image Index (female) | BYTE | 0x01 |
032 | Texture-File | BYTE | 0x01 |
033 | Portrait (male) | BYTE | 0x01 |
034 | Portrait (female) | BYTE | 0x01 |
035 | Race | BYTE | 0x01 |
036 | Social Group | BYTE | 0x01 |
037 | Guild Group | BYTE | 0x01 |
038 | ID of First Ally | LONG | 0x01 |
03C | ID of Second Ally | LONG | 0x01 |
040 | ID of Third Ally | LONG | 0x01 |
044 | ID of First Enemy | LONG | 0x01 |
048 | ID of Second Enemy | LONG | 0x01 |
04C | ID of Third Enemy | LONG | 0x01 |
050 | Unkown | BYTE | 0x12 |
Faction TypeEdit
Valid values are seen below.
Type | Value |
---|---|
Daedra | 0x00 |
God | 0x01 |
Group | 0x02 |
Subgroup | 0x03 |
Individual | 0x04 |
Official | 0x05 |
Vampire | 0x06 |
Noble | 0x07 |
Witches | 0x08 |
Temple | 0x09 |
Generic Group | 0x0C |
Thieves | 0x0D |
Courts | 0x0E |
People | 0x0F |
Values 0x0C and 0x0D are not used in any record.
RegionsEdit
The respective region the Faction/Person is associated with. For factions that are not associated with a specific region like guilds, temples etc., this value is always 0xFF (-1).
RulerEdit
If the faction is a region, this entry determines the title of the ruler. For other factions or regions without a ruler (such as The Alik'r Desert, this entry is always zero. See the Ruler enumeration here.
Reputation ValuesEdit
Valid ranges for the Reputation Values are -32768 (0x0080) to 32767 (0xFF7F), although the game mechanics will not allow your reputation to drop below -100 or grow above 100.
Faction IDs correspond to those used in the game's Faction-Database.
Allies/Enemies affiliations and powers for many factions are not static, they change randomly during the course of a game-year. There is apparently no way that the player can influence this changes from inside the game. There is apparently no rule what way this changes will take. Even very illogical changes, for example a faction's enemy can be one of its own subgroups, may occur.
There are many good programs that can be used to manipulate the reputation values of the various factions that exist in the game. See the Files page.
Vampire Clan IDEdit
If the faction is a region, this entry determines the region's dominant vampire clan. IDs correspond to those used in the game's Faction-Database. For all other factions this entry is always zero.
FlagsEdit
Number of Flags used for this faction, although the purpose of this entry is unknown.
Image IndexEdit
This entry determines which image will be used to display a person of a faction or an individual person. These images are stored in the various Texture files. Such a file contains a stack of numerous images, or flats as these images can also be called. These 2-dimensional images are used to project an object into a 3-dimensional world. The first picture of a Texture-File has the index 0 the second the index 1 and so on. Since consecutive Texture-Files use the same hex-value, see below, the indices are processed differently for Texture-Files that use the same hex-value.
- The Texture-File with the even number is processed from index 0 (0x0) to index 1 (0x01) and so on.
- The Texture-File with the uneven number uses a different processing namely, index 0 (0x80), index 1 (0x81) and so on. Index 0 starts always at 0x80 and the last index depends naturally on the number of images in the Texture-File.
Some factions and all persons use only one image, but most have two. One for a male character of the specific faction and one for a female character.
Texture FilesEdit
All flats that are used for Factions/Persons can be found in the Texture-Files 179-184. The people of Castle Daggerfall, Castle Wayrest and Castle Sentinel can be found in the files 334, 346 and 357. Each Texture-File is identified by a hex-value, which is used for two consecutive files. Following table shows these values.
Texture-File | Description | Value |
---|---|---|
175 | Daedra Lords | 0x57 |
176 | Dark Brotherhood | 0x58 |
177 | Mages | 0x58 |
178 | Necromancers | 0x59 |
179 | Witches | 0x59 |
180 | Courtiers | 0x5A |
181 | Temple People | 0x5A |
182 | Common People I | 0x5B |
183 | Nobles | 0x5B |
184 | Common People II | 0x5C |
334 | People of Castle Daggerfall | 0xA7 |
346 | People of Castle Wayrest | 0xAD |
357 | People of Castle Sentinel | 0xB2 |
PortraitEdit
These entries determine the portraits that are used when the player enters the dialog mode with a character of the respective faction. The value corresponds to the image's index in the FACES.CIF file. Index 0 (0x0) is for example the Oracle. Theoretical a maximum of two portraits per faction can be used, one for a male character and one for a female character. But since only persons have a respective portrait in the FACES.CIF file, only one portrait is used. The other entry (offset 0x34) is therefore always zero. For guilds, regions and all others that don't use such portraits, this two entries are always 0xFF.
RaceEdit
This value determines the Race to which the respective Faction/Person belongs to. For supernatural beings and factions like Daedra Lords, gods or Oblivion, this value is always 0xFF. Following numbers can be clearly assigned to following races:
Race | Value |
---|---|
Redguard | 0x02 |
Breton | 0x03 |
Dark Elf | 0x07 |
Vampire | 0x12 |
All other numbers are at best arguable because
- There are too few people belonging to a specific race, so a clear allocation can not be done.
- Their appearance is antithetic to the popular appearance of the respective race.
Additionally there are clearly some errors in the Fation-Database, for example Nulfaga, Lysandus' mother, is credited as a Redguard, however she is a Breton.
Social GroupEdit
Group | Value |
---|---|
Commoner | 0x00 |
Merchant | 0x01 |
Scholar | 0x02 |
Nobility | 0x03 |
Underworld | 0x04 |
Supernatural | 0x06 |
Knight Order, Temple or Vampire Clan | 0x07 |
Value 0x02 is used mostly for factions of the Mages Guild. Value 0x05 is only used for the faction Generic Temple and for Lord Coulder.
Regional ReputationEdit
The regional reputation data starts at offset 0x424 (verified for v1.07.213) with the record of the Alik'r Desert. Every 80 bytes the record for the next region starts. All 62 Regions of the Iliac Bay have such a record, even these regions that don't exist.
Offset | Description | Field Type | Count |
---|---|---|---|
000 | Reputation Value | BYTE | 0x01 |
001 | 0xFF or zero | BYTE | 0x01 |
Valid ranges for the Reputation Values are 0x9C (-100) to 0x64 (+100). If the Reputation Value is negative offset 0x01 is 0xFF and zero otherwise.
Increasing View DistanceEdit
by Thor-Eirik Larsen
The first thing that really got on my nerves when I ventured into the wonderful world of Tamriel, was the limited view. I figured I had to fix that particular "bug". In the file savetree.dat, Daggerfall stores the sound/music/detail settings as vars.
Now, the program itself does not allow you to enlarge the red bar beyond the limits of clicking-area, but a simple hex-editor does, if you only manage to locate the vars. As the size differs slightly from time to time, one cannot use the same offset for every savefile. To find the values let your hex-editor search the savetree.dat for these hex-values: 7F 7F 00 80 00, the first byte being the detail. These are the default values for a newly started game. If you have changed the bars manually in the meantime, set all three bars back to the maximum and search for 7F 7F 00 7F 00. Now change the first byte, the detail level, to FF. When you load your game, you'll notice that your range has been doubled making everything look much better! (Not as good as unlimited range, but beats the hell out of the first one :))