Skip to content

Animation

All · 15 min read

What the player sees: characters walk and run with smooth blending, turn their upper body toward a locked enemy while their legs keep running, switch to a sword stance when a battle starts, fidget when left standing, flinch without dropping their swing, and (on VRoid characters) blink, pull faces and turn their heads toward whoever they are looking at.

Every party character shares one host Animation Blueprint, Characters/Player/ABP_XenoCore_Base, which holds the state machine (Idle, Move, the jump states). Which clips each state plays come from a linked animation layer: a small Animation Blueprint chosen by what the character holds and by its masculine or feminine style. The host is shared and never edited per character; a new weapon or stance is a new layer child that only swaps clips, set in its Asset Override editor with no graph editing.

What you can change

How it fits together

Piece Class / sample asset Job
Anim instance (C++ parent of every XenoCore Animation Blueprint) XenoCoreAnimInstance Works out ground speed, direction, stride scale, battle stance, target twist, head turn and idle breaks, so no Blueprint graph has to
Host ABP Characters/Player/ABP_XenoCore_Base Locomotion state machine, montage slots, inertialization, stride warping, spine twist, head and neck turn
Layer interface Characters/Player/AnimLayers/ALI_XenoCore_AnimLayers The layer functions: FullBody_Idle, FullBody_Move, FullBody_Jump, FullBody_Apex, FullBody_Falling, FullBody_Land, FullBody_SkeletalControls
Layer base AnimLayers/ABP_XenoCore_ItemLayersBase The layer graphs, written once
Layer children ABP_XenoCore_UnarmedAnimLayers, ABP_XenoCore_UnarmedAnimLayers_Feminine, ABP_XenoCore_GreatSwordAnimLayers Override clips and blend spaces only
Blend spaces Characters/Player/BlendSpaces/BS_XenoCore_Unarmed_Locomotion, _Feminine, BS_XenoCore_GreatSword_Combat_Locomotion Direction × speed
Style parts Characters/Core/Cosmetics/B_XenoCore_Cosmetic_Masculine, _Feminine Carry Cosmetic.AnimationStyle.Masculine / .Feminine
Weapon instance Weapons/B_WeaponInstance_Base, GreatSword/B_WeaponInstance_GreatSword Picks and links the layer when the weapon is drawn or stowed
Face (VRoid only) Characters/VRoid/<Name>/Animation/ABP_XenoCore_VRoidRetarget_* Blinks, expressions and mouth on a VRoid body
Expression table Characters/Core/Face/DT_XenoCore_FaceExpressions Named faces (Happy, Laugh, Smug…) as mixes of face curves
Anim profile Characters/VRoid/<Name>/DA_XenoCore_AnimProfile_VRoid_* One character's own reaction, death and victory clips, idle breaks and resting faces
Enemy ABP Characters/Enemies/Minion/ABP_XenoCore_Minion_Melee Built on the same C++ parent, not on the host ABP. Moves on a 2D blend space, Minion/Animations/BS_XenoCore_Minion_Locomotion2D (direction × speed), so a minion circling sideways in a fight plays side and back jogs

Lifecycle

Every frame. The C++ parent works out these values, which the graphs read (you can see them in the Animation Blueprint's Variables list):

  • Ground Speed (horizontal only) and a smoothed copy; Is Moving above Moving Speed Threshold (20).
  • Direction, −180 to 180 against the actor's facing. Out of battle the character faces where it runs, so this stays near 0.
  • Stride Scale = Ground Speed ÷ Authored Clip Speed (400), floored at Min Stride Scale (1.0), so warping only ever lengthens the stride above the fastest clip.
  • In Battle, from Status.XenoCore.InBattle on the character's ability system.
  • Target Yaw Delta, the damped, clamped angle to the locked target. It turns the upper body toward the target while the legs keep running (look traversal), up to Max Target Twist (70°).
  • Look Bone Rotation 0–2, the head and neck turn toward what a companion is looking at (see The head turn).
  • Wants Idle Break (see below).

The state machine. The host moves between Idle and Move on ground speed with a short blend, and through jump states (Jump, Apex, Falling, Land) when airborne. Each state calls its layer function, such as FullBody_Move, which plays a 2D blend space: direction on one axis, speed on the other, with walk clips at 200 and jog at 400, so both walking and running blend continuously.

Choosing the layer. The weapon instance Blueprint holds two sets, Equipped Anim Set and Uneuipped Anim Set (Lyra's spelling), each a list of layer classes with the tags that select them. When the weapon is drawn or stowed, the set for that state is searched for the layer whose tags best match the character's style tags (so a feminine character gets the feminine unarmed layer), that layer is linked, and the change of stance blends over Anim Layer Blend Time instead of popping.

If nothing is linked, each layer node falls back to ABP_XenoCore_UnarmedAnimLayers.

Masculine and feminine. A party pawn's Cosmetic Part (on B_XenoCore_PartyMember_Base) adds a style part carrying Cosmetic.AnimationStyle.Masculine or .Feminine. The same tag picks the body mesh through the pawn's Body Meshes rules (SKM_Manny or SKM_Quinn) and the unarmed layer. The feminine layer uses Lyra's MF_ clips (MM_ is Lyra's masculine set).

Idle breaks. After Idle Break Delay (8 s) plus a random Idle Break Jitter (up to 6 s) of standing still, Wants Idle Break turns true for exactly the length of the chosen clip, and the idle layer blends to that clip and back. Each character rolls its own timing, so a party does not fidget in unison.

Which clip plays comes from two places:

  1. The character's Anim Profile, if it has one: Idle Breaks out of battle, Armed Idle Breaks with the weapon drawn. One is picked at random each time, never the same one twice running.
  2. Otherwise, the stance's own Idle Break Anim on its layer child. The shipped ones: MM_Unarmed_IdleBreak_Fidget (unarmed), MF_Unarmed_Idle_Break (feminine), AS_Kwang_IdleBreak_Laugh (greatsword). An empty Idle Break Anim means that stance never fidgets, unless the profile gives it a list.

Each shipped VRoid member has four breaks in its profile, drawn from Lyra's three and nine bare-handed clips in Characters/Core/Animations/IdleBreaks (Stretch, Waiting, Sneeze, Greeting and others). Their Armed Idle Breaks are empty, so with the sword out they use the stance's own break. See Give a character its own idle breaks and faces.

Montages. Attacks, Arts, hit reactions and the draw and sheathe play as montages on top of the state machine. Attacks and Arts use the slots of the default slot group (DefaultGroup): the party's play on FullBody, the minion's on DefaultSlot; Topple, Daze, guards, recoils and victory emotes also use FullBody; the draw and sheathe use UpperBody. A flinch plays additively on the AdditiveHitReact slot, which sits in its own group, AdditiveGroup: it is layered on top of whatever the body is doing, so a hit reads while the character walks or swings, and it never stops the swing. A character does not flinch while drawing or sheathing.

A miss plays a duck or a dodge, picked at random from the evade ability's Random Montages (GA_XenoCore_Evade), on the Defence slot. In battle the arms are taken back from the stance under that slot, so the body ducks while the hands stay on the sword; unarmed, the clip's own arms play.

While a hit's knockback is pushing the body, the anim instance reads its velocity as zero, so a character sliding backwards from a blow does not break into a forward jog.

Fails silently: a flinch that never shows, or that cancels the swing

A flinch montage must be on the AdditiveHitReact slot, its clips must be Additive Anim Type Local Space (base pose: the clip's own first frame), the anim Blueprint must apply that slot additively, and the slot must be in its own slot group on the skeleton. Montages in one group stop each other, and compiling an anim Blueprint puts a new slot in DefaultGroup, so a flinch there cuts the attack short and the next swing cuts the flinch off. Check it in the skeleton's Anim Slot Manager: AdditiveHitReact belongs under AdditiveGroup, as on SK_Mannequin.

Per-character combat clips. Reaction and death montages come from the reaction ability and the pawn by default, shared by everyone who has them. A character's Anim Profile (a data asset, set on the pawn under XenoCore › Animation) overrides them for that character only, slot by slot: an empty slot keeps the shared clip. Each reaction ability names the profile row it reads with its Profile Key (Anim.XenoCore.Reaction.Flinch, .Topple, .Daze, .Guard, .Evade, .Recoil). Walking, running and idles are not in the profile; they come from the style and the weapon, as above. See Give a character its own combat animations.

Stride warping happens once, in the host ABP, driven by Stride Scale.

VRoid faces. A VRoid party member runs the Mannequin animation on an invisible body; its VRoid mesh copies the pose, and its retarget Animation Blueprint (ABP_XenoCore_VRoidRetarget_*) drives the face:

  • a random blink, timed per character;
  • an expression chosen from the character's gameplay tags by Expression Rules, first matching rule wins. The shipped order: downed looks pained, dead closes the eyes, Topple and Break look surprised, Daze sad, a victory celebration laughs, casting an art and being in battle look angry, a conversation looks relaxed;
  • a mouth flap while Talking Tag is held, or lip sync for a voice line;
  • Play Expression for scripted moments, which wins over the rules for its duration.

An expression is named by a row of the face's Expression Table, which defaults to Characters/Core/Face/DT_XenoCore_FaceExpressions. It ships 19 rows: Happy, Smile, Laugh, Giggle, Wink, Smug, Annoyed, Angry, Determined, Sad, Worried, Surprised, Shocked, Relaxed, Bored, Sleepy, Yawn, Thinking and Pained. Each row is a Curves map of face curve to weight, built from the VRM presets (happy, angry, sad, relaxed, surprised, aa, ih, ou, ee, oh, blink, blinkLeft, blinkRight). Suppress Blink stops the blink while it shows, and Pulse Curve, Pulse Weight and Pulse Rate add an oscillating curve on top, such as a laugh's opening and closing mouth. A name that is not a row is played as one curve at full weight, so a rule that says angry still works.

To play a face from any Blueprint, call Play Expression On Actor with the pawn (or its cosmetic part), a row name, a weight and a duration. It returns false, and does nothing, on a character without a face, such as a Mannequin-bodied member or an enemy.

The head turn

Companions turn their head and neck toward whatever their gaze is on: the leader, another member, the view, the battle target. What they look at is chosen by the party StateTree (see Companion AI); this is the part that moves the bones.

ABP_XenoCore_Base adds Look Bone Rotation 0, 1 and 2 to neck_01, neck_02 and head, after the chest twist. The head carries about half the turn and moves fastest, and the neck trails it, so the turn reads as a head leading rather than one stiff hinge. When the chest is already twisted toward a battle target, that twist is taken off first, so the head does not turn twice.

The head returns forward while the character holds any of Look Blocked By Tags (downed, celebrating, toppled, dazed by default), because a clip is driving the head then. A player-controlled body has no gaze and always looks straight ahead.

Settings

Setting Where it lives What it does
Idle Break Anim, Idle Break Delay, Idle Break Jitter Layer child › Class Defaults › XenoCore › IdleBreak The fidget for this stance and how often
Clip and blend space overrides Layer child › Asset Override editor Which clips each state plays
Authored Clip Speed, Min Stride Scale, Moving Speed Threshold, Speed Smoothing Rate Host ABP › Class Defaults › XenoCore › Locomotion Stride warping and idle/move threshold
Max Target Twist, Target Twist Interp Rate Host ABP › Class Defaults › XenoCore › Battle Upper-body turn toward the target
Equipped Anim Set, Uneuipped Anim Set Weapon instance Blueprint › Class Defaults Layers for drawn and stowed
Anim Layer Blend Time Weapon instance Blueprint Blend time on a layer swap
Cosmetic Part Party pawn Blueprint › Class Defaults Masculine or feminine style part
Anim Profile Party or enemy pawn Blueprint › Class Defaults › XenoCore › Animation This character's own reaction, death and victory clips, idle breaks and resting faces; empty slots use the shared ones
Body Meshes Party pawn's character parts component Tag → body mesh rules
Expression Rules, Expression Table, blink and mouth settings VRoid retarget ABP › Class Defaults › XenoCore › Face Face behaviour, and the table expression names are looked up in
Look Bone Shares, Look Bone Interp Speeds, Look Max Yaw, Look Give Up Yaw, Look Max Pitch Up/Down, Look Origin Bone, Look Blocked By Tags Host ABP › Class Defaults › XenoCore › Look How far and how fast the head turns (70° yaw, given up past 125°; 30° up, 25° down)
Idle Breaks, Armed Idle Breaks Anim profile › Idle This character's own fidgets; empty uses the stance's
Social Expressions, Solo Expressions Anim profile › Face This character's faces at rest: its temperament

A style tag with no rule gives the default body

The character-parts component always applies a body mesh from Body Meshes. A style part whose tags match no rule, or whose class is empty, resolves to Default Mesh. Every shipped pawn has one, and XenoCore's party and player characters fall back to their spawn mesh (with a warning) if a Default Mesh is missing, so the result is the wrong body rather than none. A pawn outside XenoCore's character classes still disappears. A party pawn that sets no Cosmetic Part must not add a part at all. See Characters.

For programmers. Fails silently: an anim property without Blueprint Read Only

If you add a C++ property to an anim instance and drive an anim graph pin from it, it must be Blueprint Read Only (or Read Write). Otherwise the Animation Blueprint fails to compile with no message anywhere, and Play in Editor just says a Blueprint failed to compile.

Fails silently: a face curve the mesh does not have

An expression row that names a curve the VRoid model's face does not have shows nothing, and nothing is logged. A typo in a row name looks the same, because a name that is not a row is tried as a single curve. Rows built from the VRM presets listed above are known to work; check any row that uses a raw Fcl_* morph curve in Play before relying on it.

Fails silently: the idle break branches wired backwards

In Blend Poses by bool, the first pose pin is the True pose. Wired the other way round, the fidget becomes the idle and the real idle plays as an occasional interruption.

Fails silently: a second Stride Warping node

Stride warping already runs in the host. Adding it in a layer too applies it twice and the feet slide. A Stride Warping node with no thigh bones set does nothing at all, which hides the mistake until someone fills them in.

Fails silently: a montage on the wrong slot group

The layer-swap blend is requested on DefaultGroup. A montage on another group blends wrongly when the stance changes, with no error.

Extending it

  • A new weapon stance: duplicate ABP_XenoCore_GreatSwordAnimLayers into your own folder, set its clip and blend-space overrides and its Idle Break Anim, then point your weapon instance's Equipped Anim Set at it. No graph editing is needed. See Add a weapon.
  • Changing a character's animation style: see Animation style.
  • One character's own topple, flinch, block, dodge or death: fill in its Anim Profile; see Give a character its own combat animations. No ability needs duplicating.
  • Never recreate ABP_XenoCore_UnarmedAnimLayers. The host's layer nodes use it as their fallback class; a new asset under the same name orphans them. Duplicate it instead.
  • Do not reparent an Animation Blueprint to another Animation Blueprint to share logic: a child Animation Blueprint loses its own graph. Use override-only layer children as above; logic shared by every Animation Blueprint belongs in the C++ parent, which is a programmer's job.
  • Keep gameplay-tag-driven variables on the host Animation Blueprint; on a linked layer they stop updating after the layer is linked.
For programmers: classes and calls

The C++ parent is UXenoCoreAnimInstance: it captures velocity and rotation on the game thread and computes the values above in the thread-safe update. The face is UXenoCoreFaceAnimInstance, the profile UXenoCoreCharacterAnimProfile, an expression row FXenoCoreFaceExpressionRow. On a draw or stow, the weapon instance's SetDrawn collects the cosmetic tags, calls Lyra's PickBestAnimLayer, then LinkAnimClassLayers, then RequestSlotGroupInertialization("DefaultGroup", AnimLayerBlendTime). The flinch ability refuses while Status.XenoCore.Arming is held.

Why it's built this way

For programmers
  • Own host, not Lyra's. Lyra's locomotion enters Start/Stop states on input and commits to them for up to a second, which feels unresponsive for this style of game; its state machine lives in Lyra's own asset and cannot be owned. XenoCore's Idle ↔ Move machine with a 2D blend space is snappier and blends walk and run continuously.
  • Lyra's layer mechanism, kept. Per-state linked layers, PickBestAnimLayer from the weapon on draw, and an inertialization request (Lyra delivers the same request through a transition). Links are made once on an event, never per frame, and never unlink-then-link, which would drop every node to its fallback for an instant.
  • Not derived from ULyraAnimInstance, because it has no export macro and cannot be derived from outside Lyra's module; UXenoCoreAnimInstance reproduces the part it needs and pulls the ability system itself.
  • Idle breaks in the anim stack, where Lyra keeps its own, because the graph already knows whether the Idle state is active; an ability polling for it was heavier and less exact.