Skyrim Mod:Mod File Format/VMAD Field

The UESPWiki – Your source for The Elder Scrolls since 1995
Jump to: navigation, search

VMAD fields contain Papyrus script data, and are present in any record that contains a script, including items, dialogues, packages, and quests. Information contained in the VMAD field includes:

  • The names of all scripts attached to the record, including scripts attached to individual components (e.g., quest aliases) of the record.
    • The initial values of all properties in each of those scripts
  • The names of all script fragments attached to the record. Script fragments are most commonly used in quests, where each stage of a quest can have an associated script fragment.

The VMAD field contains several distinct sections. However, the entire field must be processed sequentially in order to identify the sections; the lengths and locations of the various sections are not provided, making it impossible to skip through the field to a specific section. All VMAD fields contain a Primary Scripts Section and its format is the same for all record types; in the majority of cases, that is the only section present. However, some records also contain a Fragments Section, with a format that is dependent upon the record type.

All script names mentioned in the VMAD field are provided without an extension. The game itself accesses compiled versions of each script, which are given a .pex extension and are stored in one of the game's .bsa archive files. The source versions of the scripts, which use a .psc extension, are not accessed by the game (and were not part of the original game distribution), but are instead only used by the Creation Kit. The source scripts were made available following the release of the Creation Kit, and all 10005 scripts (as of patch 1.5) are available in the Data/Scripts/Source directory of your Skyrim installation.

Primary Scripts Section[edit]

The Primary Scripts Section is present in all VMAD fields, and has the same format in all cases.

Name Type/Size Info
version int16 5 most recent, 2 is minimum.
objFormat int16 Seems to always be 1 or 2; affects how object-type properties are read.
scriptCount uint16 Number of scripts directly attached to this record
scripts Script[scriptCount] Information on each of the scripts, including name, list of properties, and their initial values.
fragments Fragments[] Script fragments. See below for more information.

Scripts Section[edit]

Name Type/Size Info
scriptName wstring Name of the script (without extension).
status uint8 Only present if version >= 4. Defaults to 0 for earlier versions.
0 = Local script.
1 = Inherited and properties have been altered.
3 = Inherited and then removed.
propertyCount uint16 The number of properties that are defined in this script.
properties Property[propertyCount] The name and initial value of each property. The length of each property entry is different, depending upon its contents.

Property Entry[edit]

Name Type/Size Info
propertyName wstring Name of the property.
propertyType uint8 Lookup value indicating the type of data stored in the property. Only the following values are possible:
  • 1 = object (v1: (formID = uint32, alias = int16, unused = uint16) or v2: (unused = uint16, alias = uint16, formID = uint32))
  • 2 = wstring (uint16 length + string[length])
  • 3 = int (int32)
  • 4 = float
  • 5 = bool (int8)

Only supported if version >= 5:

  • 11 = array of objects (see 1)
  • 12 = array of wstrings (uint16 length + string[length])
  • 13 = array of ints (int32)
  • 14 = array of floats
  • 15 = array of bools (int8)

Object types are used to assign formid values to properties, in particular for quest aliases, but also for a range of other cases that use formids. The length of the data for an object is always 8 bytes, but how the bytes are decoded depend upon the value of objFormat:

  • If objFormat=1, then: bytes 0-3 are a formid; bytes 4-5 are a uint16 providing the AliasID; bytes 6-7 are zero.
  • If objFormat=2, then: bytes 0-1 are zero, bytes 2-3 are a uint16 providing the AliasID; bytes 4-7 are a formid.

The AliasID is set to -1 whenever the formid does not point to a quest (in which case the formid is directly assigned to the property). Otherwise, the AliasID provides the quest alias used to assign the value (which nearly always means that the property effectively points to itself, e.g., the Alias_DragonMoundTundra03Marker property points to the quest's DragonMoundTundra03Marker alias).

status uint8 Only present if version >= 4. Defaults to 1 for earlier versions.
1 = Property edited.
3 = Property removed.
data depends on type If the data is an array (if type is 11-15), the data consists of:
  • uint32: itemCount
  • items[itemCount]

Fragments Section[edit]

If there are no fragments attached to this record, the VMAD field simply ends after the Primary Scripts Section. However, when there are fragments, the specific format used to list those fragments is dependent upon the record type. Note in particular that the fragmentCount appears before the fileName in some cases, but after the fileName in other cases. Only the record types listed below ever use script fragments.

INFO Records[edit]

INFO record fragment scripts are by default stored in a TIF file, i.e., a file named "TIF_<editorID>_<formID>". Since most INFO records do not have an editorID, this actually ends up being "TIF__<formID>" (with two underscores, not one).

Name Type/Size Info
unknown int8 Always 2.
flags uint8 Script locations.
0x1 = Has Begin Script
0x2 = Has End Script
fileName wstring Name of the script file containing the fragments (without extension).
fragments fragment[flagsCount] Information on each fragment, as detailed in the following lines. Variable flagsCount is the number of bit flags activated in flags
fragment.unknown int8
fragment.scriptName wstring Name of script (normally same as fileName).
fragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".

PACK Records[edit]

PACK record fragment scripts are by default stored in a PF file, i.e., a file named "PF_<editorID>_<formID>".

Name Type/Size Info
unknown int8 Always 2.
flags uint8 Script locations.
0x1 = On Begin.
0x2 = On End.
0x4 = On Change.
fileName wstring Name of the script file containing the fragments (without extension).
fragments fragment[flagsCount] Information on each fragment, as detailed in the following lines. flagsCount is the number of bits set in the flags field. When more than one is present, fragments are emitted in the following order: On Begin, On End, On Change.
fragment.unknown int8
fragment.scriptName wstring Name of script (normally same as fileName).
fragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".

PERK Records[edit]

PERK record fragment scripts are by default stored in a PRKF file, i.e., a file named "PRKF_<editorID>_<formID>".

Name Type/Size Info
unknown int8 Always 2.
fileName wstring Name of the script file containing the fragments (without extension).
fragmentCount uint16 Number of script fragments in this record.
fragments fragment[fragmentCount] Information on each fragment, as detailed in the following lines.
fragment.index uint16 Index.
fragment.unknown int16
fragment.unknown int8
fragment.scriptName wstring Name of script (normally same as fileName).
fragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".

QUST Records[edit]

QUST record fragment scripts are by default stored in a QF file, i.e., a file named "QF_<editorID>_<formID>".

Name Type/Size Info
unknown int8 Always 2. If it's set to anything else, then the game will likely fail to load any script data for aliases.
fragmentCount uint16 Number of script fragments in this record.
fileName wstring Name of the script file containing the fragments (without extension).
fragments fragment[fragmentCount] Information on each fragment, as detailed in the following lines.
aliasCount uint16 Number of aliases that have attached scripts. If 0, the rest of the section is empty.
aliases alias[aliasCount] Information on the scripts attached to each alias, as detailed in the following lines
fragment.index uint16 Quest stage index (equivalent to QUST INDX field) this fragment is attached to.
fragment.unknown int16 Always 0.
fragment.logentry int32 Log Entry within a stage this fragment is attached to.
fragment.unknown int8 Always 1.
fragment.scriptName wstring Name of script (normally same as fileName).
fragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".
alias.object object The FormID and AliasID to which the script is attached. Format is the same as documented under propertytype, above. The form ID here is always the form ID of the quest that contains this VMAD subrecord; the game engine actually will allow one quest to attach scripts to aliases on another quest, but official tools never generate that kind of data.
alias.version int16 Always 4 or 5; always the same as the primary script's version.
alias.objFormat int16 Always 1 or 2; always the same as the primary script's objFormat.
alias.scriptCount uint16 Number of scripts attached to this alias
alias.scripts Script[alias.scriptCount] Information on each of the scripts, including name, list of properties, and their initial values.

SCEN Records[edit]

SCEN record fragment scripts are by default stored in a SF file, i.e., a file named "SF_<editorID>_<formID>".

Name Type/Size Info
unknown int8 Always 2.
flags uint8 Script locations.
0x1 = Has Begin Script
0x2 = Has End Script
fileName wstring Name of the script file containing the fragments (without extension).
begineend beFragment[flagsCount] Information on begin/end fragments, as detailed below. flagsCount is the number of bits set in the flags field. When both are present, the Begin fragment is emitted first.
phaseCount uint16 Count of phase scripts.
phases phaseFragment[phaseCount] Information on each phase fragment, as detailed below.
beFragment.unknown int8
beFragment.scriptName wstring Name of script (normally same as fileName).
beFragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".
phaseFragment.unknown int8
phaseFragment.phase uint32 Phase number. (Note: this is 0-based in the data, but 1-based in the CK.)
phaseFragment.unknown int8
phaseFragment.scriptName wstring Name of script (normally same as fileName).
phaseFragment.fragmentName wstring Name of function containing this fragment script. Typically a name such as "Fragment_5".