About this mod
Facial expression framework to extends the facial expression system to more facial expressions
Supports console commands and papyrus scripts similar to MFG
- Requirements
- Permissions and credits
- Changelogs
- Donations
This mod is a framework that only extends facial expressions
so doesn't include all the extra facial expression morph files needed for it
but for example file that modders can refer to, support some extra facial expressions for vanilla race's
(sorry, i can't make the facial expression of vanilla race well)
also support extra facial expression tri file for the elin race
available for both player and NPC
Not a replacement for MFG mods!!
The mfg mods are for bug fix and better use of vanilla's facial expression function
This mod extends to use a new kind of facial expression that is not in vanilla's facial expression
So can be used with mfg mods and is not a replacement for mfg
How to set facial expression morph with console commands?
mfee <category number> <morph number> <value 0~100>
e.g.
mfee 0(mood) 5(MoodFlabbergasted) 80
mfee 7(tongue) 0(tongueOut) 40
mfee 0 3 100
to reset
mfee r
mfee reset
to reset category
mfee 2(ears) r
mfee 0 r
mfee 4 reset
to help print
mfee
- Categories will be printed
mfee 0
- morphs of mood category will be printed
Can I use it with MFG console commands/papyrus scripts?
- sure, it's similar to mfg, but it's a separate system from mfg
so you can use it together
How to use papyrus scripts?
please refer to MuFacialExpressionExtended.psc file in scripts/source folder
you can use it like this
MuFacialExpressionExtended.SetExpressionByNumber(Game.GetPlayer(), 0, 4, 80); set 80% of MoodTemptation in the mood category
for more info, please look at the for modder sectionCan I add another tri file for facial expressions?
sure, please refer to for modder section
Support morph name / categories
The categories support list :
0. Mood
1. Misc
2. Ears
3. Tail
4. Face
5. Eyes
6. Brows
7. Mouth
8. Tongue
The facial morph name list of Mood category :
0. MoodAhegao
1. MoodAhegao2
2. MoodSulky
3. MoodLaugh
4. MoodFlabbergasted
5. MoodTemptation
The facial morph name list of Misc category :
The facial morph name list of Ears category :
0. EarsFront
1. EarsBack
2. EarsIn
3. EarsOut
The facial morph name list of Tail category :
0. TailUpTailDown
1. TailLeftTailRight
The facial morph name list of Face category :
0. FaceInflateCheeks
The facial morph name list of Eyes category :
0. EyesIn
1. EyesOut
2. EyesSurprise
3. EyesShock
The facial morph name list of Brows category :
The facial morph name list of Mouth category :
0. MouthLaugh
1. MouthTemptation
2. MouthSmacklips
3. MouthFlabbergasted
4. MouthCry
5. MouthCat
6. MouthClench
7. MouthClenchLip
8. MouthPucker
9. MouthUpperUp
10. MouthBow
The facial morph name list of Tongue category :
0. TongueOut
1. TongueUp
2. TongueDown
3. TongueLeft
4. TongueRight
5. TongueTwistLeft
6. TongueTwistRight
If you want to add another morph name with fixed number, please feel free to suggest on the forum
FAQ
Set the facial expression but doesn't work
- if the morph match to the facial expression is not exist in the tri file then it will not work
Set the facial expression, but doesn't work but player does
- the NPC is using an independent base facial expression trip file if vertex count and vertex order in the mesh are the same, create an ini file to skse\plugins\MuFacialExpressionExtended folder to link it
Does this affect the save file?
- everything is not saved so if there's an facial expression that needs to be remained you must re-run the function after the game loaded
Also you can install and delete freely
Installation
1. install requirements
2. install the main file
- if you are playing the elin race then install the option file
Requirements
SKSE64 or SKSEVR
Address Library for SKSE Plugins (for SSE/AE)
VR Address Library for SKSEVR (for VR)
Compatibility
Support SE v1.5.97
Support AE all versions (if you have a problem with v1.6.1130 ~ v1.6.1170, install the latest Address library)
not verified for VR v1.4.15
For Modder
To link morph tri file and morph name in MFEE
Make morph name in MFEE and morph name in tri file the same
e.g.
To add a new morph for MouthLaugh facial expressions to the tri file
create morph with the same morph name (MouthLaugh) and add it to the tri file
letter case is not important
it recognize them all in lowercase
To add morph file (tri) on MFEE
1. Create ini file with any name in skse\plugins\MuFacialExpressionExtended folder
2. fill out the following form
ExtensionFile = <Headpart's facial expression tri file path>, <Extra facial expression tri file>, <Extra facial expression tri file2>, <Extra facial expression tri file3>...
<Headpart's facial expression tri file path> is .tri file of facial expressions linked to head part
<Extra facial expression tri file> is the facial expression tri file you want to add
data\meshes is the root location
so you have to fill out paths without data\meshes
also you can add multiple files by adding , or by adding multiple lines
e.g.
to add new morph file to vanilla race head mesh
vanilla race's facial expression tri file of head mesh is data\meshes\actors\character\character assets\femalehead.tri
so fill out actors\character\character assets\femalehead.tri on <Headpart's facial expression tri file path>
new facial expression tri file is data\meshes\newmorphfile\abc.tri
so fill out newmorphfile\abc.tri on <Extra facial expression tri file>
then it's fill out like this
ExtensionFile = actors\character\character assets\femalehead.tri, newmorphfile\abc.tri
If you want to add and use anothermorphfile\dec.tri file and newmorphfile\abc.tri files together to the head mesh
ExtensionFile = actors\character\character assets\femalehead.tri, newmorphfile\abc.tri, anothermorphfile\dec.tri
or
ExtensionFile = actors\character\character assets\femalehead.tri, newmorphfile\abc.tri
ExtensionFile = actors\character\character assets\femalehead.tri, anothermorphfile\dec.tri
or
a.ini file
ExtensionFile = actors\character\character assets\femalehead.tri, newmorphfile\abc.tri
b.ini file
ExtensionFile = actors\character\character assets\femalehead.tri, anothermorphfile\dec.tri
To add new morph name / new category
1. create ini file with any name in skse\plugins\MuFacialExpressionExtended\Morphs folder
2. fill out following form
<category name>|<morph name>
<category name> is the category name you want to add morph or the category you want to create
<morph name> is the morph name you want to add to the category
also separate the two with "|"
e.g.
Mood|ABCMood
Mood|VerySad
NewFacialCategory|NewCategoryMorph
letter case is not important
it recognize them all in lowercase
Description of the papyrus script functions
int function GetVersion() global native
returns the API version of MFEE.dllcurrently the latest version is 3
bool function RegisterNewMorphData(string a_morphBasePath, string a_morphPath) global native
add a new facial expression tri file to the head partit's same as ini files in skse\plugins\MuFacialExpressionExtended folder
so data\meshes is root
returns false if fails and returns true if successful
bool function RegisterNewMorphNameOnCategory(string a_morphCategory, string a_morphName) global native
add new morph name on the category or add a new category name with morph nameit's same as ini files in skse\plugins\MuFacialExpressionExtended\morphs folder
returns false if fails and returns true if successful
string[] function GetExpressionCategories() global native
returns string array for categories nameint function GetExpressionCategoriesSize() global native
returns categories countstring function GetExpressionCategoryByNumber(int a_categoryNumber) global native
returns category name that matches numberstring function GetExpressionCategoryByMorphName(string a_morphName) global native
returns category name that morph name existsint function GetExpressionCategoryNumber(string a_morphCategory) global native
returns category number that matches category namebool function IsValidExpressionCategory(string a_morphCategory) global native
returns false if invalid category and returns true if valid categorystring[] function GetExpressionMorphNames(string a_morphCategory) global native
returns string array for morph names in the category nameint function GetExpressionMorphNamesSize(string a_morphCategory) global native
returns morph name count in the category namestring[] function GetExpressionMorphNamesByNumber(int a_categoryNumber) global native
returns string array for morph names in the category numberstring function GetExpressionMorphNameByNumber(string a_morphCategory, int a_morphNumber) global native
returns morph name that matches morph number in the category namestring function GetExpressionMorphNameByNumbers(int a_categoryNumber, int a_morphNumber) global native
returns morph name that matches morph number in the category numberint function GetExpressionMorphNameNumber(string a_morphName) global native
returns number that matches the morph namebool function IsValidExpressionMorphName(string a_morphName) global native
returns false if invalid morph name and true if valid morph nameint function GetExpressionValueByName(actor a_actor, string a_morphName) global native
returns value of the morph nameint function GetExpressionValueByNumber(actor a_actor, int a_categoryNumber, int a_morphNumber) global native
returns value of the morph number in the categoryfunction SetExpressionByName(actor a_actor, string a_morphName, int a_value) global native
set morph value of the morph namefunction SetExpressionByCategory(actor a_actor, string a_morphCategory, int a_morphNumber, int a_value) global native
set morph value of the morph number in the category namefunction SetExpressionByNumber(actor a_actor, int a_categoryNumber, int a_morphNumber, int a_value) global native
set morph value of the morph number in the category numberfunction RevertExpression(actor a_actor, string a_morphCategory = "") global native
revert/reset all morph value to 0 or revert/reset all morph value to 0 in the category namefunction UpdateExpression(actor a_actor) global native
instant update facial expressionsyou don't need to use it in general
this is just in case
function InitialMorphData(actor a_actor) global native
If the tri file of headpart is changed due to the replacement of the headpart or a new headpart is addedupdate the morph data so that mfee can work in the new headpart
All morph values are initialize after this so have to done again
To update tri file and config files in the real-time
1. open the console
2. enter "mfee debug reload"
DO NOT USE it often in gameplay
it's experimental and please use only when testing mod
To instant update the actor's facial morph by console
1. open the console
2. click the actor you want to update
3. enter "mfee debug update"
usually you don't need to use it
this is just in case
To use API for skse plugin modders
Download "Modder Resource" in misc section
and include the Interface.h file in your source code
commonlib-ng is used as follows
#include "interface.h"
MFEE::InterfaceManager manager;
MFEE::IFacialExpressionExtended* mfee = manager.GetInterface(); //get interface from mfee.dll
if (!mfee) //check that the mfee interface is valid
return;
if (mfee->GetVersion() != 3) //check mfee interface version
return;
if (!mfee->IsValidExpressionCategory("mood")) //check that there is mood category, letter case doesn't matter
return;
std::vector<std::string> morphNames = mfee->GetExpressionMorphNames("mood"); //get morph names in mood category
std::vector<std::string> foundmorphName;
for (std::string morphName : morphNames)
{
if (morphName.contains("ahegao")) //find morph name that conatains "ahegao"
foundmorphName.push_back(morphName); //found MoodAhegao and MoodAhegao2
}
for (std::string morphName : foundmorphName)
{
mfee->SetExpressionByName(RE::PlayerCharacter::GetSingleton(), morphName, 50); //set MoodAhegao and MoodAhegao2 to 50
}
also you can rename interface.h file namefor Regular SKSE not commonlib, you should implement using the same message function of skse plugin's instead of InterfaceManager in Interface.h
for functions, refer to the papyrus section abovethe name and function are the same
Credit
CommonlibSSE-NG