PACK records describe AI packages, which are used to control the behavior and activities of NPCs.
PACK records use a moderately complex structure, with various fields that occur multiple times and have different meanings depending upon where they occur within the overall structure. The records also seem to generally contain a large amount of unnecessary and/or obsolete content -- deleted activities never seem to actually be deleted from the game data; some sections are required even though they are entirely empty in 99.9% of the PACK records. As a result, a large fraction of the data in a given PACK record may not be visible in the CK editor.
HeaderEdit
These fields are always found at the start of the PACK record.
C | SubRecord | Name | Type/Size | Info |
---|---|---|---|---|
+ | EDID | editorId | zstring | Editor id |
- | VMAD | script info | VMAD | script info |
* | CTDA | conditions | struct[32] | Conditions controlling when the package can be active. CTDA fields can also be found in the Procedure Tree section of the record, in which case the conditions are specific to that branch of the procedure tree. |
* |
|
Variable name? | zstring | Auxiliary data for CTDA. |
* |
|
Variable name? | zstring | Auxiliary data for CTDA. |
- | IDLC | Idle Count | uint8 | Number of formids found in subsequent IDLA field |
- | IDLA | Idle | formid[IDLC] | 1 or more IDLE formids |
- | IDLF | Idle Flags | uint8 | Flags:
|
- | IDLT | Idle Time | float | |
- | QNAM | Owner Quest | formid | QNAM can only appear once in the header section. However, it can also appear in the Begin/End/Change section, with a different format and meaning. |
+ | PKCU | PKCU field | struct[12] | |
|
ulong | Unknown, possibly flags. Values range from 1 to 34. | ||
|
formid | Formid for another PACK record that is used as a template. This value can only be provided in records that are identified with Package Type "Package", and only templates with type "Package Template" are valid entries. | ||
|
ulong | Unknown, possibly flags. Values range from 0 to 29. | ||
+ | PKDT | Package Flags | struct[12] | |
|
uint32 | Only flags that have a visible effect in the CK are listed here. Many other flags may be set in the game data, but they are probably hold-overs from Oblivion that were phased out during development.
|
||
|
uint8 | Only the first bit is relevant:
0x12 is always set. |
||
|
uint8 | Only observed values are 0 (None) and 4 (Combat) | ||
|
uint8 | This value is only relevant if the Preferred Speed Misc Flag is set (0x2000 above)
|
||
|
uint8 | Possibly padding | ||
|
uint32 |
The remainder of the bits (0xFC00) can also be set, but they appear to be "extra" interrupt flags: the "Set all interrupt flags" sets the flags to 0xFFFF, and "Clear all interrupt flags" sets them to 0x0000, but the higher bits do not correspond to any displayed flags in the CK editor. |
||
+ | PSDT | Schedule | struct[12] | Information on when package is allowed to be active |
|
byte | Any=-1 (only value currently being used in Skyrim) | ||
|
byte | Day of week
|
||
|
byte | Date (day of month); Any=0 | ||
|
byte | Start hour (0-23); Any=-1 | ||
|
byte | Start minutes (0-59); Any=-1 | ||
|
byte[3] | Probably unused padding (although values are typically not zero) | ||
|
uint32 | Duration in minutes, although the value is displayed in the CK using decimal hours |
Public Package DataEdit
The section providing the public package data is located after the fields listed for the header, and extends until an XNAM field is encountered. It provides a list of activities and parameters controlling those activities, all of which are listed in the "Public Package Data" section of the CK edit interface.
The section is made up of a series of ANAM fields, each of which is followed by various other fields providing the activity parameters corresponding to that ANAM field. Then the section contains a series of UNAM fields, each of which provides the activity name corresponding to one of the previous ANAM fields.
Note that ANAM fields are also found in the Procedure Tree section, if one exists.
C | SubRecord | Name | Type/Size | Info |
---|---|---|---|---|
* | ANAM | Activity Type | zstring | A string identifying the type of data stored in this activity entry. Each ANAM field is followed by one field that provides data with the given type. Possible values in this section, and the associated field, are:
One and only one of the following fields is found after each ANAM field. (Other values for ANAM are only found in the Procedure Tree section of the record.) |
- |
|
Numeric Value | variable | CNAM is 1-4 bytes in size, and the type of data in CNAM depends upon the previous ANAM field; see above. |
- |
|
Topic Value | struct[8] | Note that PDTO fields can also occur in the Begin/End/Change section |
|
long |
|
||
|
formid/char[4] | Formid for a DIAL record when type=0; 4-character string for type=1 (e.g. "HELO" for "Hello" subtype) | ||
- |
|
Location Value | struct[12] | |
|
long |
|
||
|
variable | Location; always 4 bytes in length, but format depends upon Type as listed above. If Location is unused, then value is empty. | ||
|
long | Radius | ||
- |
|
Target Value | struct[12] | |
|
long |
|
||
|
formid/long | Target; always 4 bytes in length, but format depends upon Type as listed above. If Location is unused, then value is empty.
For Object Type, number appears to be a lookup value. Known values are:
|
||
|
long | Count (0 in all Skyrim records) | ||
- |
|
Unknown | formid | DIAL record |
* | UNAM | Activity ID | uint8 | Each UNAM field provides a numerical ID; that ID can be looked up in the Package Template to determine the Name of the activity as listed in the CK.
Although the UNAM fields are listed after all of the ANAM fields for this section, each UNAM field provides the name for one of the previous ANAM fields. The first UNAM field corresponds to the first ANAM field, etc. |
+ | XNAM | Unknown | int8 | Number ranging from -77 to 99. There is always one XNAM field in a PACK record, and it is always located at the end of the Public Package Data section. |
Procedure TreeEdit
This section is the first of two sections that are only found in template packages. This section defines the structure of the procedure tree used by this template and all packages based upon this template.
As with the Public Package Data section, this section is also made up of a series of ANAM fields. However, a completely different set of ANAM values appear in this section, and each ANAM section contains multiple fields, all of which are different than those found in Public Package Data.
This section ends when a UNAM field is found, signaling the start of the Procedure Data section.
C | SubRecord | Name | Type/Size | Info |
---|---|---|---|---|
* | ANAM | Branch Type | zstring | A string identifying the type of branch data stored in the following section. Possible values found in this section are:
Each ANAM entry is followed by multiple fields. The count column for the following entries is relative to a given ANAM field -- overall these fields can always occur 0 or many times in a given record. |
+ |
|
Condition Count | uint32 | Number of conditions (CTDA fields) in this branch. Can be 0, in which case there are no CTDA fields. |
* | Conditions | struct[32] | Conditions controlling when this branch can be active. Note that conditions relevant to the overall package are provided using CTDA fields that appear in the header section. | |
- |
|
Unknown | struct[8] | Appears to be two uint32 values |
- |
|
Procedure Type | zstring | Note that PNAM fields also appear in the Procedure Data Section, in which case formats other than zstring are possible |
- |
|
Flag | uint32 | Flag. Only one bit is in use:
|
* |
|
Activity ID | uint8 | The PKC2 fields provide a list of all the activity IDs found in this branch. Note that a given activity ID can occur multiple times within the Procedure Tree Section, in particular if that activity is part of multiple branches. |
- |
|
Unknown | struct[16] | |
- |
|
Unknown | struct[12] |
Procedure DataEdit
This section is also only found in template packages. It provides the name associated with each activity ID. It consists of a series of UNAM fields, each followed by one BNAM field and one PNAM field.
C | SubRecord | Name | Type/Size | Info |
---|---|---|---|---|
* | UNAM | Activity ID | uint8 | This is the same activity ID provided in both the Public Package Data and Procedure Tree sections. However, many additional activity IDs can also possibly appear; any additional IDs correspond to activities that were deleted from the package and are no longer accessible through the CK edit interface. |
+ |
|
Activity Name | zstring | The activity name as displayed in the CK |
+ |
|
Unknown | uint32 | Probably a flag: only values are 0 or 1. Note that the PNAM fields also appear in the Procedure Tree section, but have a completely different format and meaning. |
Begin/End/ChangeEdit
This section provides the 'On Begin', 'On End', and 'On Change' actions for this package. It is always present at the end of all PACK records (for both standard packages and template packages -- even though the CK editor does not display this section for template packages).
It consists of three marker fields (POBA, POEA, POCA), each of which is always followed by an INAM and a PDTO field. Each marker may also be followed by an old scripting (SCHR) field.
C | SubRecord | Name | Type/Size | Info |
---|---|---|---|---|
+ | POBA or | On Begin | 0-size | Marks start of 'On Begin' actions |
POEA or | On End | 0-size | Marks start of 'On End' actions | |
POCA | On Change | 0-size | Marks start of 'On Change' actions | |
+ | INAM | Idle | formid | IDLE record. Field is always present but its value is 0 if there is no idle action. |
- | SCHR | Old Script | SCHR | Old scripting field. |
- | TNAM | Unknown | int32 | Seen only on a single PACK record ("Say" / 0x0001CB6) - always 0. |
+ | PDTO | Topic | struct[8] | Field is always present but is entirely 0 if there is no topic. Note that PDTO fields also appear in Public Package Data section; the same structure is probably used in both cases. |