...
Parameter Name | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
---|---|---|---|---|---|---|
setsupermodel | setsupermodel <model_name> <supermodel_name> | c_colemrald pfe0 | NULL | Text | 2 parts:
| This command references other model files. A model may have a (super)model from which it inherits animations. If there is no supermodel the second parameter has to be NULL. The model may overwrite any animation from its supermodel. The structure of the two models must to match, i.e. the order of the objects in both files must be the same. |
classification | classification <classification> | character | Not set (0 in binary) | Text | If not left out of definition it should be on of these:
| If not included no special classification is applied. This is entirely valid and happens on things like GUI models where this flag is simply not set (in binary it's set to 0). The other 4 all have some (unknown) level of changes in the engine when loaded, so while you can reference a door object in placeables.2da it is likely better to first of all make a copy of the model and alter this classification to match the character one. The engine may make further assumptions about the model classification however, depending on how it is loaded (eg; via. an appearance.2da line, GUI model, placeables.2da, visualeffects.2da, etc.) but this needs testing.
These classifications affects render order, hitchecks, highlighting and probably a bunch of other stuff. If anyone has concrete information about what the engine does with this please let us know on Discord or get an account and edit this in. |
setanimationscale | setanimationscale <scale> | 1.4 | 1 | Float | Positive float values (eg; 0.1 to 3.0, but not a negative like -1.5) | Even if the model hasn't got animations, or the property isn't set, when compiled it will obtain a default value of 1 Obviously only applicable to things with animations, usually a creature model that is inheriting animations from a parent super model |
beginmodelgeom | beginmodelgeom <model_name> | helm_001 | n/a | Text | Filename | This starts the geometry definition of the model, reuse the filename for the parameter |
endmodelgeom | endmodelgeom <model_name> | helm_001 | n/a | Text | Filename | This ends the geometry definition of the model, reuse the filename for the parameter |
newanim | newanim <animation_name> <model_name> | fog pln_fog | n/a | Text | Two parts which are likely limited to 16 characters:
| This starts an animation definition in the model. You can have multiple animations tied to the parent model. These can also override the super model used for animations set with the setsupermodel parameter. |
doneanim | doneanim <animation_name> <model_name> | fog pln_fog | n/a | Text | Copy of newanim | Ends that animation definition. A new animation may occur afterwards. |
...
Parameter Name | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
---|---|---|---|---|---|---|
center | n/a | Float | n/a | Unused by the game. Would possibly have been the pivot point of the object. Instead the nodes determine the object layout and attach points/center points. | ||
ambient | ambient <R> <G> <B> | 1.0 1.0 .1.0 | Float | OpenGL GL_Ambient material parameter. If it is lower then the texture on the model becomes quite dark. The default is a sane 1.0 1.0 1.0 so it can be "safely" left out, but better to set it manually. Note the old Bioware default was 0.2 0.2 0.2 where usually you'd want it set to 1.0 1.0 1.0 so if a model looks dark decompile it and change it to 1.0 1.0 1.0 (this was updated in patch 1.81.8193.17) | ||
diffuse | diffuse <R> <G> <B> | diffuse 1.0 1.0 1.0 | 1.0 1.0 1.0 | Float | 0.0 to 1.0 for each R, G and B | Material diffuse colour, ie the RGB applied to the main texture0 file. It is a relatively cheap way to get a different coloured creature; say you wanted a "red" goblin you'd set it to 1.0 0.0 0.0. Frankly in this day and age creating a better replacement texture on a new model, or even using ReplaceObjectTexture, or shaders is a much better idea. The default is a sane 1.0 1.0 1.0 so it can be "safely" left out, but better to set it manually. Note the old Bioware default value were 0.8, 0.8, 0.8 which are awful. Use 1.0, 1.0, 1.0 by default in your own models else your texture will come out weird (this was updated in patch 1.81.8193.17) |
specular | specular <R> <G> <B> | specular 0.5 0.5 0.5 | 0.0 0.0 0.0 (But can be ignored) | Float | Material specular color, however this has no effect. Compiled models do include it and default to 0.0 0.0 0.0 | |
shininess | shininess <shininess_value> | shininess 1.0 | 1.0 (But ignored by engine) | Float | This appears to be now unused as of NWN:EE, if it was ever used before the current renderer at least now ignores it, but it is still saved to the compiled model if left out (at least with a sane default 1.0) | |
render | render <on_off_boolean> | render 1 | 1 | Boolean | 1 - this model is rendered in the game world 0 - this model is not rendered in the game world | Controls whether this object should be rendered. The geometry will still be loaded to the memory and casts shadows, even if this is unchecked. This is frequently used in conjunction with the Shadow attribute to create a low-poly shadow volume object. Valid values are either 0 (disabled) or 1 (enabled). Please use 1 and 0 instead of things like "true" and "false" here. |
shadow | shadow <on_off_boolean> | shadow 0 | 1 | Boolean | 1 - shadows are attempted to be rendered for this object 0 - shadows are not rendered for this object ever | Shadow rendering only works with trimesh, not with skinmesh (and likely not animmesh or danglymesh). It also doesn't work well on models with high face counts - best idea to really do shadows well on a model is to have the usual model with render 0 and with shadow 0 set, and shadow version created as a much simpler trimesh with shadow 1 and render 0 set. Keep the new one much lower on the faces count (sub-100 or even lower) since it helps not have errors in the resulting shadows and keeps things running fast. See this Model Shadows page for more information. It needs expanding to cover the ins and outs and all the different object types using them and how the game renders it, as well as debugging them and best practices. Disabling shadows is also recommended for things generating their own light and which casting a shadow makes no sense (like ghosts or other see through things) since the shadows are quite "hard" and cannot be altered to be more transparent per-creature. |
renderhint | renderhint <renderhint_option> | renderhint NormalAndSpecMapped | Not set - "" | Text (set options) | NormalAndSpecMapped NormalTangents | EE only. Either option provides the same results. The model compiler seems to sets a flag to 1 if either are set. Instructs the game to generate tangent and handedness vertex data for the associated model(s), provided that they are uncompiled and no tangent and handedness data exist. Also makes the game choose a shader with normal mapping enabled to render this content. Note: The renderhint can also be specified in a MTR material file. |
beaming | beaming <on_off_boolean> | beaming 1 | 0 | Boolean | 1 - beaming is on 0 - beaming is off | For light-rays. Light rays cannot be made specifically for a tile, as tiles can rotate. Instead a different kind of shadow was created where the shadow volume is rendered at an alpha value and a specific color. To create shadow volumes, make a group of simple triangles above the camera level and enable this flag. |
inheritcolor | 0 | Boolean | 1 - inherit colour 0 - do not inherit colour | Apparently not used by the game (in fact no base game Bioware model sets this to 1 on any node!) but if you think it is used provide an example. Might have been so nodes that have a parent inherit their trimesh "colors" value from them (presumably that colour being the ambient or diffuse numbers? or the "colors" array under trimesh?). To be honest even if it did work there is little reason to use it today and you can simply define colours per-node anyway which is safer. Note the binary stores this weirdly as a integer, even though it should be a boolean. | ||
alpha | alpha <alpha_amount> | alpha 0.5 | 1.0 | Float | 0.0 to 1.0 | Alpha value controlling transparency. Valid values are floating point numbers within [0.0, 1.0] - 0.0 being fully transparent and 1.0 fully opaque. This property can be animated. |
transparencyhint | transparencyhint <transparency_priority> | transparencyhint 1 | 0 | Integer | Values 0 through 9 0 - Transparency hint disabled - will be rendered before transparent items 1 - 9 - Transparency hint enabled - and will display in order, so 9 will be rendered last. | As transparency can be extremely costly to calculate from alpha values on a texture, this property gives the engine priority values of transparent objects. An object with a transparency hint of 1 will be rendered after an object that has a value of 0. The values appear to work up to 9 (10 values total) but this needs fully testing since the value stored in the compiled MDL is a UINT32 (then again boolean values have UINT32...silly Bioware) (NEEDS TESTING MAY BE WRONG) This does not work on dynamic objects, it only affects static objects (this might mean only works with trimesh? - Jasperre) |
selfillumcolor | selfillumcolor <R> <G> <B> | selfillumcolor 1.0 0.5 0.5 | 0 0 0 | Float | Colour values 0.0 to 1.0 | Makes the mesh glow without actually acting as a light source. It most likely corresponds to the GL_EMISSION material parameter in OpenGL. This property can be animated. Note: In older mdl files this parameter might be spelled wrongly as |
Textures | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
materialname | materialname <material_filename> | materialname m_helm_002 | Not set - "" | Text | MTR file name so 16 characters maximum | EE only. The MTR file is able to define textures, or override textures defined in the MDL (but you can specify textures0 through 2 in the MDL, so the MTR can partially define textures) for use with Standard material inputs (fancymaps). Therefore a good use case is set texture0 for the diffuse in the MDL and have texture1 through texture4 defined in the MTR for fancymapping purposes, allowing one MTR file to be shared by multiple of the same model, but with different colours etc. - very useful for phenotype based armor. |
bitmap | bitmap <texture_filename> | bitmap c_aribeth_evil | Not set ("") if not defined (equivalent to NULL) | Text or NULL | Texture file name (Priority of loading: DDS / PLT / TGA), so 16 characters maximum Note MTR files take precedence | This is an alias for texture0. While it is very common (most decompilers use it by default as the name of the field) texture0 is a bit more sensible with the advent of MTR files properly using the texture0 through texture10 options in that file as per below for fancymaps. |
texture0 | texture0 <texture_filename> | texture0 c_aribeth_evil | Not set ("") if not defined (equivalent to NULL) | Text or NULL | Texture file name (Priority of loading: MTR / DDS / PLT / TGA), so 16 characters maximum Note MTR files take precedence | Usually texture0 is the base texture used on this node of the model. Can be omitted or preferably set to NULL if the texture isn't going to be rendered (see render above). Textures not found (or no texture defined) default to blank white usually in game. Cloaks have a special 2da that loads an overriding texture0 - see cloakmodel.2da (the prefix of the file is hardcoded and the ID number is from the 2da "TEXTURE" column). There may be also default loading of texture0 for parts-based phenotype models. Needs checking. As noted above bitmap is an alias but with MTR files using texture0 through texture15 the saner thing is to define just texture0 so it fits in and is more easily identifiable. As per the fancymap specs if you use them; you could potentially have the MDL apply the Diffuse (base texture), Normal and Specular per-model and the MTR apply the rest. |
texture1 texture2 texture3 | texture1 <texture_filename> | Untested | Not set ("") if not defined (equivalent to NULL) | Text or NULL | The original 1.69 format allows texture1, texture2 and texture3 defined as well although Bioware never used it in their models and it might not have done anything useful and it might just be broken. If it is usable it needs fully testing and the fancymap specs go up to texture5 (6 textures total) meaning 2 of them always have to be in the MTR file anyway, making it a bit useless. | |
Tile Specific | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
tilefade | tilefade <fade_option> | tilefade 1 | 0 | Integer (set values) | Options:
| This property is only relevant for tiles. It controls whether this mesh will turn invisible to offer a clear line of sight on the character. |
rotatetexture | rotatetexture <on_off_boolean> | rotatetexture 1 | 0 | Boolean | 1 - rotate texture on this tile 0 - don't rotate this texture | Only relevant for tilesets and controls ground mapping: When a model with this flag is rotated, the engine rotates the uv coordinates back to the original position. This avoids texture seams on tile edges. |
trimesh | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
verts | verts <vertex_total> | verts 4 | n/a | Integer for vertex_total Float for X/Y/Z | Positional data can be negative, positive or 0.0 for X/Y/Z | Vertices. Every lines defines a single vertex. The faces section on a node references the indices of three vertices for every face. It is recommended (and possibly required) to keep the vertex_total number the same across all of the geometry definitions in this section except the faces. |
tverts | tverts <vertex_total> | tverts 4 | n/a | Integer for vertex_total Float for U/V Last parameter is always 0 | Positional data can be negative, positive or 0.0 for U/V Usually defined the same amount as the verts. | Texture Vertices. Every lines defines a single texture vertex (tvert). They are 2-dimensional - the last value is always 0. The faces section on a node references the indices of three tverts for every face. |
faces | faces <faces_total> | faces 2 | n/a | Integer for faces_total Integer for all indexes (V1/2/3, S, UV1/2/3, M) | All the entries are indexes, starting from 0. | Each line defines a triangle:
This number is primarily what you can use to check the model complexity. |
colors | colors <vertex_total> | colors 4 | n/a | Integer for vertext_total Float for R/G/B | Float for R/G/B between 0.0 and 1.0 | Vertex colors. Each line contains the color for the corresponding vertex in the vertex list, as such the number of colors must match the number of vertices. Vertex colors are not used by the default shaders. Bioware rarely used this so there isn't much loss to not having it. Changing the diffuse texture is recommended instead. |
tangents | tangents <vertex_total> | tangents 4 | Integer for vertex_total Float for X/Y/Z and S | NWN:EE only. Part of generating normal map ("fancymap") data for better models/lighting. Tangents can be generated by the in game compiler (which are added to compiled models automatically to save time generating them again next time the model is loaded), but can be included in the ASCII model if fine tuned. Most of the time it is much easier to leave them out of the ASCII MDL and compile it in game just before releasing the model. Per-vertex tangent data. Each line contains the value for the corresponding vertex in the vertex list, as such the number of tangents must match the number of vertices.
| ||
normals | normals <vertex_total> | normals 4 | Autogenerated | Integer for vertex_total Float for X/Y/Z | NWN:EE only. Part of generating normal map ("fancymap") data for better models/lighting. Per-vertex normals. Each line contains the normal for the corresponding vertex in the vertex list, as such the number of normals must match the number of vertices. Normals can be generated by the in game compiler (which are added to compiled models automatically to save time generating them again next time the model is loaded), but can be included in the ASCII model if fine tuned. Most of the time it is much easier to leave them out of the ASCII MDL and compile it in game just before releasing the model. Note: will not be regenerated for already compiled models, you must have the file loaded from ASCII to generate them afresh (say if you alter the normal map file). | |
danglymesh | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
displacement | displacement <displacement_amount> | displacement 0.0350000001 | 0 | Float | Positive non-zero float to get an effect | Determines show far the vertices are allowed to move. This is further restricted by the constraints. The value appears to be approximately 1/2 meter per unit. Note: In animation files and others which don't really use the danglymesh defined, this and period/tightness are just set to 0 and no constraints list is present. Example: a_fa.mdl with head_g for instance. |
period | period <period_amount> | period 8 | 0 | Float | Positive non-zero float to get an effect | Determines how quickly the vertices move and how fast they come to a rest. This value can be up to 59 before the mesh begins to jiggle incorrectly. At 59.5 the mesh may spasm sporadically. At 60 or above, the mesh will jiggle insanely for up to 1 second and then no longer jiggle, becoming locked at the starting position. Tile grass (as created by walkmesh surface material 3) uses effects equivalent a hardcoded value greater than 60. It appears to be the only thing which can use this high a value. |
tightness | tightness <tightness_amount> | tightness 3 | 0 | Float | Positive non-zero float to get an effect | The ’tension’ in the object, restricting movement. A tight object is difficult to move by wind. Tile grass may have an approximate tightness of 50 or more. |
constraints | constraints <constraints_total> <list_of_constraints> | constraints 4 | Not included if none defined (ie blank) | Array of Integers | Not sure there is a limit to the number of constraints since it is per-vertex. Each value needs to be on a new line and be between 0 and 255 (byte size). | Each line contains the constraints for the corresponding vertex in the vertex list, as such the number of constraints must match the number of vertices. Constraints act as a multiplier for the displacement value and range from 0 to 255, with their value equating to the multiplier range of 0 to 1. If the maximum displacement is set to 2, then the associated vertex painted with 255 will be allowed to move approximately 1 meter during maximum strength wind. |
animmesh | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
sampleperiod | ||||||
animverts | ||||||
animtverts | ||||||
skin (skinmesh) | Definition | Example Contents | Game Default | Type | Valid Values | Description and Notes |
weights | weights <vertex_total> | weights 4 | n/a | Integer for vertex_total N1 through N4 need to be MDL Text, node names W1 through W4 are Float | N2 - N4 and W2 - W4 are optional N1 through N4 need to be MDL Text, node names W1 through W4 are Float between 0.0 and 1.0 (Sum of line must be 1.0) | Every skinmesh must specify weights which influence its movements. Each line contains the weights for the corresponding vertex in the vertex list, as such the number of entries must match the number of vertices.
|
...