Skip to content

Party

All · 15 min read · No code

The party is owned by one component on the player controller, UXenoCorePartyComponent, set up as the Blueprint Characters/Party/BP_XenoCore_Party. It holds three things: the roster (everyone recruited), the active members (everyone fielded) and the leader slot (which active member the player drives). It spawns a body for each active member and despawns benched ones. The one idea: the leader is an index into the active list, not a different kind of character. Every active member has the same class, the same spawn path and an AI controller ready to take the body back; switching leader is only the player controller letting go of one body and possessing another. The player can do that at any time, in battle too, with the triggers (XC3-style).

At a glance

In play: up to seven characters fight together; you drive one and the rest follow and fight on their own. Tap a trigger to take control of another, in or out of battle.

What you can change, no code:

How it fits together

Piece Asset What it decides
Party component Characters/Party/BP_XenoCore_Party Starting roster, party size, leader slot, leader-only abilities, spawn spacing. Added to the player controller by the plugin's Game Feature Data.
Member definition Characters/VRoid/<Name>/PartyMember_VRoid_* for the seven sample characters (UXenoCorePartyMemberDefinition); the colour mannequins' Characters/Party/PartyMember_* are kept as samples Name, role, portrait, which Blueprint to spawn, which AI controller drives it. One per recruitable character.
Member Blueprint Characters/VRoid/<Name>/B_XenoCore_Party_VRoid_*, children of Characters/VRoid/B_XenoCore_Party_VRoid_Base Everything about the character itself. See Characters.
AI controller Characters/Party/BP_AIC_XenoCore_PartyMember (AXenoCorePartyMemberController) Carries the team and runs the StateTree.
Party AI Characters/Party/AI/ST_XenoCore_PartyMember Following out of battle, fighting in battle.
Recruit trigger AXenoCorePartyRecruitTrigger (place it in a level) Adds a character to the roster when the player walks in, or when called.
Join banner UserInterface/HUD/W_XenoCore_PartyJoinBanner in the HUD layout "joined the party" / "left the party".
Party screen UserInterface/W_XenoCore_PartyManager Swap members, change leader. In battle, change leader only.
Switch abilities Input/Abilities/GA_XenoCore_PartySwitch, GA_XenoCore_PartySwitchPrev, GA_XenoCore_PartySelect Tap a trigger to switch, hold one for the party cursor. Granted through the Leader Only Ability Set.

The member definition is deliberately thin. It does not hold pawn data, a statline or a level; those belong to the member's Blueprint, so each fact has one home.

The roster, active and reserve

  • Roster: everyone recruited. Adding to the roster is idempotent, so a story event that fires twice does not duplicate anyone.
  • Active members: the first Max Active Members of the roster, in order, unless changed. The leader counts towards the number.
  • Reserve: everyone else in the roster. A reserve member has no body at all: no pawn, no ability system, no equipment component. Their level, EXP and arts live on the progression component, and what they were wearing is remembered by the party component, so the Party screen can still show them.

Reserve members gain EXP at the progression component's Reserve Experience Rate. The sample's Game/BP_XenoCore_Progression sets it to 0, so a benched member earns nothing (the C++ default is XC1's 90%). Recruits with Join At Party Level catch up when they join. See Progression.

The sample's Starting Roster is Kael and Mira. The other five characters are recruited in Gaur Plain by talking to them. Max Active Members is 7 on BP_XenoCore_Party, so every recruit joins active and the reserve stays empty until you recruit an eighth or lower the number. The C++ default is 3.

Lifecycle

  1. Start. On begin play the component either restores a save or adds every Starting Roster member in order. Starting members are the party you already have, so they raise no join banners.
  2. Spawn. As soon as the player controller has a pawn, the component records where that pawn stands, then spawns each active member. The leader's body lands exactly on that spot; the others are scattered loosely in an arc behind it, each at its own distance and facing, so the party never appears in a neat formation (the Spawn settings, see Where they appear). Each gets its own AI controller, set to the leader's team before possession.
  3. Hand-over. The player possesses the body in Leader Slot. The Leader Only Ability Set (interaction, in the sample) moves to that body and is taken away from the previous one.
  4. Changes. Every change (recruit, remove, swap, clear, set leader) edits the lists and then re-syncs bodies through one spawn path, then broadcasts XenoCore.Party.Message.Changed. The message carries no detail; listeners re-read the component.
  5. Notices. Joins and leaves are queued rather than shown immediately, because party changes are made from a paused menu. UXenoCorePartyNoticeSubsystem drains the queue once the game is running again and plays the banner, leavers first.
  6. Defeat. The component watches every body it spawns. A member who runs out of HP is downed, not killed: they kneel and can be revived for a bar of the Party Gauge, and they get up at 1 HP when the battle ends. See Party Gauge, downed and revive. When every active member is down, the party is wiped (see below).

Party wipe

When the last active member falls (a member with no body counts as down):

  1. XenoCore.Party.Message.Wiped is broadcast with Phase Defeated and the Respawn Transform the party is about to be sent to, so a "defeated" card can name the place.
  2. The defeat beat plays across Wipe Fade Delay (2.5 s): time slows, the world drains of colour, Defeated fades in in bold red, and a sting plays. Then the camera fades to Wipe Fade Colour over Wipe Fade Out Duration, with the word still on screen. Every part of the beat is a setting; see Tune revive and defeat.
  3. Under black, every active body is replaced by a fresh one at the respawn point: no reactions, no battle state, no target mode. Every enemy forgets the fight and walks home.
  4. After Wipe Hold Duration every active member is set to full health, the camera fades back in, and the message is broadcast again with Phase Respawned.

Experience, levels, items and gear are kept: none of them live on the bodies that were replaced. The respawn point is, in order: the point last recorded by Set Party Respawn Point, else the map's player start, else where the party was standing. A save point records itself when the player steps on it (unless its Is Respawn Point is off), so in practice the party returns to the last save point visited this session. To answer from anything else, such as a story checkpoint, override the Get Wipe Respawn Transform function in BP_XenoCore_Party (in the My Blueprint panel, Functions › Override), or call Set Party Respawn Point from your own Blueprint when the checkpoint is reached.

For a battle the story means the player to lose, call Begin Party Wipe to run the same flow. Is Party Wiped and Is Wipe In Progress let other systems stay out of the way meanwhile.

Fails silently: the party respawns inside the floor

The respawn point is a capsule centre, like a player start, and the leader is placed exactly there with no collision adjustment. A Get Wipe Respawn Transform override or a Set Party Respawn Point call that passes a point on the ground puts the party half into it. Raise the point by the capsule's half-height (about 100). Save points already do this with their Respawn Offset.

A fallen leader is not a wipe

By default only the whole active party going down wipes it. If the leader falls while others still stand, the player can switch to a standing member with the triggers and fight on (see Switching the controlled character). Nothing switches automatically: if the player does not, the leader kneels until the battle ends, or the fight is lost when the rest fall too. Party AI does not revive the leader yet. Tick Wipe When Leader Falls on BP_XenoCore_Party to end the fight the moment the leader goes down.

Swapping and the leader

Blueprint node What it does Refused in battle?
Add To Roster (Member, Activate Immediately, Join At Party Level) Recruit. Fields them straight away if there is room and Activate Immediately is ticked. With Join At Party Level, a new recruit arrives at least at the leader's level. No
Remove From Roster The character leaves the story. No
Set Active Members Replace the fielded list wholesale. Ignores anyone not in the roster, with a warning. No
Swap Member (Active Slot, Member) Put a roster member into a slot. If they are already active elsewhere, the two trade places. Yes
Clear Slot Bench whoever is in a slot. The list compacts: later slots move up. Yes
Set Leader (Active Slot) The player drives that member. The new leader moves to slot 0 and everyone they passed moves down one. No, but it obeys the switch rules below
Switch Leader By (Direction) The next (1) or previous (−1) member who can take control, as a trigger tap does. No
Switch Leader To (Member) The player drives that body, as the party cursor does. No
Can Change Party False while the leader carries Status.XenoCore.InBattle (weapon drawn).
Can Assign To Slot (Active Slot, Member) Whether a Swap Member with these arguments would be accepted right now. Use it to grey out rows.

The in-battle rule is enforced by the component, not the screen, so any caller obeys it. Swap Member between the leader's slot and another active member is a leader change, not a composition change, so it is allowed in battle; that is how the Party screen picks a leader. Story events (add, remove, set) are deliberately not gated, so a cutscene recruit never fails because a fight was running. Show Party Locked Message raises Lyra's own confirmation dialog explaining the refusal.

Slots move when you clear one, and when the leader changes

Clear Slot compacts the active list, so the member who was in slot 2 is now in slot 1. A leader change also reorders it, because the leader always ends up in slot 0. Never store a slot number across a change; store the member definition and look up its slot again.

Switching the controlled character

The player can take control of any active member at any time, in battle or out, XC3-style. Control changes hands; nobody joins or leaves.

Input What happens
Tap RT (C) Control passes to the next member down the party column.
Tap LT (Z) Control passes to the previous member, up the column.
Hold LT or RT (Z or C) The party cursor opens on the leader's row. The D-pad (arrow keys) moves it; releasing the trigger takes control of the member under it. Releasing on the leader cancels.

What you see. The party cursor is a highlight on the member's HUD row plus a small white ring on the floor under their body. Out of battle the party column slides in while the cursor is up. When control lands, the white ring flashes under the new leader and fades, the word Leader appears over them, the camera blends to their view, and the HUD rows slide into their new places. Out of battle the column then stays up for a moment and slides away.

The column reorders. The leader is always the top row. A trigger tap or the cursor rotates the column: the chosen member goes to the top and everyone above them moves to the bottom, in order, so repeated taps walk the whole party. A pick in the Party screen cascades: the chosen member goes to the top and only those they passed move down one.

In battle, the fight carries over. The new leader draws their weapon if it is sheathed and locks the enemy the old leader had locked. The old leader keeps their weapon out and their swing going, and the party AI takes them over. Cooldowns, gauges and statuses belong to each body, so nothing resets.

When a switch is refused, "Can't switch" appears over the leader and Switch Refused Sound plays. A switch is refused:

  • away from a leader who is toppled or dazed;
  • while an ally-targeted Art is choosing its target (the cursor is busy);
  • during a party wipe;
  • when nobody else can take control.

Members who are downed, toppled, dazed or in the air are skipped by a tap and cannot be chosen with the cursor. A downed leader can be switched away from, which is how the player carries on fighting. Nothing switches automatically, and the battle is lost only when every active member is down (unless Wipe When Leader Falls is ticked).

The Party screen in battle allows a leader pick only: select the leader's row, then another active member. Bench swaps, clearing a slot and reordering other members stay locked until the fight ends.

The same cursor is used by Arts that target one ally, such as Light Heal: confirming the Art opens the cursor on the caster, the D-pad moves it, and confirming again casts. See Targeting.

Fails silently: switch abilities granted outside the leader-only set

The three switch abilities live in AbilitySet_XenoCore_Interact, the Leader Only Ability Set, which moves to whichever body the player drives. Do not also grant them in a member's own ability set: the switch moves the leader-only set on the next frame, and a second copy on another body is never removed, so it answers the trigger from a body the player is not driving.

Fails silently: a party member that nothing can hurt

A party member is only on a team if its controller is AXenoCorePartyMemberController or a child of it. A plain Blueprint AI controller leaves the member on no team: enemies ignore it and your own attacks pass through it, with no error. Keep Controller Class empty (to use the component's Default Controller Class) or point it at a child of BP_AIC_XenoCore_PartyMember.

Fails silently: a member who never spawns

A member definition with Member Class empty is logged as an error when it should spawn and simply never appears. Run Validate Assets on your member definitions: missing Member Class, a pawn with no pawn data, a missing display name or portrait are all reported there.

Party AI

Companions are driven by ST_XenoCore_PartyMember on the StateTree component of their controller. It has two branches, chosen by XenoCore Party In Battle (the leader carries Status.XenoCore.InBattle):

  • Travel. Three states in a loop:
    • XenoCore Party Hold rests near the leader until it is Follow Start Distance away - strolling, chatting with a companion or pulling a face on its own clock (see What they do while they wait).
    • XenoCore Party Follow Leader trails the leader at Trail Distance plus Per Slot Spacing per slot, matching the leader's speed instead of stopping and starting.
    • XenoCore Party Recalculate Position runs once the leader stops: it settles, picks a resting spot on the member's own side of the leader, steps onto it, and returns to Hold.
  • In battle. One state running two tasks, XenoCore Fight Target (target and auto-attack) and XenoCore Use Best Art (arts). XenoCore Party Follow walks the member to a spot an EQS query chose around the target, so the party spreads out instead of piling up. A companion fights the leader's target; with none, the nearest enemy already fighting the party. The whole battle side is its own page: Companion AI and aggro.

The party counts as in battle when the leader has drawn its weapon, or when an enemy within 30 m is already fighting the party, so companions defend themselves even before the player locks on.

XenoCore Party Follow also teleports a member that falls more than Teleport Distance behind.

All of the distances above are parameters on the tasks inside the StateTree asset. To tune them without changing the shipped tree:

  1. In Characters/Party/AI, right-click ST_XenoCore_PartyMember and choose Duplicate. Move the copy into your own folder, for example MyGame/AI.
  2. Open your copy, select a state (for example Travel), select the task in the Details panel and change its numbers. Save.
  3. In Characters/Party, right-click BP_AIC_XenoCore_PartyMember and choose Create Child Blueprint Class. Move the child into your folder and open it.
  4. In its Components panel select StateTreeAI, and in the Details panel set its AI › State Tree to your copy. Compile and Save.
  5. Open BP_XenoCore_Party, click Class Defaults, and set XenoCore › Party › Default Controller Class to your child (or set Controller Class on one member definition, for one character only).

What you can change

Setting Where it lives What it does
Starting Roster BP_XenoCore_Party › XenoCore › Party Members the game starts with, in order.
Max Active Members BP_XenoCore_Party › XenoCore › Party How many are fielded at once, leader included. Also the number of rows on the Party screen.
Leader Slot BP_XenoCore_Party › XenoCore › Party Which active slot the player starts driving.
Leader Only Ability Set BP_XenoCore_Party › XenoCore › Party Abilities only the player-driven body may hold.
Default Controller Class BP_XenoCore_Party › XenoCore › Party AI controller for members that name none.
Spawn Inner Radius, Spawn Arc Degrees and the other Spawn settings BP_XenoCore_Party › XenoCore › Party › Spawn First placement around the leader; see Where they appear.
Switch Camera Blend Time BP_XenoCore_Party › XenoCore › Party › Switch Camera blend to the new leader (0.35 s; 0 cuts).
Switch Announce Text, Switch Announce Colour, Switch Announce Scale BP_XenoCore_Party › XenoCore › Party › Switch The "Leader" line over the new leader. Empty text shows nothing.
Switch Sound, Switch Cursor Sound BP_XenoCore_Party › XenoCore › Party › Switch Played as control lands, and as the cursor moves. Empty by default.
Switch Refused Text, Switch Refused Colour, Switch Refused Scale, Switch Refused Sound BP_XenoCore_Party › XenoCore › Party › Switch The "Can't switch" feedback.
Party Cursor Ring Material, Party Cursor Ring Colour, Party Cursor Ring Diameter, Party Cursor Ring Lift BP_XenoCore_Party › XenoCore › Party › Cursor The cursor's floor ring: the aggro ring's material tinted white, 110 cm across, 8 cm off the ground. Empty material = no ring.
Switch Ring Hold Seconds, Switch Ring Fade Seconds BP_XenoCore_Party › XenoCore › Party › Cursor The ring flash under a new leader: full strength for 0.35 s, then a 0.6 s fade. Both 0 = no flash.
Switch Slide Seconds, Switch Reveal Seconds Each party row widget (UXenoCorePartyMemberPlateBase) › XenoCore › Party › Switch How long a row slides to its new place (0.22 s; 0 snaps), and how long the column stays up after an out-of-battle switch (1.2 s).
Display Name, Role, Portrait Member definition › XenoCore › Party Shown on the HUD and menus. Role is displayed only; nothing reads it yet.
Member Class Member definition › XenoCore › Party The Blueprint spawned for this character.
Controller Class Member definition › XenoCore › Party Overrides the default AI controller.
Member To Recruit, Activate Immediately, Join At Party Level, Recruit On Overlap, Destroy After Recruiting Placed recruit trigger › XenoCore › Party Who joins, whether they are fielded, whether they arrive at the party's level (on), whether walking in triggers it, and whether the trigger removes itself.
Member To Recruit, Recruit After Quest, Join At Party Level, Leave When Recruited Placed NPC › XenoCore › NPC › Recruit Talking to this NPC recruits the member (after the quest, if one is set), at the party's level, and the NPC steps out. See Recruit by talking.
Wipe Fade Delay, Wipe Fade Out Duration, Wipe Hold Duration, Wipe Fade In Duration, Wipe Fade Colour BP_XenoCore_Party › XenoCore › Party › Wipe Timing and colour of the defeat fade (2.5, 1.0, 0.5, 1.0 s, black).
Wipe When Leader Falls BP_XenoCore_Party › XenoCore › Party › Wipe Also wipe as soon as the leader falls. Off by default.
Get Wipe Respawn Transform BP_XenoCore_Party, function override Where a wiped party stands again.
Respawn Offset, Is Respawn Point Placed save point › XenoCore › Save Where on the pad the party respawns (default 100 up), and whether visiting the pad records it.
Travel and battle distances ST_XenoCore_PartyMember task parameters Follow spacing, speeds, teleport distance.

Fails silently: the cursor ring overlaps the aggro ring

Party Cursor Ring Diameter is kept well inside the aggro ring (220 cm) so the two nest under a member an enemy is after. Make it 220 or larger and the rings overlap into one shape, with nothing to tell the player which is which.

Fails silently: a cursor ring material without the right parameters

The ring writes its tint to a Colour parameter and the switch flash fades it through an Opacity parameter. A material of your own without them draws the ring in its own colour, and the flash stays at full strength until it vanishes instead of fading. Nothing is logged. Copy both parameters from Effects/Aggro/M_XenoCore_AggroRing.

Fails silently: interaction on an AI body

Anything in Leader Only Ability Set is granted only to a player-controlled body. Lyra's interaction scan asserts if it runs without a player controller, which is why interaction lives there. If you add your own ability that needs a player controller, put it in that set, not in a member's pawn data.

Extending it

  • Add a character: a Blueprint plus a member definition, no code. See Add a party member and Set the starting party.
  • A flourish on a switch: implement On Switch Slide (From Slot) on your party row widget; it fires on each row whose character arrived from another row.
  • Recruit by talking to someone: set Member To Recruit on a placed NPC. See Recruit a party member by talking to them.
  • Recruit from a story event: call Add To Roster on Get Party Component, or place an AXenoCorePartyRecruitTrigger and call its Recruit node from a cutscene. A Blueprint child of the trigger can implement On Recruited for a sound or a line of dialogue.
  • Different AI: duplicate the StateTree ST_XenoCore_PartyMember (it is data), and make a child Blueprint of BP_AIC_XenoCore_PartyMember that uses your tree. A child keeps the C++ controller the team depends on.
  • Do not keep your own list of party pawns. Ask Get Active Member Pawns or Get Pawn For Member, and listen for XenoCore.Party.Message.Changed.

Console commands

XenoSetLeader, XenoDownMember, XenoWipeParty, XenoReviveMember and XenoHurtParty run in development builds. See Diagnostics.

Why it's built this way

For programmers: the design reasons
  • On the controller because the party must survive changing which body the player drives, and because Lyra's own party-wide systems (quick bar, item costs) look there.
  • Spawning lives with the lists because "who is active" and "who has a body" are one fact. Two components each owning half would disagree.
  • The leader is a slot so the Party screen, the HUD and the save all describe the leader the same way as everyone else. An earlier design kept the leader outside the list and every screen needed special cases for it.
  • Switching is a free action (XC3): it interrupts neither character, so the fight is handed over rather than ended and restarted. Every rule lives on the party component, so the triggers, the Party screen and the console all obey the same ones.
  • An empty roster still plays. Until you author your first member, the player keeps the pawn Lyra's game mode spawned. Nothing in the component names a character, so you can delete every shipped character without touching C++.