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, where they laugh or hum or make a sound that isn't speech, 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 notes which words the tag covers and writes it as a cue on the same timeline as the mouth movement, timed to when those words are spoken. The tag itself is never read as part of the line. The line is read as just This is a great place to live, so the tag cannot disturb the lip sync.

There are seven 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
Laugh <Laugh/> Marks where the character laughs
Hum <Hum/> Marks a hum the mouth holds, such as mhm
Sound <Sound/> Marks a sound that isn't speech, which the mouth rests through
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 it plays no part in matching the words to the audio. Synthesis keeps it, because punctuation is how you tell a voice where the phrasing goes. The words themselves stay identical either way, which is what lets one script serve both.

Synthesis acts on two kinds of tag: a language span is spoken in its own language, and Say As decides how a number is read. Every other tag is removed without being acted on, 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 that names none of FaceCue's emotions, so nothing plays for it. 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. At play time FaceCue looks it up among the emotions it ships, and your character's rig map decides how it looks.

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 only what FaceCue's built-in emotions cover, 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, How It Looks on Your Character Is Not

FaceCue ships 28 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. How each of those expressions looks on your character 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, adding a 29th of your own, or changing which expressions an emotion is composed of and how, is not something the tool offers. Opening that up is on the roadmap. Until it lands, tag against the names the Face Rig Designer's Emotion channel lists.

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 & 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 comes from the character, rather than from the tag, stays plateau. So asking for envelope and writing neither ramp gives the same result as plateau, and the baker warns you when you do.

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 three, each with a short form:

Tag Short The moment it marks
<Thinking> <Think>, <Th> Concentrating, or reaching for a word or an idea
<Agitation> <Agi> Wound up the unpleasant way: anxious, afraid, angry
<Excitement> <Exc> Wound up the pleasant way: eager, delighted
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 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 thing, not two unrelated states, so tagging both across the same words is not meaningful. Most of the time you will not need either, because every emotion already carries its own share of each. The tags are for the moments where the words say it and the face does not.

What these tags set, and what reads it, is on Mental State.

A Moment or a Phrase

A cognitive tag can mark a single moment instead of a stretch of words. Write it on its own, closed with a slash, where the moment falls:

I've been applying to <Think/> probably two jobs a day.
I've been applying to <Thinking>probably two jobs a day</Thinking>.

Wrapped around words, the tag marks the whole phrase, and what the character does in response lasts as long as the phrase. On its own, it marks the moment, and the character decides how long the response lasts. For Thinking that response is a look away: short for a marked moment, as long as the phrase for a marked phrase.

A tag that opens and is never closed is read as a moment where it opens, and the baker warns you about it, so a forgotten closing tag never stretches the state across the rest of the line.

Laugh Tags

A laugh has no words in it, so a recognizer hears it as little more than silence, and the words either side of it can drift into the gap. A laugh tag marks where the laugh sits. The baker keeps it in its own stretch of the line, plays it on the mouth as laughter, and leaves the words around it where they were said.

<Laugh>haha</Laugh> You did not.
Oh, <Chuckle>hehe</Chuckle> sure.
That's the plan? <Laugh/> No.

Wrap the laugh in a laugh tag, spelled however you want it to read in the game, and the whole of it plays as one laugh. Nothing inside the tag is said as a word, so <Laugh>bwahaha</Laugh> and <Laugh>*snort*</Laugh> work as well as haha. <Chuckle> is the smaller laugh, and <Ckl> is its short form. A bare <Laugh/> marks a laugh without writing one out.

A laugh plays where it is heard in the line, and stops where the line goes quiet. A laugh tag reads the same in every language, which makes it the clearest way to mark a laugh.

Don't Mark Words as a Laugh

Everything inside a laugh tag plays as laughter and is never said, so real words wrapped in one are lost. That holds even when the character is laughing through them. For words said while laughing, tag them with an emotion such as <Amused> instead: the mouth still says the words, and the face carries the laugh.

A Laugh Keeps Its Own Rhythm

The baker reads the rhythm of each laugh from the recording. Every burst of the laugh opens the mouth, and the breath between bursts lets it ease off without closing, so a slow, rolling laugh and a quick giggle each move the way they sound. A laugh too soft to make out against the speech around it takes an even beat instead, set by Fallback Laugh Pace in the baker's settings pane under Non-Speech Handling.

Laughs Written as Words

Transcripts often spell a laugh out instead: haha, jajaja, 哈哈. The baker can read those as laughs too, in the spellings each language uses for them, and play them as laughter rather than saying them. A single ha stays a word, since it is as often a reply as a laugh.

Laugh Detection decides which, in the baker's settings pane under Non-Speech Handling. Tags & Transcript reads the tags and the spelled-out laughs. Tags reads only the tags, for transcripts that spell out laugh sounds you want said as words.

The Face Laughs Too

A laugh is more than the mouth. For each laugh, the baker writes an emotion cue into the line's emotion file, the same <clip name>_emotions.json an emotion tag writes to, so the rest of the face takes part. It is an ordinary emotion cue, a little softer over a chuckle than over a full laugh. It stays on the face for a while after the laugh ends, and a longer laugh lingers longer.

How long it lingers is the one thing worth choosing per laugh, because it depends on what the laugh means. Write it on the tag with linger, from 1 to 6:

Well, <Laugh linger=2>heh</Laugh> that went well.
<Laugh linger=6>hahaha</Laugh> We actually did it.
linger= Reads best for
1 to 2 A short, dry, sarcastic or sardonic laugh, gone as soon as it is over
3 to 4 Most laughs. The middle ground that fits nearly anything
5 to 6 A long, warm, happy laugh whose good mood carries on through the rest of the line

A tag without linger uses the Laugh Linger setting, so set that to suit the project and write linger only on the laughs that need to read differently. A laugh near the end of a line can leave its emotion on the face after the speech has ended. The Cue Clip Composer shows it running on past the line, where you can still adjust it.

Choosing the Emotion

Not every laugh is a happy one. A sardonic laugh reads truer as Contemptuous or Bitter, a nervous one as Nervous, and some laughs are better on the mouth alone. Write emotion on the tag to choose for that one laugh:

Well, <Laugh linger=2 emotion=Contemptuous>heh</Laugh> that went well.
<Ckl emotion=none>hm</Ckl> Sure.

emotion takes any emotion name, the same way an emotion tag does, or none for no emotion at all. It plays at the laugh's usual strength and lingers as the tag's linger says. A tag's choice holds even when Laugh Emotion is turned off, so a project can leave laughs on the mouth alone and still give a few of them a face.

Which emotion plays when a tag does not say, how strongly, and whether one plays at all are set in the baker's settings pane, under Non-Speech Handling.

Hum Tags

A hum such as mhm or mmm is a held sound, not a word. Read by its letters, each one comes out as the letter's name, and the mouth says something nobody said. A hum tag marks where the hum sits. The baker keeps it in its own stretch of the line and holds the sound for as long as it lasts, with the lips shut for a closed hum, and the words around it stay where they were said.

<Hum>mm-hm</Hum> I'll be there.
Right. <Hum/> Go on.

Wrap the hum in a hum tag, spelled however you want it to read, and it plays as the hum it spells. A tag around a spelling that says no hum plays a closed one, and a bare <Hum/> marks a closed hum without writing one out.

Hums Written as Words

Transcripts usually write hums out: mhm, hmm, М-м-м, shhh. The baker can read those as hums too, in the spellings each language uses for them, including the backchannels a listener answers with, such as mm-hm, Russian угу, Japanese うん and Korean 음. A hum that opens the mouth, like uh-huh, stays a word and is read as it is spelled.

Hum Detection decides which, in the baker's settings pane under Non-Speech Handling. Tags & Transcript reads the tags and the written hums. Tags reads only the tags, and a written hum is then read as its letters.

A hum plays the way it is written, so one spoken more openly than its spelling, a hmm that drifts toward huh, still plays closed.

Sound Tags

Some sounds in a recording are not speech at all: a sigh, a cough, a breath. A recognizer looks for words there, and the words nearby drift into the gap. A sound tag marks where the sound sits. The baker keeps it in its own stretch of the line and lets the mouth rest through it, so the words around it keep their places.

<Sound/> Fine. I'll go.
I told you, <Sound>coughs</Sound> I'm fine.

Whatever a sound tag wraps is never said, and a bare <Sound/> marks a sound without describing it. A laugh or a hum plays on the mouth, so give those their own tags. A sound tag is for everything the mouth stays at rest through.

Speech Synthesis Reads What a Sound Tag Wraps

Speech synthesis has no sound to make for a sound tag, so it reads whatever the tag wraps as words, and a voice reading <Sound>coughs</Sound> says coughs. There are two ways round it. Write a bare <Sound/> where you want the sound and nothing else. Or, if the script already writes its sounds as stage directions, such as (coughs), leave the script as it is and turn that bracket on under Stage Directions: both Remove and Sound Tag take the direction out of the line the voice is made from, so the voice never reads it either way.

A Word the Bake Can't Read

A word with nothing in it the bake can read as speech, such as Korean ㄷㄷ, plays nothing on the mouth, and the baker names it in a warning so it does not pass unnoticed. Write it the way it is said, or mark it with a sound tag.

Stage Directions

Scripts often write directions in brackets: [laughs], (sighs), *coughs*. By default the baker reads them like the rest of the line, as words the actor never said, which pulls the lip sync away from the audio. Three settings under Non-Speech Handling, one for each kind of bracket, decide what happens instead:

Setting Text it covers
[…] Square Brackets [laughs]
(…) Round Brackets (sighs)
*…* Asterisks *coughs*

Each one has three choices:

Choice What happens
Read as Words Read like the rest of the line. The default
Remove Taken out, brackets and all, before the line is read
Sound Tag Read as a tag: a laugh direction as a laugh tag, anything else as a sound tag
[laughs] You did not.           a laugh, played on the mouth
I told you (coughs) I'm fine.   a sound, the mouth at rest

Sound Tag knows a laugh direction by its first word, in the words each language uses for one: laughs and chuckles, se ríe, rires, смеётся, 笑 and their like. Choose it for directions that are sounds. Choose Remove for directions that describe a manner or say who is spoken to, such as [whispering] or (to Judy). Those have no sound of their own, and a sound marked there takes a moment of audio from the words beside it.

The settings are off by default because brackets also hold real dialogue: an aside in parentheses, or a choice label in a game script. A bracket inside a laugh, hum or sound tag is part of what that tag wraps. In speech synthesis, Remove and Sound Tag both take the direction out, so the voice never reads it.

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 listening for one language hears almost nothing it knows in a stretch of another. The result is a mouth that barely moves over that stretch, which is much harder to spot in review than a wrong shape 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) Reads every stretch with the recognizer built for its own language. 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 full reading only from the per-language pass. Baked any other way, a Japanese stretch loses detail the performance relies on. 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 & 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.

So the baker reads numbers the way they are spoken. 42 becomes forty two. It handles currency, decimals, ranges, ordinals and telephone-style digit strings, in every language it supports numbers for, and in English a decade too, so the '80s is read as the eighties.

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 & 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

Overlapping tags of one emotion become a single cue only when they ask for exactly the same thing: the same intensity, the same ramps, the same ramp style. Tags that differ in any of those are both kept, and the line plays them as two copies of the emotion.

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

That is a quiet Proud across the whole span with a louder one over ourselves, which plays as a lift in the middle and a settle back to the quieter level. Write the two tags with nothing to tell them apart and they merge into one stretch covering the words of both. Timing & Blending has the full picture, with diagrams.

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.

Two tags of the same name need an id to cross, since without one a closing tag goes with the nearest opening tag that has none:

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

The quiet Proud ends on ourselves and the louder one carries the rest. An id is yours to name and works on every kind of tag. The baker says so if a closing tag names an id no open tag is using, or if two open tags of one name are given the same one.

Language & 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 & Cognitive Names Are Reserved

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