Kovati Docs

Vocabularies

Why a curve-name mismatch is made inexpressible rather than merely unlikely.

Documented in depthFaceForge0.2.2Open source

A face solver produces named floats. A character's face consumes named floats. If the names do not match, the curves import cleanly, evaluate to zero, and animate nothing — with no warning at all.

That failure is silent, plausible-looking, and expensive. So vocabularies are a type here, not a convention.

The three vocabularies

VocabularyWhat it is
MetaHumanBoardThe 81 MetaHuman face-board control curves
ARKit52Apple's 52 ARKit blendshapes — what most authored, CC5, Reallusion, Daz and Ready Player Me heads speak
MetaHumanRawThe raw control values underneath the board

Every curve set is tagged with its vocabulary, so a mismatch is inexpressible rather than merely likely.

Only 81 names are MetaHuman. If you are writing anything that moves face curves around, carry the vocabulary with them. A bare array of named floats is not enough information to use safely, and treating it as though it were is exactly how a face animates nothing.

Two kinds of transform, and they are not interchangeable

UFaceCurveMappingA vocabulary converter
NatureLossy, tunableExact
Defined byData — weighted sumsCode
Tuning knobYesNo
ExampleBoard → ARKitBoard → raw, via the engine's own conversion

The distinction matters when something looks wrong. A lossy mapping is meant to be adjusted — that is what the weights are for. An exact conversion is not, and adjusting one would only ever make it wrong.

Coverage, before you bake

DescribeFaceCoverage reports four things, and each one is a different problem:

FindingWhat it means
Curves the mapping drives with no matching morph targetThe character cannot do what the mapping is asking
Morph targets the mapping never touchesThe character can do more than the mapping uses
Source controls no rule readsThe solve is producing output that is discarded
Rule terms naming nonexistent controlsThe mapping has a typo or is out of date

Bake itself refuses outright when not one curve name it is about to write is registered on the target skeleton. That is the last line of defence against the silent-zero failure — it will not write an animation that could not possibly play.

An empty coverage report can mean "no problems" or "nothing was checked", and one field tells you which. The mesh half of the report only runs when the bank names a Target Face Mesh, which is optional and easy not to set. Without it the tool returns every list empty and bMeshWasChecked false.

Both banks in the scene these pages are written from are in exactly that state, so their coverage reports say nothing at all. Set the face mesh on a bank before trusting a clean report — it is the one setting whose entire purpose is to make this check possible.

Driving a MetaHuman

A solver emitting ARKit-52 natively needs no mapping for an ARKit-shaped head. A MetaHuman still needs a conversion — just a different one.

The MetaHuman face montage chain has four links, and all four must be right. A montage needs the correct slot and the correct component tag; getting the slot right while the tag is wrong produces a montage that plays and moves nothing.

If a face plays silently on the body mesh instead, that is the chain, not the solve.

A vocabulary decides which tools apply

The clearest everyday consequence is not about characters at all. Two clips of the same character, in the same bank, can offer different actions — because one was solved from audio into the board vocabulary and the other from video into another.

Correct in Sequencer needs MetaHumanBoard, because the sequence it builds is the MetaHuman face board. A clip solved from video is greyed out with that reason in its tooltip. See correction.

This is the vocabulary type earning its keep in the interface rather than only in the data: a mismatch that would otherwise produce an empty or nonsensical sequence is a disabled button with a sentence attached.

A practical consequence

Because the solve is vocabulary-tagged and character-agnostic, the same solve dresses different characters — the bake is where the character enters.

That is also why a face bank's language is the language of the speech bank it claims, rather than something stored separately: identity is (container, line id), and the container carries the language. See localisation.

On this page