Morrowind:Формат файлов ESM

Материал из Tiarum
Перейти к: навигация, поиск
Icon-Information.png Это статья-заготовка.
Вы поможете проекту, доработав и дополнив её. Не забывайте предварительно добавлять шаблон {{Edit}} в материалы над которыми работаете, чтобы не создавать конфликта правок.
Переводить Этот материал нуждается в переводе или допереводе..
Вы можете помочь перевести его. Не забывайте предварительно добавлять строку {{Edit|--~~~~}} в материалы над которыми работаете, чтобы не создавать конфликта правок.
Пожалуйста, снимите шаблон этого сообщения, когда материал будет вычитан.


Содержание


Основной базовый формат:

Файлы ESM/ESP/ESS состоят целиком из записей, имеющих следующий формат:

Record

4 bytes: char Name[4]
4-byte record name string (not null-terminated)
4 bytes: long Size
Size of the record not including the 16 bytes of header data.
4 bytes: long Header1
Unknown value, usually 0 (deleted/ignored flag?).
4 bytes: long Flags
Record flags.
0x00002000 = Blocked
0x00000400 = Persistant
 ? bytes: SubRecords[]
All records are composed of a variable number of sub-records. There is no sub-record count, just use the record Size value to determine when to stop reading a record.

All records, as shown above, are again composed entirely of a variable number of sub-records with a similar format, as given below:

Sub-Record

4 bytes: char Name[4]
4-byte sub-record name string (not null-terminated)
4 bytes: long Size
Size of the sub-record not including the 8 bytes of header data.
 ? bytes: Sub-Record data.
Format depends on the sub-record type (see below).

48228 total base records
Number of unique main headers = 42

0: TES3 = 1 count

Main Header Record, 308 Bytes
HEDR (300 bytes)
4 bytes, float Version (1.2)
4 bytes, long Unknown (1)
32 Bytes, Company Name string
256 Bytes, ESM file description?
4 bytes, long NumRecords (48227)
MAST = string, variable length
Only found in ESP plugins and specifies a master file that the plugin requires. Can occur multiple times. Usually found just after the TES3 record.
DATA = 8 Bytes long64 MasterSize
Size of the previous master file in bytes (used for version tracking of plugin).
The MAST and DATA records are always found together, the DATA following the MAST record that it refers to.

1: GMST = 1428 counts

Game Setting Record, 19 to 261 bytes (43 average)
NAME = Setting ID string
STRV = String value
INTV = Integer value (4 btes)
FLTV = Float value (4 bytes)
Each GMST has one of STRV, INTV, FLTV for the setting value.

2: GLOB = 73 counts

Global Variable, 33 to 51 bytes (44 average)
NAME = Global ID
FNAM = Type of global (1 byte)
's' = short
'l' = long
'f' = float
FLTV = Float data (4 bytes)

3: CLAS = 77 counts

Class Definition, 96 to 352 bytes (185 average)
NAME = Class ID string
FNAM = Class name string
CLDT = Class Data (60 bytes)
long AttributeID1
long AttributeID2
long Specialization?
0 = Combat
1 = Magic
2 = Stealth
long MinorID1
long MajorID1
long MinorID2
long MajorID2
long MinorID3
long MajorID3
long MinorID4
long MajorID4
long MinorID5
long MajorID5
long Flags
0x0001 = Playable
long AutoCalcFlags
0x00001 = Weapon
0x00002 = Armor
0x00004 = Clothing
0x00008 = Books
0x00010 = Ingrediant
0x00020 = Picks
0x00040 = Probes
0x00080 = Lights
0x00100 = Apparatus
0x00200 = Repair
0x00400 = Misc
0x00800 = Spells
0x01000 = Magic Items
0x02000 = Potions
0x04000 = Training
0x08000 = Spellmaking
0x10000 = Enchanting
0x20000 = Repair Item
DESC = Description string

4: FACT = 22 (286, 983.64, 1218)

Faction Definition, 286 to 1218 bytes (984 average)
NAME = Faction ID string
FNAM = Faction name string
RNAM = Rank Name (32 bytes)
Occurs 10 times for each rank in order
FADT = Faction data (240 bytes)
long AttributeID1
long AttributeID2
RankData[10]
long Attribute1
long Attribute2
long FirstSkill
long SecondSkill
long Faction
long SkillID[6]
long Unknown1 (-1)?
long Flags
1 = Hidden from Player
ANAM = Faction name string
INTV = Faction reaction value (4 bytes, long)
The ANAM/INTV occur in pairs for each faction with a reaction adjustment (usually -4 to +4)

5: RACE = 10 ( 693, 751.50, 881)

Race Definition, 693 to 881 (752 average)
NAME = Race ID string
FNAM = Race name string
RADT = Race data (140 bytes)
SkillBonuses[7]
long SkillID
long Bonus
long Strength[2] (Male/Female)
long Intelligence[2]
long Willpower[2]
long Agility[2]
long Speed[2]
long Endurance[2]
long Personality[2]
long Luck[2]
float Height[2]
float Weight[2]
long Flags
1 = Playable
2 = Beast Race
NPCS = Special power/ability name string (32 bytes), multiple
DESC = Race description

6: SOUN = 430 (44, 60.52, 80)

Sound
NAME = Sound ID
FNAM = Sound Filename (relative to Sounds\)
DATA = Sound Data (3 bytes)
byte Volume (0=0.00, 255=1.00)
byte MinRange
byte MaxRange

7: SKIL = 27 (144, 247.44, 330)

Skill
INDX = Skill ID (4 bytes, long)
The Skill ID (0 to 26) since skills are hardcoded in the game
SKDT = Skill Data (24 bytes)
long Attribute
long Specialization
0 = Combat
1 = Magic
2 = Stealth
float UseValue[4]
The use types for each skill are hard-coded.
DESC = Skill description string

8: MGEF = 137 ( 113, 432.65, 665)

Magic Effect
INDX = The Effect ID (0 to 137) (4 bytes, long)
MEDT = Effect Data (36 bytes)
long SpellSchool
0 = Alteration
1 = Conjuration
2 = Destruction
3 = Illusion
4 = Mysticism
5 = Restoration
float BaseCost
long Flags
0x0200 = Spellmaking
0x0400 = Enchanting
0x0800 = Negative
long Red
long Blue
long Green
float SpeedX
float SizeX
float SizeCap
ITEX = Effect Icon string
PTEX = Particle texture string
CVFX = Casting visual string
BVFX = Bolt visual string
HVFX = Hit visual string
AVFX = Area visual string
DESC = Description text
CSND = Cast sound (optional)
BSND = Bolt sound (optional)
HSND = Hit sound (optional)
ASND = Area sound (optional)

9: SCPT = 631 ( 100, 1248.95, 9966)

Script
SCHD = Script Header (52 bytes)
char Name[32]
long NumShorts
long NumLongs
long NumFloats
long ScriptDataSize
long LocalVarSize
SCVR = List of all the local script variables seperated by '\0' NULL characters.
SCDT = The compiled script data
SCTX = Script text

10: REGN = 9 ( 313, 682.44, 1219)

Region
NAME = Region ID string
FNAM = Region name string
WEAT = Weather Data (8 bytes)
byte Clear
byte Cloudy
byte Foggy
byte Overcast
byte Rain
byte Thunder
byte Ash
byte Blight
BNAM = Sleep creature string
CNAM = Map Color (4 bytes, COLORREF)
byte Red
byte Green
byte Blue
byte Null
SNAM = Sound Record
byte SoundName[32] (lots of extra junk beyond string?)
byte Chance
Multiple records with the order determining the sound priority

11: BSGN = 13 ( 158, 199.23, 272)

Birth Sign
NAME = Sign ID string
FNAM = Sign name string
TNAM = Texture filename
DESC = Description string
NPCS = Spell/ability (32 bytes), multiple

12: LTEX = 107 ( 48, 62.84, 76)

Land Texture?

13: STAT = 2788 ( 39, 59.74, 79)

Static
NAME = ID string
MODL = NIF model

14: DOOR = 140 ( 47, 134.68, 185)

Door Definition
NAME = door ID
FNAM = door name
MODL = NIF model filename
SCIP = Script (optional)
SNAM = Sound name open
ANAM = Sound name close

15: MISC = 536 ( 99, 134.01, 176)

Misc Items
NAME = item ID, required
MODL = model filename, required
FNAM = item name
MCDT = Weapon Data, 12 bytes binary, required
float Weight
long Value
long Unknown
ITEX = Iventory icon filename
ENAM = Enchantment ID string???
SCRI = script ID string

16: WEAP = 485 ( 90, 162.62, 222)

Weapons
NAME = item ID, required
MODL = model filename, required
FNAM = item name
WPDT = Weapon Data, 0x20 bytes binary, required
float Weight
long Value
short Type? (0 to 13)
0 = ShortBladeOneHand
1 = LongBladeOneHand
2 = LongBladeTwoClose
3 = BluntOneHand
4 = BluntTwoClose
5 = BluntTwoWide
6 = SpearTwoWide
7 = AxeOneHand
8 = AxeTwoHand
9 = MarksmanBow
10 = MarksmanCrossbow
11 = MarksmanThrown
12 = Arrow
13 = Bolt
short Health
float Speed
float Reach
short EnchantPts
byte ChopMin
byte ChopMax
byte SlashMin
byte SlashMax
byte ThrustMin
byte ThrustMax
long Flags (0 to 1)
0 = ?
1 = Ignore Normal Weapon Resistance?
ITEX = Iventory icon filename
ENAM = Enchantment ID string
SCRI = script ID string

17: CONT = 890 ( 80, 284.19, 10371)

Containers
NAME = ID
MODL = NIF Model
FNAM = Container name
CNDT = Container data (4 bytes)
float Weight
FLAG = Container flags (4 bytes, bit-field)
0x0001 = Organic
0x0002 = Respawns, organic only
0x0008 = Default, unknown
NPCO = An item record (36 bytes, 0+ times)
long Count Number of the item
char Name[32] The ID of the item

18: SPEL = 982 ( 76, 109.80, 345)

Spells
NAME = Spell ID
FNAM = Spell Name
SPDT = Spell Data (12 bytes)
long Type
0 = Spell
1 = Ability
2 = Blight
3 = Disease
4 = Curse
5 = Power
long SpellCost
long Flags
0x0001 = AutoCalc
0x0002 = PC Start
0x0004 = Always Succeeds
ENAM = Enchantment data (24 bytes, 0 to 8)

19: CREA = 260 ( 213, 412.08, 780)

Creatures
NAME = ID
MODL = NIF Model
FNAM = Creature name
NPDT = Creature data, 96 bytes
long Type
0 = Creature
1 = Daedra
2 = Undead
3 = Humanoid
long Level
long Strength
long Intelligence
long Willpower
long Agility
long Speed
long Endurance
long Personality
long Luck
long Health
long SpellPts
long Fatigue
long Soul
long Combat
long Magic
long Stealth
long AttackMin1
long AttackMax1
long AttackMin2
long AttackMax2
long AttackMin3
long AttackMax3
long Gold
FLAG = Creature Flags (4 bytes, bit field)
0x0001 = Biped
0x0002 = Respawn
0x0004 = Weapon and shield
0x0008 = None
0x0010 = Swims
0x0020 = Flies
0x0040 = Walks
0x0048 = Default flags
0x0080 = Essential
0x0400 = Skeleton Blood
0x0800 = Metal Blood
SCRI = Script
NPCO = Item record (36 bytes, 0+ times)
long Count Number of the item
char Name[32] The ID of the item
AIDT = AI data (12 bytes)
AI_W = AI Wander (14 bytes)
short Distance
byte Duration
byte TimeOfDay
byte Idle[10]
AI_T = AI Travel?
AI_F = AI Follow?
AI_E = AI Escort?
AI_A = AI Activate?
XSCL = Scale (4 bytes, float, optional)
Only present if the scale is not 1.0

20: BODY = 1125 ( 75, 92.73, 103)

Body Parts
BYDT = Body part data (4 bytes)
byte Part
0 = Head
1 = Hair
2 = Neck
3 = Chest
4 = Groin
5 = Hand
6 = Wrist
7 = Forearm
8 = Upperarm
9 = Foot
10 = Ankle
11 = Knee
12 = Upperleg
13 = Clavicle
14 = Tail
byte Vampire
byte Flags
1 = Female
2 = Playable
byte PartType
0 = Skin
1 = Clothing
2 = Armor

21: LIGH = 574 ( 55, 105.77, 197)

Lights
NAME = ID string
FNAM = Item name (optional)
LHDT = Light data (24 bytes)
float Weight
long Value
long Time
long Radius
byte Red }
byte Green }
byte Blue } long ColorRef?
byte Null }
long Flags
0x0001 = Dynamic
0x0002 = Can Carry
0x0004 = Negative
0x0008 = Flicker
0x0010 = Fire
0x0020 = Off Default
0x0040 = Flicker Slow
0x0080 = Pulse
0x0100 = Pulse Slow
SCPT = Script name (optional)
ITEX = Inventory icon (optional)
MODL = NIF model name
SNAM = Sound name

22: ENCH = 708 ( 57, 98.59, 311)

Enchanting Effects
NAME = ID string
ENDT = Enchant Data (16 bytes)
long Type
0 = Cast Once
1 = Cast Strikes
2 = Cast when Used
3 = Constant Effect
long EnchantCost
long Charge
long AutoCalc
ENAM = Single enchantment data (24 bytes)
short EffectID
byte SkillID (-1 if NA)
byte AttributeID (-1 if NA)
long RangeType
0 = Self
1 = Touch
2 = Target
long Area
long Duration
long MagMin
long MagMax

23: NPC_ = 2675 ( 233, 619.12, 6236)

NPCs
NAME = NPC ID string
FNAM = NPC name
MODL = Animation file
RNAM = Race Name }
ANAM = Faction name } Required, even if empty
BNAM = Head model }
CNAM = Class name
KNAM = Hair model }
NPDT = NPC Data (12 bytes or 52 bytes?)
short Level
byte Strength
byte Intelligence
byte Willpower
byte Agility
byte Speed
byte Endurance
byte Personality
byte Luck
byte Skills[27] } According to the skillID (0-26)
byte Reputation
short Health
short SpellPts
short Fatigue
byte Disposition
byte FactionID
byte Rank
byte Unknown1
long Gold
12 byte Version
short Level
byte Disposition
byte FactionID?
byte Rank
byte Unknown1
byte Unknown2
byte Unknown3
long Gold?
FLAG = NPC Flags (4 bytes, long)
0x0001 = Female
0x0002 = Essential
0x0004 = Respawn
0x0008 = None?
0x0010 = Autocalc
0x0400 = Blood Skel
0x0800 = Blood Metal
NPCO = NPC item (36 bytes, occurs 0+ times)
long Count Number of the item
char Name[32] The ID of the item
NPCS = NPC spell (32 bytes, occurs 0+ times)
char Name[32] The ID of the item
AIDT = AI data (12 bytes)
byte Hello
byte Unknown1
byte Fight
byte Flee
byte Alarm
byte Unknown2
byte Unknown3
byte Unknown4
long Flags
0x00001 = Weapon
0x00002 = Armor
0x00004 = Clothing
0x00008 = Books
0x00010 = Ingrediant
0x00020 = Picks
0x00040 = Probes
0x00080 = Lights
0x00100 = Apparatus
0x00200 = Repair
0x00400 = Misc
0x00800 = Spells
0x01000 = Magic Items
0x02000 = Potions
0x04000 = Training
0x08000 = Spellmaking
0x10000 = Enchanting
0x20000 = Repair Item
AI_W = AI bytes (14 bytes)
short Distance
short Duration
byte TimeOfDay
byte Idle[8]
byte Unknown (1?)
AI_T = AI Travel (16 bytes)
float X
float Y
float Z
long Unknown (1?)
AI_F = AI Follow (48 bytes)
float X
float Y
float Z
short Duration
char ID[32]
short Unknown (0100?)
AI_E = AI Escort (48 bytes)
float X
float Y
float Z
short Duration
char ID[32]
short Unknown (0100?)
CNDT = Cell escort/follow to string (optional)
AI_A = AI Activate (33 bytes)
char Name[32]
byte Unknown (1?)
DODT = Cell Travel Destination
float XPos
float YPos
float ZPos
float XRot
float YRot
float ZRot
DNAM = Cell name for previous DODT, if interior
XSCL = Scale (4 bytes, float, optional)
Only present if the scale is not 1.0

24: ARMO = 280 ( 155, 217.10, 346)

Armour
NAME = Item ID, required
MODL = Model Filename, required
FNAM = Item Name, required
AODT = Armour Data, required (24 bytes)
long Type
0 = Helmet
1 = Cuirass
2 = L. Pauldron
3 = R. Pauldron
4 = Greaves
5 = Boots
6 = L. Gauntlet
7 = R. Gauntlet
8 = Shield
9 = L. Bracer
10 = R. Bracer
float Weight
long Value
long Health
long EnchantPts
long Armour
ITEX = Icon Filename, required
INDX = Body Part Index (1 byte)
0 = Head
1 = Hair
2 = Neck
3 = Cuirass
4 = Groin
5 = Skirt
6 = Right Hand
7 = Left Hand
8 = Right Wrist
9 = Left Wrist
10 = Shield
11 = Right Forearm
12 = Left Forearm
13 = Right Upper Arm
14 = Left Upper Arm
15 = Right Foot
16 = Left Foot
17 = Right Ankle
18 = Left Ankle
19 = Right Knee
20 = Left Knee
21 = Right Upper Leg
22 = Left Upper Leg
23 = Right Pauldron
24 = Left Pauldron
25 = Weapon
26 = Tail
BNAM = Male Part Name
CNAM = Female Body Part Name (0 occurences)
INDX and BNAM/CNAM are grouped together. INDX first followed by an optional BNAM (no BNAM indicates a NULL field for that index). Up to 7 pairs allowed.
SCRI = Script Name
ENAM = Enchantment Name

25: CLOT = 510 ( 123, 203.98, 658)

Clothing
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
CTDT = Clothing Data (12 bytes), required
long Type
0 = Pants
1 = Shoes
2 = Shirt
3 = Belt
4 = Robe
5 = Right Glove
6 = Left Glove
7 = Skirt
8 = Ring
9 = Amulet
float Weight
short Value
short EnchantPts
ITEX = Inventory Icon
INDX = Body Part Index (1 byte)
BNAM = Male Body Part Name
CNAM = Female Body Part Name
INDX and BNAM/CNAM are grouped together. INDX first followed by an optional BNAM (no BNAM indicates a NULL field for that index). Up to 7 pairs allowed.
ENAM = Enchantment Name
SCRI = Script Name

26: REPA = 6 ( 124, 145.67, 158)

Repair Items
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
RIDT = Repair Data (16 bytes), required
float Weight
long Value
long Uses
float Quality
ITEX = Inventory Icon
SCRI = Script Name

27: ACTI = 697 ( 52, 93.60, 138)

Activator
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
SCRI = Script Name

28: APPA = 22 ( 139, 152.59, 167)

Alchemy Apparatus
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
AADT = Alchemy Data (16 bytes), required
long Type
0 = Mortar and Pestle
1 = Albemic
2 = Calcinator
3 = Retort
float Quality
float Weight
long Value
ITEX = Inventory Icon
SCRI = Script Name

29: LOCK = 6 ( 126, 136.17, 145)

Lockpicking Items
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
LKDT = Lock Data (16 bytes), required
float Weight
long Value
float Quality
long Uses
ITEX = Inventory Icon
SCRI = Script Name

30: PROB = 6 ( 124, 136.33, 145)

Probe Items
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
PBDT = Probe Data (16 bytes), required
float Weight
long Value
float Quality
long Uses
ITEX = Inventory Icon
SCRI = Script Name

31: INGR = 95 ( 151, 181.66, 227)

Ingrediants
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
IRDT = Ingrediant Data (56 bytes), required
float Weight
long Value
long EffectID[4] 0 or -1 means no effect
long SkillID[4] only for Skill related effects, 0 or -1 otherwise
long AttributeID[4] only for Attribute related effects, 0 or -1 otherwise
ITEX = Inventory Icon
SCRI = Script Name

32: BOOK = 574 ( 131, 3306.91, 42120)

Books
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
BKDT = Book Data (20 bytes), required
float Weight
long Value
long Scroll (1 is scroll, 0 not)
long SkillID (-1 is no skill)
long EnchantPts
ITEX = Inventory Icon
SCRI = Script Name
TEXT = Book text

33: ALCH = 258 ( 163, 188.15, 334)

Alchemy?
NAME = Item ID, required
MODL = Model Name, required
FNAM = Item Name, required
ALDT = Alchemy Data (12 bytes), required
float Weight
long Value
long AutoCalc
ENAM = Enchantment (24 bytes) 1 to 8 per record
short EffectID
byte SkillID for skill related effects, -1/0 otherwise
byte AttributeID for attribute related effects, -1/0 otherwise
long Unknown1
long Unknown2
long Duration
long Magnitude
long Unknown4
TEXT = Inventory Icon
SCRI = Script Name

34: LEVI = 227 ( 80, 486.23, 9201)

Levelled Items
Levelled Creatures
NAME = ID of levelled list
DATA = List data (4 bytes, long)
1 = Calc from all levels <= PC level
2 = Calc for each item
NNAM = Chance None? (1 byte)
INDX = Number of items in list (4 bytes, long)
INAM = ID string of list item
INTV = PC level for previous INAM (2 bytes, short)
The INAM/INTV can occur many times in pairs

35: LEVC = 116 ( 97, 326.54, 1105)

Levelled Creatures
NAME = ID of levelled list
DATA = List data (4 bytes, long)
1 = Calc from all levels <= PC level
NNAM = Chance None? (1 byte)
INDX = Number of items in list (4 bytes, long)
CNAM = ID string of list item
INTV = PC level for previous CNAM (2 bytes, short)
The CNAM/INTV can occur many times in pairs

36: CELL = 2538 ( 29, 10151.12, 104488)

Cell Definitions
NAME = Cell ID string. Can be an empty string for exterior cells in which case the region name is used instead.
DATA = Cell Data
long Flags
0x01 = Interior?
0x02 = Has Water
0x04 = Illegal to Sleep here
0x80 = Behave like exterior (Tribunal)
long GridX
long GridY
RGNN = Region name string
NAM0 = Number of objects in cell in current file? (4 byte, long), Optional
Exterior Cell Sub-Records
NAM5 = Map Color (4 bytes, long, COLORREF)
Interior Cell Sub-Records
WHGT = Water Height (4 bytes, float)
AMBI = Ambient Light Level (16 bytes)
long AmbientColor
long SunlightColor
long FogColor
float FogDensity
Referenced Object Data Grouping
FRMR = Object Index (starts at 1) (4 bytes, long)
This is used to uniquely identify objects in the cell. For new files the index starts at 1 and is incremented for each new object added. For modified objects the index is kept the same.
NAME = Object ID string
XSCL = Scale (4 bytes, float) Static
DELE = (4 byte long) Indicates that the reference is deleted.
DODT = XYZ Pos, XYZ Rotation of exit (24 bytes, Door objects)
float XPos
float YPos
float ZPos
float XRotate
float YRotate
float ZRotate
DNAM = Door exit name (Door objects)
FLTV = Follows the DNAM optionally, lock level (long)
KNAM = Door key
TNAM = Trap name
UNAM = Reference Blocked (1 byte, 00?), only occurs once in MORROWIND.ESM
ANAM = Owner ID string
BNAM = Global variable/rank ID string
INTV = Number of uses ( 4 bytes, long, 1 default), occurs even for objects that don't use it
NAM9 = ? (4 bytes, long, 0x00000001)
XSOL = Soul Extra Data (ID string of creature)
DATA = Ref Position Data (24 bytes)
float XPos
float YPos
float ZPos
float XRotate
float YRotate
float ZRotate

37: LAND = 1390 ( 28, 27374.14, 30243)

Landscape
INTV (8 bytes)
long CellX
long CellY
The cell coordinates of the cell.
DATA (4 bytes)
long Unknown (default of 0x09)
Changing this value makes the land 'disappear' in the editor.
VNML (12675 bytes)
struct {
signed byte X
signed byte Y
signed byte Z
} normals[65][65];
A RGB color map 65x65 pixels in size representing the land normal vectors. The signed value of the 'color' represents the vector's component. Blue is vertical (Z), Red the X direction and Green the Y direction. Note that the y-direction of the data is from the bottom up.
VHGT (4232 bytes)
float Unknown1
A height offset for the entire cell. Decreasing this value will shift the entire cell land down.
byte Unknown2 (0x00)
signed byte HeightData[65][65]
Contains the height data for the cell in the form of a 65x65 pixel array. The height data is not absolute values but uses differences between adjacent pixels. Thus a pixel value of 0 means it has the same height as the last pixel. Note that the y-direction of the data is from the bottom up.
short Unknown2 (0x0000)
WNAM (81 bytes)
byte Data[9][9]
Unknown byte data.
VCLR (12675 bytes) optional
Vertex color array, looks like another RBG image 65x65 pixels in size.
VTEX (512 bytes) optional
A 16x16 array of short texture indices (from a LTEX record I think).

38: PGRD = 1194 ( 101, 996.60, 8261)

Path Grid

39: SNDG = 168 ( 50, 75.86, 94)

Sound Generator
NAME = Name? (DEFAULT0001, ALIT0001, etc...)
DATA = Sound Type Data (4 bytes, long)
0 = Left Foot
1 = Right Foot
2 = Swim Left
3 = Swim Right
4 = Moan
5 = Roar
6 = Scream
7 = Land
SNAM = Sound ID string
CNAM = Creature name (optional)

40: DIAL = 772 ( 24, 33.54, 54)

Dialogue topic (including journals)
NAME = Dialogue ID string
DATA = Dialogue Type? (1 byte, 4 bytes for deleted?)
0 = Regular Topic
1 = Voice?
2 = Greeting?
3 = Persuasion?
4 = Journal
What follows in the ESP/ESM are all the INFO records that belong to the
DIAL record (one of the few cases where order is important).

41: INFO = 3408 ( 107, 299.86, 1063)

Dialogue response record that belongs to previous DIAL record.
INAM = Info name string (unique sequence of #'s), ID
PNAM = Previous info ID
NNAM = Next info ID (form a linked list of INFOs for the DIAL). First
INFO has an empty PNAM, last has an empty NNAM.
DATA = Info data (12 bytes)
long Unknown1
long Disposition
byte Rank (0-10)
byte Gender
0xFF = None
0x00 = Male
0x01 = Female
byte PCRank (0-10)
byte Unknown2
ONAM = Actor string
RNAM = Race string
CNAM = Class string
FNAM = Faction string
ANAM = Cell string
DNAM = PC Faction string
NAME = The info response string (512 max)
SNAM = Sound filename
QSTN = Journal Name (1 byte, 0x01)
QSTF = Journal Finished (1 byte, 0x01)
QSTR = Journal Restart (1 byte, 0x01)
SCVR = String for the function/variable choice (5+ bytes)
byte Index
'0' to '5'
byte Type
'0' = Nothing?
'1' = Function
'2' = Global
'3' = Local
'4' = Journal
'5' = Item
'6' = Dead
'7' = Not ID
'8' = Not Faction
'9' = Not Class
'A' = Not Race
'B' = Not Cell
'C' = Not Local
short Function (2-byte string, '00' to '71')
'sX' = Global/Local/Not Local types
'JX' = Journal type
'IX' = Item Type
'DX' = Dead Type
'XX' = Not ID Type
'FX' = Not Faction
'CX' = Not Class
'RX' = Not Race
'LX' = Not Cell
byte CompareOp
'0' = '='
'1' = '!='
'2' = '>'
'3' = '>='
'4' = '<'
'5' = '<='
byte Name[]
Except for the function type, this is the ID for the global/local/etc... Is not nessecarily NULL terminated. The function type SCVR sub-record has no name string.
INTV =
FLTV = The function/variable result for the previous SCVR
BNAM = Result text (not compiled)
Size of master in bytes (64 bits)

ESS Save Game Format Differences

  • Custom objects (alchemy, magic items, and spells) hatve a unique numeric ID, much like the dialogue infos. The characters class is held in the NEWCLASSID_CHARGEN class ID.
GMDT (124 bytes)
float Unknown[6]
- Unknown values
char CellName[64]
- Current cell name of character?
float Unknown
char CharacterName[32]
SCRD (20 bytes)
unknown combination of short/longs? Related to SCRD?
SCRS (65536 bytes)
Looks like an array of byte data. Possible the save game screenshot.
SCPT
Contains local variable information for global scripts?
SLCS
SLCD
QUES
Quest dialogue/journal values?
NAME
- Quest name string
DATA
- INFO ID string?
JOUR
The character's journal
NAME
- The entire journal text (HTML) in one section
KLST
Kill stats?
KNAM - Creature/NPC ID string
CNAM - Occurs just after the KNAM sub-record
long Value
FMAP - Map data?
MAPH - (8 bytes) Map header?
long Size
long Value
MAPD - (786432 bytes) Map data? Size corresponds to an RGB 512x512 image.
PCDT
DNAM - Dialogue topic
MNAM
PNAM
SNAM
NAM9

Conversion from a biped to a bodypart types

Armor Biped Type BodyPart Type
0 = Head 0 = Head
1 = Hair 1 = Hair
2 = Neck 2 = Neck
3 = Cuirass 3 = Chest
4 = Groin 4 = Groin
5 = Skirt 4 = Groin
6 = Right Hand 5 = Hand
7 = Left Hand 5 = Hand
8 = Right Wrist 6 = Wrist
9 = Left Wrist 6 = Wrist
10 = Shield 6 = Wrist
11 = Right Forearm 7 = Forearm
12 = Left Forearm 7 = Forearm
13 = Right Upper Arm 8 = Upperarm
14 = Left Upper Arm 8 = Upperarm
15 = Right Foot 9 = Foot
16 = Left Foot 9 = Foot
17 = Right Ankle 10 = Ankle
18 = Left Ankle 10 = Ankle
19 = Right Knee 11 = Knee
20 = Left Knee 11 = Knee
21 = Right Upper Legv 12 = Uppperleg
22 = Left Upper Leg 12 = Upperleg
23 = Right Pauldron 13 = Clavicle
24 = Left Pauldron 13 = Clavicle
25 = Weapon -1 = None?
26 = Tail 14 = Tail

INFO Function Codes (2-byte character string)

'00' = Rank Low
'01' = Rank High
'02' = Rank Requirement
'03' = Reputation
'04' = Health Percent
'05' = PC Reputation
'06' = PC Level
'07' = PC Health Percent
'08' = PC Magicka
'09' = PC Fatigue
'10' = PC Strength
'11' = PC Block
'12' = PC Armorer
'13' = PC Medium Armor
'14' = PC Heavy Armor
'15' = PC Blunt Weapon
'16' = PC Long Blade
'17' = PC Axe
'18' = PC Spear
'19' = PC Athletics
'20' = PC Enchant
'21' = PC Destruction
'22' = PC Alteration
'23' = PC Illusion
'24' = PC Conjuration
'25' = PC Mysticism
'26' = PC Restoration
'27' = PC Alchemy
'28' = PC Unarmored
'29' = PC Security
'30' = PC Sneak
'31' = PC Acrobatics
'32' = PC Light Armor
'33' = PC Short Blade
'34' = PC Marksman
'35' = PC Mercantile
'36' = PC Speechcraft
'37' = PC Hand-to-Hand
'38' = PC Gender
'39' = PC Expelled
'40' = PC Common Disease
'41' = PC Blight Disease
'42' = PC Clothing Modifier
'43' = PC Crime Level
'44' = Same Gender
'45' = Same Race
'46' = Same Faction
'47' = Faction Rank Diff
'48' = Detected
'49' = Alarmed?
'50' = Choice
'51' = PC Intelligence
'52' = PC Willpower
'53' = PC Agility
'54' = PC Speed
'55' = PC Endurance
'56' = PC Personality
'57' = PC Luck
'58' = PC Corprus
'59' = Weather
'60' = PC Vampire
'61' = Level
'62' = Attacked
'63' = Talked to PC
'64' = PC Health
'65' = Creature Target
'66' = Friend Hit
'67' = Fight
'69' = Hello
'69' = Alarm
'70' = Flee
'71' = Should Attack

Skill Action/Use

Acrobatics: Jump, Fall
Alchemy: Potion Use, Ingrediant Use
Alteration: Successful Cast
Armorer: Successful Repair
Athletics: Second of Running, Second of Swimming
Axe: Successful Attack
Block: Successful Block
Blunt Weapon: Successful Attack
Conjuration: Successful Cast
Destruction: Successful Cast
Enchant: Recharge Item, Use Magic Item, Create Magic Item, Cast When Strikes
Hand-To-Hand: Successful Attack
Heavy Armor: Hit by Opponent
Illusion: Successful Cast
Light Armor: Hit by Opponent
Long Blade: Successful Attack
Marksman: Successful Attack
Medium Armor: Hit by Opponent
Mercantile: Successful Bargain, Successful Bribe
Mysticism: Successful Cast
Restoration: Successful Cast
Security: Defeat Trap, Pick Lock
Short Blade: Successful Attack
Sneak: Avoid Notice, Successful Pick Pocket
Spear: Successful Attack
SpeechCraft: Successful Persuasion, Failed Persuasion
Unarmored: Hit by Opponent

SCDT Compiled script data

For commands with ID

short Code
byte IDLength
char ID[]

IF Block

short Code = 0x0601
byte Unknown (00?)
byte CompareLength
byte VarType
0x20
byte VarSize
s/l/f/G
local short VarIndex
1 based index of local variable by type
global byte GlobalSize
byte GlobalName[]
Not NULL terminated
byte CompareText[]
Not NULL terminated

SET Block

short Code = 0x0501
short VarCode (0x2073, ... )
(var data)
byte SetSize
byte SetData[]
Data in stack order: (6*3+1 => 6 3 * 1 +)

Codes

0x2073 = Get short local var
0x206C = Get long local var
0x2066 = Get float local var
0x2047 = Get global var
0x010C =
0x1019 =
0x0501 = set
0x0601 = if
0x0101 = End
0x0901 = EndIf

Variables

Vars are not defined in the SCDT.

In SCVR the vars are listed as null terminated strings in the order shorts, longs, floats, this does not appear to be used by SCDT.

The number of variables of each type is stored in SCHD, the format of which appears to be:

SCHD (long) size, (cstr32) scriptname, (long) num shorts, (long) num longs, (long) num floats

(long) 2, (long) size of SCVR seg

SCDT uses the index of the variable by type, so the first float would be 'f0001', it starts at 1 not 0 because its stupid.


Mnemonic HexOp Params
-> 010C (bstr) objectname ; appears before the function which uses it lasts for 1 simple statement only
else 0107 (byte) statement count
elseif 0108 (byte) statement count, (ifexpr) condition
end 0101 none
endif 0109 none
if 0106 (byte) statement count, (ifexpr) condition
set 0105 (variable) target, (setexpr) newvalue
ForceSneak 1163 none
GetAlchemy 106B none
GetDistance 1001 (ref) objectname
GetPos 100A (byte) 'X' 'Y' or 'Z'
Journal 10CC (bstr) topic, (sparam) index
Lock 1136 (short) literal
MessageBox 1000 (lstr) formatstr, (byte) num args, [ (variable) arg1 [, (variable) arg2 [...]]], (byte) num buttons, [ (bcstr) but1 [, (bcstr) but2 [...]]]
Position 1004 (float) x, (float) y, (float) z, (float) zangle
Random 1021 (short) limit
SetAlchemy 106C (fparam) newalchemy
SetSneak 1075 (fparam) newsneak
StopScript 101C (bstr) scriptname

Definitions

not there are no implicit separators, this is a binary stream

= byte value

= ' '

bstr = (byte) length, ascii

lstr = (short) length, ascii

cstr = ascii, <00>

bcstr = (byte) length, cstr

length1 = (byte) length

varidx1 = (byte) var index

varidx2 = (short) var index

varidx = (short) var index

mathop = ('+'|'-'|'*'|'/')

mathcomp = ('=='|'!='|'<'|'<='|'>'|'>=')

valascii = ['-']*(0-9)[.]*(0-9)

vartype = ('s'|'f'|'l')

local = ( vartype varidx )

global = ('G' bstr)

variable = ( local | global )

ref = ('r' bstr)

foreign = ( ref local )

fparam = ( float | local <00> ) ; 4 bytes either way see

sparam = ( short | local <00> ) ; 4 bytes either way see

rval = ( local | valascii )

setval = ( local | global | func | valascii )

The know issue of: set temp to ( myobj.val ); not working is a runtime problem the compiler generates a foreign reference exactly the same as for if

func = ('X' opcode [ rval [ rval [ rval [ rval]]]])

How does the evaluator know how many params to grab?
everything up to the end of the expression, can only have 1 function
per set
set temp to ( Position 1 2 3 4 ) okay
set temp to ( Position 1 2 3 4 + 1 ) wont work
set temp to ( 1 + Position 1 2 3 4 ) would work
but this would not be backwards compatible
up to the next space, funcs can only have 1 param,
set temp to ( GetPos x + GetPos y ) okay
this is backwards compatable, tested and works

polish = Reverse polish calculator, uses space as 'push', mathop as operators, setval as values. If there is only 1 variable or 1 function then an additional <00> is appended which appears to do nothing, but is required by the runtime.

setexpr = (byte) length, polish

ifval = ( local | global | foreign | func | valascii )

ifexpr = (byte) length, ifval [mathcomp ifval]

The if evaluator cannot handle calculations, the comparison operator is not implemented as part of the reverse polish calculator, the compiler will encode calculations in reverse polish but the comparisons are inserted in the wrong order to work.
Like the calculator if there is only one term a <00> byte is appended