The esp is basically a list of objects. Each object represents something that has been added or changed from the ESM.
The first 362 bytes of the ESP are the header. (This is true for most ESP files, but can vary if the ESP uses a different master file than Morrowind.esm, or if it is dependent upon more than one master file). The header contains the author's name, a description of the mod, the master filename, etc.
Objects begin following the header. Each object starts with its type and length. Then come the subobjects ((type + length + data) + subobject + ...). The type is a 4 letter word (Ex: DOOR, LIGH, STAT). The length field of some larger objects is 12 bytes, but the length field of most objects and subobjects is only 4 bytes.
Note: It appears that the extra 8 bytes of "length data" may actually hold bitflag information. E.g., if an item is marked as being "blocked" or "references persist", the last 8 bytes of this "length" field change. We just haven't pinned down what it all means at this time.
The length, as with all binary values in the ESP file, is written in little endian form, base 256, so that the least significant byte comes first, and the most-significant comes last: A*256^0 + B*256^1 + C*256^2....
In addition, most "name" fields in Morrowind are limited to 31 characters in length. In the ESP file, these fields are often written as 32-byte strings, with extra space at the end filled by zeroes, and there must be at least one zero at the end, which forces the maximum name length to be 31.
Tag | Description |
ACTI | Activator |
ALCH | Alchemy |
APPA | Apparatus |
ARMO | Armor |
BOOK | Book |
BODY | Bodypart |
CELL | Cell |
CLAS | NPC / Player Class (e.g., Paladin, Spellsword) |
CLOT | Clothing |
CONT | Container |
CREA | Creature |
DOOR | Door |
DIAL | Dialog |
ENCH | Enchanting |
FACT | Faction |
FRMR | Object Reference (rather than a whole new object or copy of an object) |
GLOB | Global variable |
INFO | Info/Response |
INGR | Ingredient |
LAND | Changes in landscape heightmap |
LEVC | Leveled creature |
LEVI | Leveled item |
LIGH | Light |
LTEX | Changes in landscape texture |
MGEF | Magic effect |
MISC | Misc item |
NPC_ | Npc |
PGRD | Path grid |
PROB | Probe |
REPA | Repair item |
SCPT | Script |
SKIL | Skill |
SNDG | Sound: defines what kind of sound a creature/thing makes. |
SOUN | Creates a new type of sound. So SNDG will refer to a SOUN, which refers to a WAV file. |
SPEL | Spell |
STAT | Static |
WEAP | Weapon |
Field Names | |
BNAM | NPC Facetype |
CNAM | Sound file used by a creature or NPC. |
FLTV | Additional information for a reference to an object. Used to hold lock information for chests and doors. |
FNAM | Friendly Name: name the user will see in-game. |
ITEX | Inventory pic for items |
KNAM | Name of an associated object. E.g., could be the name of the key that unlocks this chest or door. |
MODL | NPC Model |
NAME | Unique identifier |
NAM0 | Not sure. Appears before a list of object references in a cell.? |
NPCO | Inventory of a creature or NPC; contents of a container. |
RNAM | NPC Race |
SCHD | Script header (Name) |
SCDT | Script Data |
SCRI | Name of a script attached to an object. |
SCTX | Script text |
Individual sections are left out of the ESP file if nothing of that type has been added or changed.
The original version of the editor generated only what you told it to. Later versions, especially if you have official expansion packs installed, tend to add a lot of extra content, especially dialog. Not sure why that is, but it is annoying.
Field | Type | Length | Description |
---|---|---|---|
Header |
Warning. Be careful about assuming a fixed length for the header. Because the header contains the master filename, the length of the header can vary.... | ||
File Signature | String | 4 | This is always "TES3" to indicate that it's an elder scrolls 3 file. |
Header Size | Integer | 4 | Indicates how big the header is. Usually is 0x5A 0x01 0x00 0x00. |
Reserved | Byte | 8 | These bytes should all be NULL. |
Header | String | 4 | "HEDR" |
Header Size | Binary | 4 | Distance from the end of the Header Size to the start of the MAST entry. Usually this is 0x2C 0x01 0x00 0x00. |
Version Number | Float | 4 | Version number (1.2) of the file, as a floating point number: 0x9A 0x99 0x99 0x3F |
Unknown | Binary | 4 | Four null values, unknown purpose: 0x00 0x00 0x00 0x00 |
Author Name | String | 32 | Unused characters should be NULL. |
Description | String | 260 | User's description of this mod. Unused characters should be NULL. |
Master File | String | 4 | "MAST" |
Master Filename Length | Binary | 4 | Indicates the length, in bytes, of the master filename string that follows, including the required trailing NULL. If you're using "Morrowind.esm" as the master file (probably), then this value is 0x0E. |
Master Filename | String | Varies | This is a null-terminated string, typically "Morrowind.esm" but it can be different if you're using a custom ESM file. |
Data | String | 4 | "DATA" |
Data Length | Integer | 4 | 0x08 0x00 0x00 0x00 |
Data | Integer | 8 | Size, in bytes, of the master file: 0x1C 0xF9 0xC1 0x04 0x00 0x00 0x00 0x00 |
Script Data |
|||
Script | String | 4 | "SCPT" |
Script Length | Integer | 12 | Length of the script, from the "SCHD" tag to the end of the script. |
Script Header | String | 4 | "SCHD" |
SCHD Length | Integer | 4 | Appears to always be 0x34. |
SCHD Data | String | Varies | This field contains the name of the script, but also contains additional non-null data at odd offsets, so this is probably also a compiled portion of the script. |
Script Variables (Compiled) | String | 4 | "SCVR" |
SCVR Length | Integer | 4 | Length of the variable section. |
SCVR Data | String | Varies | Each variable name is listed, separated by a null. |
Compiled Script | String | 4 | "SCDT" |
SCDT Length | Integer | 4 | Length of the SCDT field |
SCDT Data | Binary | Varies | Compiled version of the script. |
Script Text | String | 4 | "SCTX" |
SCTX Length | Integer | 4 | Length of the SCTX field |
Script Text Data | String | Varies | Uncompiled, text version of the script. |
Class Data |
This is rare, but if you decide to create a new type of NPC or player class, this is what you would use. | ||
Class | String | 4 | "CLAS" |
Class Size | Integer | 12 | Length of the Class record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length of the unique identifier for this class. |
Name Data | String | Varies | Unique ID name of the class. Ex., "Fighter". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name for this class. Ex., "Fighter". |
Class Data | String | 4 | "CLDT" |
CLDT Length | Integer | 4 | Typically is 0x3C: 15 4-byte values. |
CLDT Data | Set of Integers | 0x3C | Note: These values are IDs that map either to Attributes
or Skills.
Note 2: The Skills are listed with alternating Major and Minor skills, Minor skills starting first. So the order is Minor, Major, Minor, Major.... One thing that is confusing is that the Major skills come in the same order as they appear in the Class dialog box in the TES editor. The Minor skills, though, are in a different order. As far as I can tell, the order of Minor skills in the ESP maps to the dialog as: 1,4,5,3,2. The order only matters if you are trying to map values you see in the ESP to values you see in the dialog box.
|
Class Description | String | 4 | "DESC" |
Desc Length | Integer | 4 | Length of the description, including trailing NULL. |
Desc Data | String | Varies | Describes the class. |
Faction Data |
This is rare, but if you decide to create a new player or NPC faction, this is what you would use. (Ex., Mages Guild, Redoran, etc.) | ||
Faction | String | 4 | "FACT" |
Faction Size | Integer | 12 | Length of the Faction record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length of the unique identifier for this faction. |
Name Data | String | Varies | Unique name of the faction. Ex., "Axe Swingers". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name for this faction. Ex., "Swinging Axes". |
Rank Names | String | 4 | "RNAM" |
RNAM Length | Integer | 4 | Generally always 0x20, with extra space padded by nulls. |
RNAM Data | String | 0x20 | Rank name such as "Acolyte, Initiate, Peon," etc. |
Faction Data | String | 4 | "FADT" |
FADT Length | Integer | 4 | Typically is 0xF0. |
FADT Data | Set of Integers | 0xF0 | [Not decoded yet.] However, this looks like a list of the attribute and skill levels required to attain each of the faction ranks, as well as the general disposition of other faction members to someone with that rank. |
Faction Associations | String | 4 | "ANAM" |
ANAM Length | Integer | 4 | Length of the other faction's unique name. --This is one of the few places where I've seen a string that isn't null terminated. |
ANAM Data | String | Varies | Unique name of another faction. |
Disposition Modifier | String | 4 | "INTV" |
INTV Length | Integer | 4 | Always 0x04 |
INTV Data | Integer | 4 | Amount by which disposition is increased or decreased, if a member of *this* faction meets a member of *that* faction. |
Race Data |
This is rare, but if you decide to create a new player or NPC race, this is what you would use. (Ex., Orc, Human, Elf.) | ||
Race | String | 4 | "RACE" |
Race Size | Integer | 12 | Length of the Race record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length of the unique identifier for this race. |
Name Data | String | Varies | Unique ID name of the race. Ex., "Ogre". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name for this race. Ex., "Ogre". |
Race Data | String | 4 | "RADT" |
RADT Length | Integer | 4 | Typically is 0x8C. |
RADT Data | Set of Integers | 0x8C | [Not decoded yet.] |
Race Spell Information | String | 4 | "NPCS" - This is a repeating field, and appears once for each spell, ability, or power the race has. These are spells that every member of the race will have by default. |
NPCS Length | Integer | 4 | The length of the NPCS field, always appears to be 32 (0x20), with extra space padded with nulls. |
NPC Spell Name | String | Varies | The name of the spell, ability, or power with trailing nulls to pad out any extra space. |
NPC Data |
|||
NPC | String | 4 | "NPC_" |
NPC Size | Integer | 12 | Length of the NPC record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length of the unique identifier for this NPC. |
Name Data | String | Varies | Unique ID name of the NPC. Ex., "npc_22". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name for this npc. Ex., "Joe da Killer". |
Race Name | String | 4 | "RNAM" |
RNAM Length | Integer | 4 | Length of the race name. |
RNAM Data | String | Varies | Name of the npc's race. One of: Argonian, Breton, Dark Elf, High Elf, Imperial, Khajiit, Nord, Orc, Redguard, Wood Elf. |
Class Name | String | 4 | "CNAM" |
CNAM Length | Integer | 4 | Length of the class name. |
CNAM Data | String | Varies | Name of the npc's class. One of: Acrobat, Agent, Alchemist, Alchemist Service, Apothecary, Apothecary Service, Archer, Assassin, Assassin Service, Barbarian, Bard, Battlemage, Battlemage Service, Bookseller, Buoyant Armiger, Caravaner, Champion, Clothier, Commoner, Crusader, Dreamers, Drillmaster, Drillmaster Service, Enchanter, Enchanter Service, Enforcer, Farmer, Gondolier, Guard, Guild Guide, Healer, Healer Service, Herder, Hunter, Knight, Mabrigash, Mage, Mage Service, Master-at-Arms, Merchant, Miner, Monk, Monk Service, Necromancer, Nightblade, Nightblade Service, Noble, Ordinator, Ordinator Guard, Pauper, Pawnbroker, Pilgrim, Priest, Priest Service, Publican, Rogue, Savant, Savant Service, Scout, Sharpshooter, Shipmaster, Slave, Smith, Smuggler, Sorcerer, Sorcerer Service, Spellsword, Thief, Thief Service, Trader, Trader Service, Warlock, Warrior, Wise Woman, Wise Woman Service, Witch, Witchhunter. |
Alliance Name | String | 4 | "ANAM" |
ANAM Length | Integer | 4 | Length of the faction name. |
ANAM Data | String | Varies | Name of the npc's alliance, if any. One of: Redoran, Thieves Guild, Temple, Imperial Cult, Imperial Knights, Hlaalu, Telvanni, Fighters Guild, Morag Tong, Ashlanders, Blades, Clan Quarra, Clan Aundae, Clan Berne, Camonna Tong, Imperial Legion, Mages Guild, Sixth House, Census and Excise, Twin Lamps, Nerevarine, Talos Cult. |
Body Name | String | 4 | "BNAM" |
BNAM Length | Integer | 4 | Length of the body name. |
BNAM Data | String | Varies | Name of the body type associated with this individual. Ex., "breton_m_head_04". |
Hair Name | String | 4 | "KNAM" |
KNAM Length | Integer | 4 | Length of the hair name. |
KNAM Data | String | Varies | Name of the hair style associated with this individual. Ex., "b_n_breton_m_hair_00". |
Stats | String | 4 | "NPDT" |
Stats Length | Integer | 4 | Length of the stats record section. |
Stats Data | Set of Integers | NPC stats can be marked to "auto calculate," which means that they are based on the NPC's level and class. If auto-calc is turned on, then this NPDT section is much shorter than if all the stats are fully specified. | Information is a set of 1-byte integers, listed in this order:
|
FLAG | String | 4 | "FLAG" |
FLAG Length | Integer | 4 | Always 4 bytes long? |
FLAG Data | Integer | 4 | This is a bitmask, containing values for several fields on the NPC.
|
NPC Spell Information | String | 4 | "NPCS" - This is a repeating field, and appears once for each spell, ability, or power the npc has. |
NPCS Length | Integer | 4 | The length of the NPCS field, always appears to be 32 (0x20), with extra space padded with nulls. |
NPC Spell Name | String | Varies | The name of the spell, ability, or power with trailing nulls to pad out any extra space. |
AI Data | String | 4 | "AIDT" |
AI Data Length | Integer | 4 | The length of the AIDT field. Is 0x0C (12 bytes). |
AIDT Data | Integer | 12 | Various AI properties:
|
AI Wander | String | 4 | "AI_W" |
AI_W Length | Integer | 4 | The length of the AI_W field. Is 0x0E (14 bytes). |
AI_W Data | Integer | 14 | The default wander AI module, generally associated with all npcs?
|
NPCO | String | 4 | "NPCO" -- That is an uppercase oh not a zero. This is a repeating field, one for each thing carried in the NPC's inventory. |
NPCO Length | Integer | 4 | May vary, but appears to typically (always?) be 0x24, with extra unused space at the end of the NPCO record padded using nulls. |
Item Quantity | Integer | 4 | Indicates how many of that item are carried. |
Item ID | String | Varies | This the unique name/ID of the item being carried. |
Creature Data |
|||
Creature | String | 4 | "CREA" |
Creature Size | Integer | 12 | Length of the creature record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length of the monster's name, including terminating null character. |
Name Data | String | Varies | Unique ID name of the monster. Ex., "cave_rat". |
Model Name | String | 4 | MODL |
Model Name Length | Integer | 4 | Length of the model filename, including terminating null char. |
Model Name Data | String | Varies | Filename of the NIF file used for this monster. Ex., "r\Rust rat.nif". |
Sound Name | String | 4 | CNAM |
Sound Name Length | Integer | 4 | Length of the sound name, including terminating null char. |
Sound Name | String | Varies | Unique ID of the sound name, as defined in Morrowind. This is often the name of sub-directory under Sound/Cr that holds the .wav files used for this monster, but this is not guaranteed. Ex., "rat". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name. Ex., "Cave Rat". |
Stats | String | 4 | "NPDT" |
Stats Length | Integer | 4 | Length of the stats record section. |
Stats Data | Set of Integers | 96 bytes ? (60 hex) | Information is a set of 4-byte integers, listed in this order:
|
FLAG | String | 4 | "FLAG" |
FLAG Length | Integer | 4 | 0x04 0x00 0x00 0x00 |
FLAG Data | Integer | 4 | This is a bitmask, containing values for several fields on the
monster.
|
Scale | String | 4 | "XSCL" |
XSCL Length | Integer | 4 | The length of the XSCL field, which looks to be 4 bytes always. |
XSCL Data | Float | 4 | The scale of the object as a floating point number from 0.0 to 1.0. |
NPC Spell Information | String | 4 | "NPCS" - This is a repeating field, and appears once for each spell, ability, or power the monster has. |
NPCS Length | Integer | 4 | The length of the NPCS field, always appears to be 32 (0x20), with extra space padded with nulls. |
NPC Spell Name | String | Varies | The name of the spell, ability, or power with trailing nulls to pad out any extra space. |
AI Data | String | 4 | "AIDT" |
AI Data Length | Integer | 4 | The length of the AIDT field. Is 0x0C (12 bytes). |
AIDT Data | Integer | 12 | Various AI properties:
|
AI Wander | String | 4 | "AI_W" |
AI_W Length | Integer | 4 | The length of the AI_W field. Is 0x0E (14 bytes). |
AI_W Data | Integer | 14 | The default wander AI module, generally associated with all creatures?
|
NPCO | String | 4 | "NPCO" -- That is an uppercase oh not a zero. This is a repeating field, one for each thing carried in the monster's inventory. |
NPCO Length | Integer | 4 | May vary, but appears to typically (always?) be 0x24, with extra unused space at the end of the NPCO record padded using nulls. |
Item Quantity | Integer | 4 | Indicates how many of that item are carried. |
Item ID | String | Varies | This the unique name/ID of the item being carried. |
Leveled Creature |
|||
Leveled Creature | String | 4 | "LEVC" |
LEVC Size | Integer | 12 | Length of the leveled creature record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Varies. |
Name Data | String | Varies | Unique ID name of the leveled creature. Ex., "in_cave_alit_lev+0". |
Data | String | 4 | "DATA" |
Data Length | Integer | 4 | 4 bytes |
Data | Flags | 4 | The first byte indicates whether monster placement should be "Calculate from all levels <= player's." A value of 0x01 means yes, a value of 0x00 means no. |
NNAM | String | 4 | "NNAM" |
NNAM Length | Integer | 4 | 0x01 |
NNAM Data | Short Integer | Varies | Percent chance none" value, stored as a single byte. |
INDX | String | 4 | "INDX" - Number of creatures referenced by this instance. |
INDX Length | Integer | 4 | 0x04 |
INDX Data | Integer | Varies | Number of creatures referenced by this instance. I.e. the number of CNAM/INTV record pairs. |
Creature Name | String | 4 | "CNAM" |
CNAM Length | Integer | 4 | The length of the creature's name, including terminating NULL. The CNAM/INTV records are repeated once for each creature that appears in this leveled instance. |
CNAM Data | String | Varies | Unique name of a creature. |
Creature Level | String | 4 | "INTV" |
INTV Length | Integer | 4 | 0x02 |
INTV Data | Short Integer | Varies | Difficulty level assigned to the previous creature (CNAM) record. This is stored as a 2-byte integer. |
Activator |
For a reference to an Activator, see Reference to an Object. | ||
Activator | String | 4 | "ACTI" |
Activator Size | Integer | 12 | Length of the activator record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Varies. |
Name Data | String | Varies | Unique ID name of the activator. Ex., "active_com_bed_01". |
Model Name | String | 4 | MODL |
Model Name Length | Integer | 4 | Length of the model filename for this activator. |
Model Name Data | Integer | 4 | Filename of the NIF file used for this activator. Ex., "f\Furn_Com_Bed_01.nif". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name. Ex., "Bed". |
Script Name | String | 4 | "SCRI" |
SCRI Length | Integer | 4 | Length of the name of the script, including trailing null. |
SCRI Data | String | 4 | Null-terminated name of the script used to activate this item. Ex., "Bed_Standard". |
Miscellaneous |
|||
Misc | String | 4 | "MISC" |
Misc Size | Integer | 12 | Holds the length of the miscellaneous record. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Varies. |
Name Data | String | Varies | Unique ID name of the misc item. Ex., "Misc_SoulGem_Common". |
Model Name | String | 4 | MODL |
Model Name Length | Integer | 4 | Length of the model filename for this item. |
Model Name Data | Integer | 4 | Filename of the NIF file used for this item. Ex., "m\misc_soulgem_lesser.nif". |
Friendly Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the friendly name, including trailing null. |
FNAM Data | String | Varies | User-friendly name. Ex., "Common Soulgem". |
Extra Data | String | 4 | "MCDT" |
Data Length | String | 4 | Looks like it is usually 12 (0x0C). |
Extra Data | Values | 12 | This field holds the weight of the item in the first 4 bytes as a floating point number. The next 4 bytes hold the goldpiece value of the item as an integer. The last 4 bytes are by default zero: not sure what they are used for. |
Script Name | String | 4 | SCRI |
Script Name Length | Integer | 4 | Length of the script name for this item. |
Script Name Data | Integer | 4 | Unique name of the optional script that can be attached to this object. Ex., "make_them_sorry". |
Inventory Picture Name | String | 4 | ITEX |
Picutre Name Length | Integer | 4 | Length of the picture filename for this item. |
Picture Name Data | Integer | 4 | Filename of the TGA or other file used for this item when it is shown in the inventory window. Ex., "m\misc_soulgem_common.tga". |
Container |
For a reference to a Container, see Reference
to an Object.
To define a new container (for when you want to create a container that isn't empty, etc.): | ||
Container | String | 4 | "CONT" |
Container Length | Integer | 12 | Length of the rest of the container data. |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Varies. |
Name Data | String | Varies | This is actually the unique ID of the container. |
MODL | String | 4 | "MODL" |
MODL Length | Integer | 4 | Varies. |
MODL Data | String | Varies | Name of the NIF model associated with the container.
Example: "o\Contain_Com_Chest_01.nif" |
FNAM | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Varies |
FNAM Data | String | Varies | User-friendly name of the container. |
CNDT (Container Weight) | String | 4 | "CNDT" |
CNDT Length | Integer | 4 | Always a length of 4. |
CNDT Data | Float | 4 | Container Weight. This is how much stuff the container can hold, as a floating point number. |
FLAG | String | 4 | "FLAG" |
FLAG Length | Integer | 4 | Length is always a value of 4. |
FLAG Data | Integer | 4 | By default is "0x08". |
NPCO | String | 4 | "NPCO" -- That is an uppercase oh not a zero. This is a repeating field, one for each type of thing inside the container. |
NPCO Length | Integer | 4 | May vary, but appears to typically (always?) be 0x24, with extra unused space at the end of the NPCO record padded using nulls. |
Item Quantity | Integer | 4 | Indicates how many of that item are in the container. |
Item ID | String | Varies | This the ID of the item that is in the container. |
Sounds |
|||
Sound | String | 4 | "SOUN" |
Sound Length | Integer | 12 | Total length of the sound definition, starting at the NAME field. |
Name | String | 4 | "NAME" |
Field Length | Integer | 4 | Length of the name, including null terminator. |
NAME Data | String | Varies | The unique ID of the sound. Ex., "Stone_Door_Open_01" |
File Name | String | 4 | "FNAM" |
FNAM Length | Integer | 4 | Length of the file name, including trailing null. |
FNAM Data | String | 4 | Filename of the WAV file used for this sound. Ex., "Fx\Stone01.wav". |
Data Prefix | String | 4 | "DATA" |
Data Length | Integer | 4 | Length in bytes of the sound data. Appears to always be 0x03. |
Sound Data | Set of Values | 3 | Not sure what these values mean. Most common values appear to
be: 0xFF 0x00 0x00 |
Exterior Cell Data |
All exterior cells appear to be of the same size. They also appear to
be arranged in a grid, with position 0,0 being on the equator in the
center of the world map. Exterior cells are assigned a unique spot inside
this grid, with some spots having negative values--haven't determined if
negative indicates north or south of the center-line.
Still haven't determined where the "Illegal to Sleep Here" flag is stored. Nor do we know where the Map Color information is stored. The meaning of some of the internal fields is also a mystery, especially the PGRP, PGRD, and PGRC sections. | ||
Begin Cell |
String | 4 | "CELL" |
Cell Length | Integer | 12 | Length, in bytes, of this cell, following the Cell Length. |
Cell Name | String | 4 | "NAME" |
Cell Name Length | Integer | 4 | Length in bytes of the cell name, including the required terminating null. |
Cell Name | String | Varies | The cell name, including the required terminating null. |
Data | String | 4 | "DATA" |
Data Length | Integer | 16 | Length in bytes of the cell data? |
RGNN | String | 4 | Name of the region this cell is associated with. The region controls the weather. |
RGNN Length | Integer | 4 | Length of the region name, including trailing null. |
Region Name | String | Varies | The name of the associated region, including trailing null. |
NAM5 | String | 4 | Start of NAM5 section. |
NAM5 Length | Integer | 4 | Length of the NAM5 string. |
NAM5 | String | Varies? | ??? |
Referenced Object List | List of FRMR records | Varies | At this point, any creatures or other objects (including building exteriors) that show up in the cell are listed as FRMR records. |
LAND | Precedes the height map, vertex normals, texture coordinates, etc. | ||
LAND Data | Unknown | 12 | Unknown. Possibly the size of the remaining data. |
Cell Position | String | 4 | "INTV" (Integer Values?) |
INTV Length | Integer | 4 | Length of the INTV data, always 8. |
INTV Data | Int | 8 | This is the Row,Col coordinates of the cell. This might be its logical location inside the owning region, but more probably it is the cell's location on the world map. E.g., when you see an exterior cell, it often has a name like: "Ald Daedroth - (11,20)." The 11,20 shows the cell's position relative to all defined exterior cells, with values of 0,0 representing the equator/prime meridian, as about half of the cell values are negative. |
Data | String | 4 | "DATA" |
Length | Integer | 4 | Length of the DATA section. |
DATA | Unknown | 4 | Unknown |
VNML | String | 4 | "VNML" |
Length | Integer | 4 | Length of the VNML section. |
VNML Data | ??? | ?? | Probably vertex normal information, where each normal is evenly spaced in x,y terms across the land grid? Typically normals are stored as (X, Y, Z) vectors, so that is probably how they are stored here.... |
VHGT | String | 4 | "VHGT" |
Length | Integer | 4 | Length of the VHGT section. |
VHGT Data | ??? | ?? | Vertex height field? Probably the Z coordinates of each vertex, since X & Y are spaced evenly in the cell. I'm pretty sure they're 16-bit values. The downside is that you're limited to 2730 feet above or below sea level (as the unit of measurement here is one inch?). The highest point of Dagoth Ur is only about 800 feet above sea level. There goes making Mt. Everest, eh? |
WNAM | String | 4 | "WNAM" |
Length | Integer | 4 | Length of the WNAM section. |
WNAM Data | Unknown | Varies? | Unknown |
VCLR | String | 4 | "VCLR" |
Length | Integer | 4 | Length of the VCLR section. |
VCLR Data | RGB Triplet List | Varies | Vertex Colors. RGB triples repeated for each vertex (1 byte per color per vertex, or 3 bytes per vertex). |
VTEX | String | 4 | "VTEX" |
Length | Integer | 4 | Length of the VTEX section. |
VTEX Data | Texture Index List | Varies | Vertex Colors. RGB triplets repeated for each vertex (1 byte per color per vertex, or 3 bytes per vertex). |
PGRD | String | 4 | "PGRD" |
Length | Integer | 4 | Length of the PGRD section. |
PGRD Data | Unknown | Unknown | Unknown |
Data | String | 4 | "DATA" |
Length | Integer | 4 | Length of the DATA section. |
DATA | Unknown | 4 | Unknown |
Name | String | 4 | "NAME" |
Name Length | Integer | 4 | Length in bytes of the name, including the required terminating null. |
Name | String | Varies | Appears to be a duplicate of the cell name? |
PGRP | String | 4 | "PGRP" |
Length | Integer | 4 | Length of the PGRP section. |
PGRP Data | Unknown | Unknown | Unknown |
PGRC | String | 4 | "PGRC" |
Length | Integer | 4 | Length of the PGRC section. |
PGRC Data | Unknown | Unknown | Unknown |
Interior Cell Data |
|||
Cell | String | 4 | "CELL" |
Cell Length | Integer | 12 | Length, in bytes, of this cell, following the Cell Length. |
Cell Name | String | 4 | "NAME" |
Cell Name Length | Integer | 4 | Length in bytes of the cell name, including the required terminating null. |
Cell Name | String | Varies | The cell name, including the required terminating null. |
Data | String | 4 | "DATA" |
Data Length | Integer | 4 | Length in bytes of the cell data. |
Cell Data | Set of Values | 12 | Default values are:
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x3F The first four bytes area a bitmask that controls whether there is water in the cell and whether it is illegal to sleep here. (a) If there is water, the first value changes to 0x03. (Switch on the 0x02 bit.) Control the height of the water in the INTV data section (next). Not sure what the default 0x01 value means, though. (b) If it is illegal to sleep here, the first number should be 0x05. (Switch on the 0x04 bit). (c) If there is both water and it is illegal to sleep, change to 0x07 (first three bits set).
The next four bytes show the level of fog in the cell. Note: this information duplicates information also given in the AMBI data (follows the INTV section).
The last 4 bytes are a floating point number that is the Fog Density, in a range of 0.0f to 1.0f. Note: this information is duplicated in the AMBI data (follows the INTV section). |
INTV | String | 4 | "INTV" (Integer Value?) |
INTV Length | Integer | 4 | Length of the INTV data, always 4. |
INTV Data | Int | 4 | Height of water in the cell. For water to be turned on, Cell Data needs to be modified also (see above). E.g., for a water height of five units (not sure if this maps to logical game units of about 1 inch per, or what), do 0x05 0x00 0x00 0x00. Water height is given relative to z=0, which means that a "negative" water height will make sense in some cells. |
AMBI | String | 4 | "AMBI" -- contains ambient lighting information for the cell. |
AMBI Length | Integer | 4 | Length of the AMBI field data. |
AMBI Data | 4 Sets of 4 Integers | 16 | The default values are:
0x47 0x47 0x47 0x00 0xF2 0xD9 0xD9 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x3F
The first 4 values correspond to RGB ambient lighting, although the default value of 0x47 does not correspond to what's shown for the default ambient lighting in the editor! 0x47=66, but the editor was showing 71 for these values.... But when you change the values, they match up exactly. The 4th value for ambient lighting always appears to be 0x00.
The next 4 values 0xF2 0xD9 0xD9 0x00 correspond to the RGB Sunlight values in the cell, with the 4th value always being zero.
The next 4 values (all zeroes by default) correspond to the RGB Fog values in the cell, with the 4th value always being zero. Duplicated in the Cell Data section above.
The last 4 bytes are a floating point number that is the Fog Density, in a range of 0.0f to 1.0f. Duplicated in the Cell Data section above. |
NAM0 | String | 4 | "NAM0" -- Note that is a trailing zero character, not an uppercase oh. It looks like this precedes the list of referenced objects (FRMRs) that are in a cell. This only appears once, no matter how many objects are in the cell. |
NAM0 Length | Integer | 4 | By default is 0x04 0x00 0x00 0x00. |
NAM0 Data | Integer | 4 | Not sure? At times, this appears to indicate the number of FRMR records in the list, but this isn't always the case.... |
Referenced Object List | List of FRMR records | Varies | At this point, any creatures or other objects (including building exteriors) that show up in the cell are listed as FRMR records. |
Reference to an Object |
Any time you reference any kind of object (static, container, creature, activator, etc.), you can use this same format. Only if you create a new kind of thing, or create a full copy of a thing, do you need to use a more detailed format. | ||
FRMR | String | 4 | "FRMR" -- Don't know what it stands for. |
Field Length | Integer | 4 | Value is always 4. |
FRMR Data | Index | 4 | Index of this object inside the cell. First object in the cell is 0x01. Next object is 0x02, and so forth. |
Name | String | 4 | "NAME" |
Field Length | Integer | 4 | Length of the name, including null terminator. |
NAME Data | String | Varies | The name of the referenced object. E.g., "in_v_s_corner01" |
Scale [Optional] | String | 4 | "XSCL" -- This field is only exported if the scale of the item is not 1.0. |
Scale Length | Integer | 4 | Always has a length of 4. |
Scale Data | float | 4 | The scale of the item, if not 1.0. |
Lock Info [Optional] | String | 4 | "FLTV" -- This field is only exported if the item is a container or door that is locked. |
FLTV Length | Integer | 4 | Always has a length of 4. |
Lock Data | Integer | 4 | The lock difficulty, a value of 0 to 100. |
Key Info [Optional] | String | 4 | "KNAM" -- This field is only exported if the item is a container or door that is locked and there is a key that opens it. |
KNAM Length | Integer | 4 | The length of the null-ternimated name of the key. |
KNAM Data | String | Vaires | The null-ternimated name (unique id) of the key. |
Trap Info [Optional] | String | 4 | "TNAM" -- This field is only exported if the item is a container or door that is trapped. |
TNAM Length | Integer | 4 | The length of the null-ternimated name of the trap. |
TNAM Data | String | Vaires | The null-ternimated name (unique id) of the spell effect associated with the trap. |
Data | String | 4 | "DATA" |
Data Length | Integer | 4 | Always 24 bytes long (0x18). |
Data | Set of Values | 24 |
First 3 values are the X, Y, Z coordinates of the object, given as 3 floating point numbers (4 bytes each). Next 3 values are the X, Y, Z rotation of the object, given as 3 floating point numbers (4 bytes each), but the numbers are stored as radians, rather than as degrees (although the editor shows them as degrees). |
Teleporting Door |
For a non-teleporting door, see Reference to an Object. Teleporting doors still appear as FRMR records inside a cell, not as separate records at the beginning of the file (unlike most other object definitions). | ||
FRMR | String | 4 | "FRMR" -- Don't know what it is |
Field Length | Integer | 4 | 0x04 0x00 0x00 0x00. |
FRMR Data | Index | 4 | Index of this object inside the cell. First object in the cell is 0x01. Next object is 0x02, and so forth. |
Name | String | 4 | "NAME" |
Field Length | Integer | 4 | Length of the name, including null terminator. |
NAME Data | String | Varies | The name (ID) of this door. E.g., "door_cavern_doors10". |
DODT | String | 4 | "DODT" |
Field Length | Integer | 4 | Length of the DODT section: 0x18 0x00 0x00 0x00. |
DODT Data | Set of Values | 24 | The location information for where exactly you will arrive. I.e., the X,Y,Z coordinates and then the X,Y,Z rotation of the travel marker that is at the other end of the teleport. |
Destination Name [Optional] | String | 4 | "DNAM" -- Only used for teleporting to an interior cell. |
Field Length | Integer | 4 | Length of the destination name, including null terminator. |
DNAM Data | String | Varies | The interior cell name of the location where the door takes you to. E.g., "Balmora, Guild of Mages" |
Data | String | 4 | "DATA" |
Data Length | Integer | 4 | Length of the data: 0x18 0x00 0x00 0x00. |
Data | Set of Values | 24 | X,Y,Z location followed by the X,Y,Z rotation of the door itself. One floating point number for each coordinate. |
Contributors:
Dave Humphrey
Dizzy
Erik Benerdal (aka
Scarabus of Fudge Entertainment)
Jason
Hoffoss
Jim Adam
Maurizio
Raymond Tukkers
To contribute information, please email Jim Adam.