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:
- Who you start with, and how many fight at once: Set the starting party
- A new character: Add a party member
- Recruiting someone by talking to them: Recruit a party member
- The defeat screen and where the party wakes: Tune revive and defeat
- How companions follow and fight: Tune companion AI
- Every setting on this page: What you can change
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¶
- 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.
- 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.
- 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.
- 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. - Notices. Joins and leaves are queued rather than shown immediately, because party changes
are made from a paused menu.
UXenoCorePartyNoticeSubsystemdrains the queue once the game is running again and plays the banner, leavers first. - 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):
XenoCore.Party.Message.Wipedis broadcast with PhaseDefeatedand the Respawn Transform the party is about to be sent to, so a "defeated" card can name the place.- 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.
- 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.
- 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:
- In
Characters/Party/AI, right-clickST_XenoCore_PartyMemberand choose Duplicate. Move the copy into your own folder, for exampleMyGame/AI. - Open your copy, select a state (for example Travel), select the task in the Details panel and change its numbers. Save.
- In
Characters/Party, right-clickBP_AIC_XenoCore_PartyMemberand choose Create Child Blueprint Class. Move the child into your folder and open it. - In its Components panel select StateTreeAI, and in the Details panel set its AI › State Tree to your copy. Compile and Save.
- 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
AXenoCorePartyRecruitTriggerand 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 ofBP_AIC_XenoCore_PartyMemberthat 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++.