Morrowind:Формат файлов ESM
| Это статья-заготовка. Вы поможете проекту, доработав и дополнив её. Не забывайте предварительно добавлять шаблон {{Edit}} в материалы над которыми работаете, чтобы не создавать конфликта правок. |
| Этот материал нуждается в переводе или допереводе.. Вы можете помочь перевести его. Не забывайте предварительно добавлять строку {{Edit|--~~~~}} в материалы над которыми работаете, чтобы не создавать конфликта правок. Пожалуйста, снимите шаблон этого сообщения, когда материал будет вычитан. |
- Источник: Format of Morrowind's ESM Plug-In File
- Provided As-Is by Dave Humphrey - uesp@sympatico.ca
- Дата публикации оригинала: 10.05.2003
Основной базовый формат:
Файлы 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
- Record flags.
- ? 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
- SkillBonuses[7]
- 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
- long SpellSchool
- 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
- long Type
- 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
- long Type
- 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
- byte Part
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
- long Type
- 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
- long Type
- 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
- long Type
- 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
- long Type
- 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
- long Flags
- 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
- FRMR = Object Index (starts at 1) (4 bytes, long)
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.
- long Unknown (default of 0x09)
- 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)
- float Unknown1
- WNAM (81 bytes)
- byte Data[9][9]
- Unknown byte data.
- byte Data[9][9]
- 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.
- byte Index
- 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]
- float Unknown[6]
- 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.
- MAPH - (8 bytes) Map header?
- 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 GlobalName[]
- 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