Skip to content
/a/ FaceCue Performance Studio

Transcript Tags

The tags you can write into a transcript to tell the character how to feel, when to glance away, which stretch is spoken in another language, and how to read a number. The baker turns them into cues alongside the mouth movement.

Tags are the most powerful thing in the baker and the easiest to miss, because nothing in the window advertises them. They are just text you type into the script.

How Tags Work

A tag wraps the words it applies to, in the shape of an XML element:

This is a <Proud>great place to live</Proud>!

The baker reads the tag, notes which words it covered and when those words are spoken, and writes a cue for it on the same timeline as the mouth movement. Then it removes the tag from the text before recognition, so the recognizer only ever sees This is a great place to live. The tags cannot corrupt the lip sync, because the recognizer never sees them.

There are four families:

Family Looks like What it does
Emotion <Proud>…</Proud> Puts an emotion on the character for those words
Cognitive <Thinking>…</Thinking> Marks a moment the character's attention goes inward
Language <Korean>…</Korean> Marks a stretch spoken in another language
Say As <SayAs as="year">…</SayAs> Says how to read a number

Tag names are matched without regard to case, so <proud> and <Proud> are the same tag.

One Transcript Works for Both Baking and Synthesis

Speech synthesis strips the tags too, so you can hand the same tagged script to Generate Audio and to the bake without keeping two copies of it. Nothing gets read aloud.

The two paths differ in one deliberate way. A bake strips punctuation, because a recognizer lining words up against audio does not want it. Synthesis keeps it, because punctuation is how you tell a voice model where the phrasing goes. The words themselves stay identical either way, which is what lets one script serve both.

Synthesis removes the tags without acting on them, so an <Excited> tag shapes the face and not the voice.

A Typo Costs You the Tag, Not the Bake

Emotion is open vocabulary, so a misspelled emotion name is still a valid emotion tag, just one your character's Emotion Library has no entry for at play time. A tag you open and never close is closed for you at the end of the clip, so it still lands, covering more words than you meant. A closing tag with nothing open to match it is left in the text as ordinary words. In every case the bake completes and the mouth movement is unaffected. Check the emotion row in the Cue Clip Composer if a tag does not seem to have landed where you expected.

Emotion Tags

The baker accepts any name. It has no list of valid emotions and does not check what you wrote against one. It stores the name verbatim, and your character's Emotion Library decides what it looks like at play time.

That separation is useful. A writer can tag a line before anyone has built the expression behind it, and building it later brings every already-baked line to life with no re-bake.

What plays back, though, is whatever the Emotion Library holds, and FaceCue ships a fixed set, not an empty one. A tag naming something outside that set bakes cleanly and then has nothing to play.

<Proud>I built this myself</Proud>, and <Sad>nobody ever came to see it</Sad>.

The Vocabulary Is Fixed, the Look Is Not

FaceCue ships twenty-eight named emotions, each already tuned. That set is the vocabulary to write against today.

What you can change is how any of them looks on your character. An emotion is built from expressions with their own weights and timing, and all of that is yours to tune in the Face Rig Designer. Your Angry can be a different Angry from anyone else's.

What you cannot change yet is the set itself. Renaming one, or adding a twenty-ninth of your own, is not something the tool offers. Opening that up is on the roadmap. Until it lands, check the Emotion Library on your character for the names it has and tag against those.

Shaping a Tag

Four attributes shape how the emotion arrives and leaves. Each has a single-letter short form, because a densely tagged script gets unreadable fast.

Attribute Short Takes What it does
intensity i 0 to 1 How strongly the emotion plays
rampUp u seconds How long it takes to come in
rampDown d seconds How long it takes to fade out
rampSemantics rs plateau or envelope Where the ramps sit relative to the words

Anything you leave out is inherited from the character, so a bare <Proud> is the normal case and not a lazy one.

<Proud i=0.6 u=0.3 d=0.8>I built this myself</Proud>

Both spellings work everywhere, so <Proud intensity=0.6> and <Proud i=0.6> are identical.

Plateau and Envelope

This is the one that surprises people, so it is worth a picture.

When you tag a few words as <Proud>, there are two reasonable readings of what you meant, and they produce visibly different performances. The tag is in the same place in both.

Plateau Envelope the tagged words the tagged words
The same tag, read two ways. Plateau holds full strength across every tagged word and does its rising and falling outside them. Envelope fits the whole shape inside them.

Plateau treats the tagged words as the emotion at full. The ramps hang outside the brackets, so the character is already fully proud by the first tagged word and only starts letting go after the last one. Use it when the tag marks the part of the line that is the emotion.

Envelope treats the tagged words as containing the whole shape. Each ramp is inset, so the rise happens inside the first words and the fall inside the last ones, and full strength lands somewhere in the middle. Use it when the tag marks a stretch the emotion moves across.

Set it per tag with rampSemantics, or once for the whole project in the baker's settings pane, under Emotion Handling.

<Proud rs="envelope" u=0.4 d=0.6>slowly, this became mine</Proud>

Envelope Only Insets a Side You Wrote a Ramp For

A side whose ramp is inherited from the character stays plateau, because the inherited value is not known until play time. So asking for envelope and writing neither ramp bakes exactly what plateau would. The baker warns you when you do that, rather than leaving you to wonder.

Cognitive Tags

Cognitive tags mark the moments a character's attention leaves the person they are talking to. People do this constantly and almost never notice it, which is exactly why a character who never does it reads as vacant.

There are four, each with a short form:

Tag Short The moment it marks
<Thinking> <Think> Reaching for a word or an idea
<Awkwardness> <Awk> Discomfort, wanting to be looking anywhere else
<Agitation> <Agi> Agitation, the low end of being wound up
<Excitement> <Exc> Excitement, the high end
I think it was, <Think>what was it called</Think>, the blue one.

Unlike emotion, this list is closed. A name that is not one of these eight is read as an emotion instead, and no error is raised, so a mistyped <Thnking> silently becomes an emotion named Thnking.

Agitation and Excitement are the two ends of one axis, not two unrelated states, so tagging both across the same words is not meaningful.

Language Spans

Mark a stretch as spoken in another language by wrapping it in the language's name:

She smiled and said <Korean>반갑습니다</Korean>, then switched back.

Names are written the way you would say them in English: <English>, <Spanish>, <French>, <German>, <Japanese>, <Korean>, <Russian>, <Greek>, <Portuguese>, <Arabic>, <Hindi>, and many more. <Mandarin> is the tag for Chinese, and <Chinese> is accepted as a colloquial alias for it.

The problem this solves is real and easy to miss. A recognizer runs once over the whole clip with one language's model, so a stretch in another language matches almost nothing that model knows. The result is not wrong mouth movement, it is no mouth movement, which is much harder to spot in review than an error would be.

You do not have to write these by hand. Recognize Speech can listen for a change of language in a recording and write the span where it hears one, and what it writes is exactly this markup, so you can check and correct it like anything else in the transcript.

How much the bake does about it is yours to choose. Write a language tag and a Language Spans group appears in the baker's Recognizer section, with a Handling control offering three answers:

Handling What the bake does
Ignore Reads the whole clip with the selected recognizer. The tagged stretch is still recorded, but it may get little or no mouth movement.
Single Pass Reads the clip once with the multilingual decoder, so every language moves the mouth.
Per Language (Slower) Does that first to find where each language starts, then reads every stretch again with the recognizer built for it. The most accurate option.

That group appears only when something in front of you carries language spans, so a project that never uses them never sees it.

Japanese Needs Per Language

Japanese gets its written form from the per-language pass specifically. A generalist reading produces no kana and no mora for it, so a Japanese stretch baked any other way is missing something the runtime uses. If a clip mixes Japanese with anything, this is the setting.

Language spans are carried into the cue file either way, so the Cue Clip Composer shows you where they are even when the bake did not act on them.

Numbers and Say As

A recognizer hears words. It does not hear 1987, so a transcript that contains digits does not line up with audio that contains speech.

The baker handles this before recognition, by spelling numbers into words. 1987 becomes nineteen eighty seven, and the rest of the pipeline never knows the digits were there. It handles currency, decimals, ranges, ordinals and telephone-style digit strings, in every language it supports numbers for.

Where it cannot know, it guesses, and where the guess matters you can override it.

The <SayAs as="year">2010</SayAs> model cost <SayAs as="currency" code="USD">$40</SayAs>.

The as attribute takes:

as= Reads 2010 as
year twenty ten
digits two zero one zero
ordinal the ordinal form of the number
currency an amount, with code naming the currency
decimal a decimal number
range a span between two numbers

Anything else, and anything untagged that the baker reads as a plain number, is spelled as a cardinal: two thousand and ten.

The Year Case Is the One Worth Knowing

Four-digit numbers are ambiguous and game dialogue is full of them. A quantity of 2010 rounds and a year 2010 does not, and no amount of cleverness settles it from the digits alone. If a line has a year in it, tag it.

Year Reading Is English and German Only

Those two languages read years differently from ordinary numbers, so they have their own handling. Every other language spells a year the same way it spells the number, which is what a speaker of most of them would do anyway. Tagging a year outside English and German is harmless, it simply changes nothing.

Nesting, Overlap and Reserved Names

Tags do not have to nest tidily, and the rules differ per family because the underlying things behave differently.

Different Emotions Overlap Freely

Two different emotions can cover overlapping stretches and both are baked, because a character can be two things at once.

<Tired>I have been up since four, but <Proud>we finished it</Proud> anyway</Tired>.

Tired runs across the whole line and Proud runs across three words inside it. Both play.

The Same Emotion Twice Becomes One Stretch

Overlapping tags of the same name merge into their union instead of stacking, taking the parameters of the most recently opened one.

<Proud i=0.4>we built it <Proud i=0.9>ourselves</Proud> and shipped it</Proud>

That is one Proud across the whole span at intensity 0.9, not a quiet one with a loud one on top.

Spans May Cross Rather Than Nest

A closing tag binds to the nearest still-open tag of the same name, not to the innermost open tag, so this is legal and means what it looks like:

<Tired>I have been up <Proud>since four</Tired> and we finished it</Proud>.

Tired covers the first half, Proud covers the second, and they share the middle.

Language and Cognitive Spans Cannot Overlap

A word is spoken in one language, and attention is in one place at a time. Overlapping tags resolve to a clean partition, most recently opened winning the contested stretch.

<English>She said <Mandarin>你好</Mandarin> and left</English>

That bakes as English, then Mandarin, then English again, and not two languages at once.

An Unclosed Tag Is Closed for You

It closes at the end of the clip, so it still lands, covering more words than you probably meant.

Language and Cognitive Names Are Reserved

Because everything unrecognised falls through to emotion, the four cognitive names, their four short forms and every language name are checked first and are never read as emotions. You cannot have an emotion called Thinking, or one called French.