Skip to content

Battle voices and banter

Designer · 12 min read · No code · Last tested: 2026-10-02

Party members speak. They shout their arts by name, call out when a fight starts, name the ally they are reviving, groan when hit, cheer a win and chat while the party travels. That is Xenoblade's pattern. With AI companions it is also a gameplay signal: you hear "Wild Down!" and know a Topple is coming without looking.

Everything here is set in the editor. The lines are rows in a Data Table, the pacing is a second Data Table, and the global feel is one Data Asset. There is no C++ per line, per character or per category.

What you can change, no code

Status, 2026-10-03

All seven characters are voiced (470 lines, two takes each, with lip-sync keys and an expression per line) and the gameplay triggers are wired: art calls, battle start, hits, downed and revive, victory, Talent ready, the Party Gauge, level up, switching leader and talking to an ally. Faces lip-sync and change expression with each line.

How it fits together

Piece What it is Where it lives
A character's lines Data Table, row type Xeno Core Voice Line Row One per character, e.g. Audio/Voice/Kael/DT_XenoCore_Voice_Kael, chosen in the member definition's Voice Table
Pacing Data Table, row type Xeno Core Voice Rule Row Audio/Voice/DT_XenoCore_VoiceRules
Global feel Data Asset Xeno Core Battle Voice Config Audio/Voice/DA_XenoCore_BattleVoiceConfig, chosen in Project Settings > XenoCore Content > Voice
Volume Sound class SC_XenoCore_Dialogue Follows Lyra's Dialogue volume slider, mixed through Lyra's VoiceSubmix
Left / right Attenuation ATT_XenoCore_Voice The voice is attached to the speaker's head and pans by where they stand. It stays at full volume out to 25 m, so a fight never gets quieter
The player UXenoCoreBattleVoiceSubsystem Asked to Speak; decides whether the line is heard

Writing a character's lines

A row is one thing a character can say:

Field Meaning
Category When it is said, a XenoCore.Voice.* tag (table below)
Art Only for this art. Leave empty for any art
Addressee Only when speaking to this ally (revives, exchanges). Leave empty for anyone
Reply After this line, the Addressee answers with a line of this category, spoken back to this character. This is how a two-person exchange is written, with no graph
Takes The recordings, each with its lip-sync keys. One is picked each time, and none repeats until all have played
Expression, Expression Weight The face held while the line plays: a face curve such as angry, happy, sad
Subtitle What is said, shown only if subtitles are on
Direction How it was recorded, e.g. [shouts]. Reference only

Which row plays. Rows with the requested category are the candidates. A row naming an Art or an Addressee only matches that art or ally, and the most specific match wins. So write one generic Art row as a fallback, then one row per art the character can use.

Arts are shared, lines are not

Light Heal is on five characters, so its call-out cannot live on the art. Each character's table has its own Art = Light Heal row in their own voice. When a character learns a new art, add a row to their table.

Categories

Category Said when
BattleStart.Leader.Weak / Even / Strong, BattleStart.Follower.* Drawing on an enemy, by role and the enemy's strength
Art Casting an art (set Art)
TalentReady The Talent Gauge fills
Effort.Attack, Effort.Jump, Effort.Block A swing, a jump, a blocked hit. Overlap other lines
Hurt.Light, Hurt.Heavy Hit; toppled or dazed. Overlaps other lines
LowHP, Downed Own HP low; downed
Revive.Given (set Addressee), Revive.Received Reviving an ally; being revived
Aid.Given (optionally set Addressee), Aid.Received Healing or buffing an ally; being healed or buffed
Critical, Miss, Evade Own crit, own miss, a dodge
Gauge.Bar, Gauge.Full The Party Gauge fills a bar; fills completely
Enemy.Low, Enemy.Last, Enemy.Reinforcement Enemy nearly beaten; one left; another joins
Reaction.Break / Topple / Daze A reaction lands on the target. Off in the shipped rules: the art call already says it
Victory.Clean, Victory.Close, Victory.Reply The win, and an ally's answer
LevelUp This character levelled
TakeControl The player switched to this character in battle
Field.Idle, Field.Travel, Field.Scenery, Field.EnemySighted, Field.WaitUp Out of battle: standing about, jogging, sights, an enemy spotted, falling behind
Field.Talk The player talked to this ally out of battle. Always answers; movement is not locked
Field.Exchange → Field.Reply Two-person banter (set Addressee and Reply)

Talking to an ally

Out of battle, stop beside a companion and the prompt reads A - Talk. They answer with a line from their Field.Talk rows, voiced and shown in the dialogue box over their head. Nothing is held: you keep walking, the camera stays yours, and the box closes itself.

Setting Where
The prompt's word, or empty to make a character untalkable Talk Verb on the party member's Blueprint (Class Defaults › XenoCore › Interaction)
How close to stand Interact Range, same category (110 cm, the revive range), the same field an NPC has
Only when still Talk Max Leader Speed, same category (50 cm/s): the party walks bunched, so Talk is offered only once you stop
What they say Field.Talk rows in their voice table; the box shows the row's Subtitle
Which categories also show the box Show In Dialogue Box on the config (shipped: Field.Talk)
How long the box lingers after the voice Dialogue Box Linger on the config

In battle the prompt is not offered; a downed ally offers Revive instead.

The face

While a line plays, the speaker's face lip-syncs to it and shows the row's Expression. The mouth follows the take's keys (baked from the recording, so nothing is guessed at runtime) and closes the moment the voice stops, including when a more important line cuts in.

Setting Where
Which expression and how strongly Expression and Expression Weight on the voice row (a VRM name: happy, angry, sad, relaxed, surprised)
Lip sync on or off; mouth size; snappiness Lip Sync, Lip Sync Weight Scale and Lip Sync Blend Speed on the character's face anim Blueprint (ABP_XenoCore_VRoidRetarget_*, parent XenoCoreFaceAnimInstance)

A recording with no keys falls back to a generic mouth flap.

What triggers each line

Category Triggered by
Art Casting an art, by the player or a companion
Battle start The first body to draw its weapon in a fight; strength compares the nearest enemy's level to the speaker's (Strong / Weak Level Gap on the config)
Talent ready The Talent Gauge filling
Effort A swing, a jump, a blocked hit
Hurt Any damaging hit (light); being toppled or dazed (heavy)
Low HP, Enemy low A hit crossing Low Health Fraction (self) or Enemy Low Health Fraction (the enemy)
Critical, Miss, Evade The hit roll
Downed Going down. It also makes the next win Close
Revive The reviver names the ally, then the ally answers
Party Gauge A bar filling; the gauge full. The leader speaks
Enemy last One engaged enemy left. The leader speaks
Victory The win, after Victory Line Delay. One speaker per win, taking turns. Close if anyone was downed, or the leader is below Close Victory Health Fraction
Level up Once per level-up burst
Take control Switching leader
Field idle, scenery, travel Every Field Banter Interval, out of battle, never during a conversation: travel while the leader moves, otherwise idle or (Field Scenery Chance) scenery
Field exchange and reply On a banter tick, Field Exchange Chance of the time: one character opens to a named ally and that ally answers. Write one exchange per ordered pair (X to Y), with Y's reply addressed back to X
Field enemy sighted An enemy, not yet fighting, within Enemy Sighted Radius of the leader. Once per enemy
Field wait up A companion further than Wait Up Distance behind a moving leader
Aid given A heal or buff cast says this instead of the art's name Aid Given Chance of the time
Aid received One ally a heal or buff reached thanks the caster, once the cast's line has finished
Enemy reinforcement Another enemy joins a fight already Reinforcement After Seconds old
Reaction The leader calls a Break, Topple or Daze landing on an enemy (off in the shipped rules)

Pacing: the rules table

Seven voices could easily talk over each other; XC3 was criticised for exactly that. Every voice therefore follows these rules, all set in DT_XenoCore_VoiceRules:

  • One line at a time. A request at or below the priority of the line playing is dropped, not queued; a higher one cuts in. Rows with Overlaps (grunts, hurt) are the exception.
  • A gap (Gap Seconds on the config, 0.8 s) follows every line. It holds back lines of equal or lower priority than the one that ended; a more urgent line (Downed, a revive) goes straight through.
  • Chance applies to the player-controlled character; AI Chance to companions. With Scale With Party Size on, the AI chance is multiplied by Reference Party Size / active members, so a party of seven says less per head than a party of three.
  • Speaker Cooldown stops one character repeating a category; Category Cooldown stops anyone.
  • A rule covers its children. The XenoCore.Voice.Field row paces every field category, so a new category inherits sensible pacing until it gets its own row. A category with no rule anywhere is never said, and the log names it.
Shipped priority Category
100 Downed
90 Revive
80 Victory
70 Talent ready
60 Art
55 Battle start, take control
45 Reactions (off)
40 Low HP
35 Party Gauge
30 Critical
25 Enemy status
20 Aid
15 Miss, evade
10 Level up
5 Field banter

Adding a category of your own

A boss taunt or a quest beat needs no C++:

  1. Add the tag under XenoCore.Voice, e.g. XenoCore.Voice.Boss.PhaseTwo: open Project Settings › Project › GameplayTags, click Add New Gameplay Tag, and save it to a tag file of your own project rather than XenoCore's (a template update replaces XenoCore's).
  2. Optionally add a rules row. Without one it uses XenoCore.Voice's.
  3. Add rows with that category to the characters who should say it.
  4. Call Speak from the Blueprint where it happens: the boss's phase change, a trigger volume, a quest step.

Speak (Xeno Core Battle Voice Subsystem) takes a Speaker, a Category and, optionally, an Art and an Addressee. It returns whether a line started. Call it as often as you like; the rules decide.

Recording lines

The shipped lines were generated with a text-to-speech service, then trimmed, levelled and given lip-sync keys. To add your own recording:

  1. Level it like the shipped takes: about -16 dB average loudness, peaks under -1 dBFS.
  2. Drag the WAV into the Content Browser, next to the character's voice table. Import it as mono: a stereo file cannot pan with the speaker.
  3. Open the new sound wave and set its Sound Class to SC_XenoCore_Dialogue, so it follows the player's Dialogue volume.
  4. In the character's voice table, add it to a row's Takes.

A hand-imported take has no lip-sync keys, so the mouth uses the generic flap described in The face.

Test it

Start the gym, then type XenoCore.Voice.Speak Kael <Category> in the console with your row's category. Log LogXenoVoice Verbose explains a line that did not play.

Events

XenoCore.Voice.Message.Spoke is sent the moment a line starts. Payload XenoCoreVoiceSpokeMessage: Speaker, Category, Take (with its lip-sync keys), Expression, Expression Weight, Subtitle, Duration. Use it for subtitles or a speaking indicator. See Events you can listen to.

Debugging

Command Does
XenoCore.Voice.Describe Prints the config, every rule and each active member's table
XenoCore.Voice.Speak <Member> <Category> [Art] Asks a member for a line, exactly as gameplay does. The category may omit XenoCore.Voice.; e.g. XenoCore.Voice.Speak Kael Art DA_XenoCore_BackSlash
Log LogXenoVoice Verbose Logs why each request was or was not said (cooldown, chance, gap, priority, no row)

Known gaps

  • Victory replies (an ally answering the victory line) have a category but no lines.