Format of Morrowind's ESM Plug-In File

		Provided As-Is by Dave Humphrey - uesp@sympatico.ca

				10 May 2003

Basic Overall Format:

The ESM/ESP/ESS files are composed entirely of records with the following format:

  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 Leg			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 'f
0001', 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

return		0124	none

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



If you have any problems, suggestions or comments on this page or website, please feel free to use the Contact Form to send a message to the WebMaster.
This document was last modified on: Tuesday, 15 February 2011, at 20:25:32 and has been accessed 6575 times ( morrow/tech/mw_esm.txt ).
/text.shtml