Tes4Mod:Mod File Format

The UESPWiki – Your source for The Elder Scrolls since 1995
Jump to: navigation, search
Outdated Tech: While these pages still provide the best public documentation of the Oblivion file formats, all mod makers should also be using Tes4View, which currently provides the most complete and correct understanding of the mod file format in a readily accessible manner.
Type Data Object
ACHR Placed NPC
ACRE Placed creature
ACTI Activator
ALCH Potion
AMMO Ammo
ANIO Animated Object
APPA Alchem. Apparatus
ARMO Armor
BOOK Book
BSGN Birthsign
CELL Cell
CLAS Class
CLMT Climate
CLOT Clothing
CONT Container
CREA Creature
Type Data Object
CSTY Combat Style
DIAL Dialog Topic
DOOR Door
EFSH Effect Shader
ENCH Enchantment
EYES Eyes
FACT Faction
FLOR Flora
FURN Furniture
GLOB Global
GMST Game Setting
GRAS Grass
HAIR Hair
IDLE Idle Animations
INFO Dialog response
INGR Ingredient
Type Data Object
KEYM Key
LAND Land
LIGH Light
LSCR Load Screen
LTEX Land Texture
LVLC Leveled Creature
LVLI Leveled Item
LVSP Leveled Spell
MGEF Magic Effect
MISC Misc. Item
NPC_ Non-Player Character
PACK AI Package
PGRD Path grid
QUST Quest
RACE Race
REFR Placed object
Type Data Object
REGN Region
ROAD Road
SBSP Subspace
SCPT Script
SGST Sigil Stone
SKIL Skill
SLGM Soul Gem
SOUN Sound
SPEL Spell
STAT Static
TES4 Tes4 Header
TREE Tree
WATR Water Type
WEAP Weapon
WRLD Worldspace
WTHR Weather

Contents

[edit] Overview

Mod files for CS4 (TES4 Construction Set) are essentially collections of records, which are further divided into subrecords. Records generally correspond to objects in the construction set (e.g., a creature, a GMST setting, a dialog entry), with the fine details of the object (e.g., health of a creature, a dialog entry test) being handled by the subrecords of the record. Records themselves are organized into groups by GRUP records. At the highest grouping level, the TES4 file is simply:

  • A single TES4 record
  • A collection of top groups.

While CS4 seems to have some flexibility in the ordering and structure of records and groups in the files it reads, it also clearly likes to write files in a more specific ordering, which is described below. If your application is writing a mod file, it is suggested that you follow this preferred format if possible.

For a comparison with Morrowind (TES3) file format, see: Mod File Format/Vs Morrowind.

[edit] Groups

GRUPs are new (compared to Tes3), and seem to have been introduced largely to improve scanning of files, since they make it easier to skip over blocks of records that the reading program is not interested in. In addition to this, subgroups for WRLD and CELLS provide some useful structural information (e.g., the division of cell data into persistent and non-persistent references.)

Name Type/Size Info
type char[4] Always "GRUP"
groupSize ulong Size of the entire group, including the group header (20 bytes).
  • This is in contrast to records and subrecords, whose sizes does not include their header sizes.
label ubyte[4] Format depends on group type (see next field).
  • In the CS4 Details view, you can mark a group as ignored, but CS4 ignores this setting and reads the group anyway. If you subsequently save, the group will be written without the ignore markings. The ignore flag interferes with what should ordinarily be in the label field. E.g., "HAIR" becomes "HQIR". This mislabeling has no effect on record loading. In short, the label field of a group is not reliable.
groupType long Group type...
Type Info Label Label
0 Top (Type) char[4] Record type
1 World Children formid Parent
2 Interior Cell Block long Block number
3 Interior Cell Sub-Block long Sub-block number
4 Exterior Cell Block short[2] Grid Y, X (Note the reverse order)
5 Exterior Cell Sub-Block short[2] Grid Y, X (Note the reverse order)
6 Cell Children formid Parent
7 Topic Children formid Parent
8 Cell Persistent Childen formid Parent
9 Cell Temporary Children formid Parent
10 Cell Visible Distant Children formid Parent
stamp ulong Date stamp, presumably of the last file modification. Stamp uses the MS-DOS date format.
  • For a given esp, the stamp is the same for all groups, and seems to increase with date (and possibly time).
  • Oblivion.esm stamps vary. Possibly due to a merging process?

[edit] Top Groups

In Oblivion.esm, the top, or highest level groups are stored in the following order:

GMST, GLOB, CLAS, FACT, HAIR, EYES, RACE, SOUN, SKIL, MGEF, SCPT, LTEX, ENCH, SPEL, BSGN, ACTI, APPA, ARMO, BOOK, CLOT, CONT, DOOR, INGR, LIGH, MISC, STAT, GRAS, TREE, FLOR, FURN, WEAP, AMMO, NPC_, CREA, LVLC, SLGM, KEYM, ALCH, SBSP, SGST, LVLI, WTHR, CLMT, REGN, CELL, WRLD, DIAL, QUST, IDLE, PACK, CSTY, LSCR, LVSP, ANIO, WATR, EFSH.

Whether the game engine expects this order is unknown, but it's probably safer to use this order than not.

All top groups contain records matching their label (e.g., the GMST top group contains GMST records). For most top groups, only the matching record types are present. However, in the CELL, WRLD and DIAL top groups, each main record can be followed by one or more child groups which contain additional records of a different type. Structure and ordering of those are as follows...

[edit] Hierarchical Top Groups

DIAL Top Group
  • DIAL
  • Topic Children
    • INFO
CELL Top Group
  • Interior Cell Block
    • Interior Cell Sub-Block
      • CELL
      • Cell Childen
        • Persistent children
          • REFR, ACHR, ACRE
        • Visible distant children
          • REFR, ACHR, ACRE
        • Temp Children
          • PGRD
          • REFR, ACHR, ACRE
WRLD Top Group
  • WRLD
  • World Children
    • ROAD
    • CELL
    • Cell Children
      • Persistent Children
        • REFR, ACHR, ACRE
      • Visible Distant Children
        • REFR, ACHR, ACRE
      • Temp Children
        • PGRD
        • REFR, ACHR, ACRE
    • Exterior World Block
      • Exterior World Sub-block
        • CELL
        • Cell Childen
          • Persistent Children
            • REFR, ACHR, ACRE
          • Visible Distant Children
            • REFR, ACHR, ACRE
          • Temp Children
            • LAND
            • PGRD
            • REFR, ACHR, ACRE

[edit] Records

Name Type/Size Info
type char[4] Record type
dataSize ulong Size of data field.
flags ulong Flags...
Flag Meaning
0x00000001 ESM file. (TES4.HEDR record only.)
0x00000020 Deleted
0x00000200 Casts shadows
0x00000400 Quest item / Persistent reference
0x00000800 Initially disabled
0x00001000 Ignored
0x00008000 Visible when distant
0x00020000 Dangerous / Off limits (Interior cell)
0x00040000 Data is compressed
0x00080000 Can't wait
formid formid Record identifier.
  • Tes4 does not have a FormId.
  • Some GMST records do not have a FormID.
Version Control Info ulong used for revision control by the CS (only if enabled)
  • Low word is a timestamp: low byte is the day of the month, high byte is a month number, starting with 1 = Jan. 2003

The CS's algorithm for producing the timestamps is a bit strange, though, so that the month of December for a given year actually comes before January of that year, instead of January of the next year. One can only assume it was a bug ...

  • High word marks ownership: low byte is user id that last had the form checked out, high byte is user id (if any) that currently has the form checked out
data ubyte[dataSize] Data
  • For uncompressed records, this is a sequence of subrecords.
  • Compressed data is the same, except that the subrecords are compressed using ZLIB level 6, and stored into the data field like so...
Name Type/Size Info
decompSize uint Size of decompressed data.
compData ubyte[dataSize-4] Compressed collection of subrecords.

[edit] Subrecords

Name Type/Size Info
subType char[4] Subrecord type.
dataSize ushort Size of data field.
  • If the preceding field has the type XXXX, then dataSize will be 0 and the size of the data is in fact the 32 bit quantity stored in the XXXX field. This happens once in Oblivion.esm.
data ubyte[dataSize] Data.
  • Format depends on record and subrecord type.

There are a number of subrecord formats that are appear in several places.

Variable Length String (terminated)
Holds a variable length string including the nul (0x00) terminator. This means that an empty string would have a subrecord size of 1. Most variable string subrecords use this type.
Variable Length String (not terminated)
Holds a variable length string but does not include the nul (0x00) terminator. Only seen in SCTX subrecords in scripts so far.
byte/word/dword/int64/float
Basic data types which are used in a variety of places. The subrecord size is the same size of the native type.

Personal tools
 What is this Ad?
Report Ad