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.