Quick ‘n dirty guide to .mor modding
This guide is very heavily in debt to LOTC’s mop modding tutorial. If you want to make significant alterations to an NPC’s face you’d be best off starting from scratch in the CC (LOTC’s NPC presets are a great starting point). But if you merely want to make cosmetic edits (i.e. not alter the face shape, but change the hair or tints or textures used) then you bypass a lot of long and imprecise work by just editing the headmorph (.mor) directly. You will need to know how to use pyGFF.
Morph parts
- 23000 MORPH_PARTS [ECString] (4 items) 0 base head ECString art\characters\playercharacter\humanmale\mt_bas_hm 1 eye mesh ? ? 2 hair mesh ECString art\characters\playercharacter\humanmale\hm_har_ha01a 3 beard mesh ECString art\characters\playercharacter\humanmale\hm_brd_hm01
The eye mesh is usually empty, since eyes are included in the base head.
These morph parts and the tint files below are indexed, so they always go in this order. If the node for the beard mesh is missing you can add it to the end of the list.
Tints
- 23001 MORPH_TINTFILENAMES [ECString] (12 items) 0 skin ECString t1_skn_h07 1 lipstick ECString t1_mul_bk3 2 eye ECString t3_eey_gn2 3 hair/beard/scalp ECString tints\t3_har_lotc27 4 eyeshadow ECString t1_mue_re3 5 blush ECString t1_mub_r02 6 tattoo channel R ECString t1_tat_blk 7 tattoo channel G ECString t1_tat_blk 8 tattoo channel B ECString t1_tat_blk 9 tattoo channel A ECString t1_tat_blk 10 eyebrow/stubble ECString tints\t1_stb_lotc24 11 unused ECString tints\t1_stb_lotc27
11 is set by the CC to match the hair tint, but is not actually used in the game.
Morph Nodes
Texture and vector parameters, i.e. basically everything else, are hiding under 23002 MORPH_NODES, along with all the vertex data for the headmorph.
These texture and vector parameters are referenced by name rather than by index, so you can add and remove whatever parameters you want in whatever order you want.
If you cross-reference with the morph_mat_params table included in LOTC’s mop modding tutorial against the parameters in the headmorph, you can see how the data was copied over in a reasonably predictable fashion.
The face (FaceM1)
Somewhere near-ish the bottom of the lengthy list of nodes, you’ll find one named 1753679605, which corresponds to FaceM1. This is where you want to change the skin textures, facial hair, tattoos, and makeup.
2 NAME UINT32 1753679605 4 POSITION Vector3f 8013 MESH_STREAM_VERTEXCOUNT UINT32 8024 MESH_STREAM_VERTEXDATA [FLOAT32] + 23004 MORPH_TEXTUREPARAM [tprm] (4 items) + 23005 MORPH_VECTOR4FPARAM [vprm] (5 items)
Skin textures (FaceM1)
2 NAME UINT32 175367905 - 23004 MORPH_TEXTUREPARAM [tprm] - 0 tprm 2 NAME ECString mml_tDiffuse 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_hed_trqa_0d - 1 tprm 2 NAME ECString mml_tNormalMap 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_hed_trqa_0d - 2 tprm 2 NAME ECString mml_tAgeNormalMap 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_hed_olda_0d - 3 tprm 2 NAME ECString mml_tAgeDiffuseMap 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_hed_olda_0d
FaceM1 can accept four skin texture parameters: a base diffuse and normal map, and an age diffuse and normal map. If only the age textures are listed then the base textures default to mt_hed_masa or mt_hed_fema depending on the gender.
The base and age textures can be blended together with the mml_fAgeBlendWeight vector parameter:
2 NAME UINT32 175367905 - 23005 MORPH_VECTOR4FPARAM [vprm] - 0 vprm 2 NAME ECString mml_fAgeBlendWeight - 17 VECTOR4F_LIST [Vector4f] (6 items) 0 diffuse 0, 1, 2, 3 Vector4f 0.0, 0.0, 0.0, 0.0 1 diffuse 4, 5, 6, 7 Vector4f 0.0, 0.0, 0.0, 0.0 2 diffuse --, --, --, 11 Vector4f 0.0, 0.0, 0.0, 1.0 3 normal 12, 13, 14, 15 Vector4f 0.0, 0.0, 0.0, 0.0 4 normal 16, 17, 18, 19 Vector4f 0.0, 0.0, 0.0, 0.0 5 normal --, --, --, 20 Vector4f 0.0, 0.0, 0.0, 1.0
0.0 shows only the base texture, 1.0 shows only the age texture. These are the in the same order as the indices of the blend weights in a .mop preset:
- 0, 12 – blend right eye
- 1, 13 – blend left eye
- 2, 14 – blend right cheek
- 3, 15 – blend left cheek
- 4, 16 – blend right forehead
- 5, 17 – blend left forehead
- 6, 18 – blend nose
- 7, 19 – blend middle forehead
- 11, 20 – blend all override
The blend all override blends the entire texture, not just individual parts, and can stack with individual blends.
Tattoos (FaceM1)
2 NAME UINT32 175367905 - 23004 MORPH_TEXTUREPARAM [tprm] - 0 tprm 2 NAME ECString mml_tTattooMask 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_tat_pmta_0t - 23005 MORPH_VECTOR4FPARAM [vprm] - 0 vprm 2 NAME ECString mml_vTattooParameters - 17 VECTOR4F_LIST [Vector4f] (5 items) 0 tattoo: R, G, B, A Vector4f 1.0, 0.0, 0.0, 0.0
The first line in mml_vTattooParameters controls the opacity of each individual channel in the texture set in mml_tTattooMask. There are more rows beneath the first, but they don’t do anything.
Facial hair (FaceM1)
2 NAME UINT32 175367905 - 23005 MORPH_VECTOR4FPARAM [vprm] - 0 vprm 2 NAME ECString mml_vFacialHairWeights - 17 VECTOR4F_LIST [Vector4f] (2 items) 0 eyebrow: bushy, regular, thick, thin Vector4f 0.0, 1.0, 0.0, 0.0 1 goatee, stubble, mustache, porkchops Vector4f 0.75, 1.0, 0.75, 0.75
Makeup opacity (FaceM1)
2 NAME UINT32 175367905 - 23005 MORPH_VECTOR4FPARAM [vprm] - 0 vprm 2 NAME ECString mml_vTintMaskColours - 17 VECTOR4F_LIST [Vector4f] (10 items) 0 lipstick, eyeshadow, blush, -- Vector4f 1.0, 1.0, 1.0, 0.0
Scalp stubble (HairM1)
HairM1 corresponds to node 3604562093.
2 NAME UINT32 3604562093 - 23005 MORPH_VECTOR4FPARAM [vprm] - 0 vprm 2 NAME ECString g_vFacialHairWeights - 17 VECTOR4F_LIST [Vector4f] (2 items) 0 Vector4f 0.0, 0.0, 0.0, 0.0 1 default, crew cut, receding, balding Vector4f 1.0, 1.0, 1.0, 0.0
Scalp stubble is the second line under HairM1 g_vFacialHairWeights (as opposed to FaceM1 g_vFacialHairWeights). The first option is the default scalp tint under most haircuts (the ones without funky hairlines anyway) which is primarily an all-over solid tint.
Eye textures (EyesM1)
Eye textures, if any, are under 3208920268. This is usually near the top around the early teens.
2 NAME UINT32 3208920268 - 23004 MORPH_TEXTUREPARAM [tprm] - 0 tprm 2 NAME ECString mml_tDiffuse 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\heads\textures\mt_eye_infa_0d - 1 tprm 2 NAME ECString mml_vTintMask 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\textures\default_black
If you don’t want the eye tint to apply on top of the eye texture you can add mml_tTintMask with a path to something like art\characters\playercharacter\shared\textures\default_black.
Eyelash textures (LashesM1)
Eyelash textures are under 1306876726.
2 NAME UINT32 1306876726 - 23004 MORPH_TEXTUREPARAM [tprm] - 0 tprm 2 NAME ECString mml_tDiffuse 23003 MORPH_TEXTURE_NAME ECString art\characters\playercharacter\shared\textures\mt_ulm_basa
Texture defaults
The texture parameters in the headmorph override the default texture parameters, which are listed in the material objects (.mao) for each base head. These files are in globalmao-core.rim and have filenames like mt_bas_hf_facem1.mao, mt_bas_hm_eyesm1.mao, mt_bas_ef_scalpm1.mao, etc. Unlike the DAO-style XML material objects, these can be opened in pyGFF:
Theoretically, any texture parameter in these material objects can be added to a headmorph.
So there are two ways to add modded textures to a .mor. You can add and change texture parameters in the .mor directly, or you can follow the process in this thread to duplicate the base head and specify new default textures.
So say, for example, you wanted to edit a morph to use Ellise’s unique face textures, which use the latter method. What you would do is open up Ellise’s file to get the name of the new base head and copy that over to morph_parts for the morph you wish to edit. Delete all the texture entries from under
1753679605 (FaceM1), 1306876726 (LashesM1), and 3208920268 (EyesM1), so they won’t override the modded textures. Also delete all the vector parameters under FaceM1 since eyebrows, stubble, tattoos, etc. are already included in the textures. It’s a simple enough process.
I’ve found that sometimes eye textures can be resistant to this method, mysteriously somehow reverting to default textures even when all the other modded textures in the new .mao are working perfectly fine. Adding the modded textures under EyesM1 in the headmorph while letting the other textures load from the modded base head should fix it up.