Questlight Studio
Docs / Characters and party

5. Characters and party

In short: A class (URSEClassData) defines stat growth, abilities by level and allowed equipment. A character (URSECharacterData) is a specific hero, recruit or enemy with a fixed class plus personal traits. The party (URSEPartySubsystem) holds who is in your team, their levels, equipment, resources and Pacts for the whole game, and survives level changes and saves.

5.1 Basics

5.1.1 The three kinds of character

Every character has a Roster that says where it can fight:

RosterWhat it isFights in
MainA story character: found in the world and recruited as the story goes.Every battle mode.
SecondaryA recruited unit (a mercenary, a volunteer).Grid Tactics only.
EnemyAn enemy or neutral unit, controlled by the AI.Every battle mode, on the other side.

Two more ideas modify this:

  • Guest: a character with Guest ticked is a temporary party member. It always wears its Default Equipment and the player cannot change it, for exactly as long as it is in the party. A guest keeps a fixed loadout, build and Pact.
  • Class is fixed. There is no job change. A character keeps its class for the whole game. What changes a character over time is levels, equipment, the progression system (Progression) and, for main characters, Pacts.

The same character, class, stats and abilities work in every battle mode.

5.1.2 First working example: make a class, a hero and put it in the party

  1. Archetypes first. In the Studio, 2. Archetypes → Archetype library, pick a hero class archetype such as Paladin and press Create content from it. That creates a class in your project.
  2. A hero. 3. Content → New character. Answer the seven steps: Who is it? (name, Hero), Start from (an archetype or an existing character), How does it look?, Which class? (and starting level), What can it do? (abilities by level, with checkboxes), Where does it appear?, Summary and Create.
  3. Where does it appear? offers four choices:
    • Not yet: only the asset is made.
    • In the starting party: the hero is part of a new game's party (the Studio updates Party → Starting Members for you).
    • Recruitable in the world: an NPC with a "Join us?" dialog is placed in front of the camera, with a story flag that remembers the recruitment.
    • An enemy in the world: an encounter and a spawner or battle zone.
  4. After Create, open the character sheet. Press Test in battle to play a few quick simulated battles and read the win rate.

The same one-click actions are available on any Character asset: right-click it, RPG Saga: Character Actions, then Add to Starting Party, Make Recruitable or Make Enemy. Undo removes what was placed in the level.

5.1.3 The character sheet

Double-click a Character asset to open its sheet: header (portrait, name, role, class, level, valid or not), buttons (Test in battle, Add to party, Make recruitable, Make enemy, Duplicate, Open generic editor) and tabs: General, Look (live preview), Class & stats (the stats at the starting level), Abilities, Equipment and In game. Simple / Advanced shows the essential fields or all of them. Only the fields that make sense for the role are shown (an enemy has no guest flag and no Add to party button, a hero has no loot table). The class and the look can be edited right on the sheet.

Characters and classes that come with the plugin are templates: the sheet shows a Create a copy in the project button, and only your character changes.

5.1.4 The fields of a character

FieldMeaning
ClassThe fixed class.
RosterMain, Secondary or Enemy.
Starting LevelLevel when the character first joins (default 1).
ControlPlayer or AI. Guests can be either; enemies are AI.
Default ATB RowFront or back, for classic battles. Casters and archers usually stand in the back.
Experience RewardWhat the party gets when the character is defeated as an enemy. 0 = the formula in the Progression settings.
Loot Table, Default AI ProfileRewards and AI for enemies. An encounter may override the AI profile.
Guest, Default EquipmentA guest wears the default equipment, locked. Other characters start with it.
Personal Modifiers, Personal Affinities, Personal TraitsDifferences from the class: a sturdier knight, a hero weak to fire. They are combined with the class's.
Growth Plan, Bag SizeAn own growth plan and (per-character inventory) bag size, instead of the class's.
Appearance, Portrait, Follower Profile, Attack PresentationsPresentation only. Battles and saves never read them.
Bestiary fieldsDescription, category, hide from the bestiary.

5.1.5 The class

A class (URSEClassData) has:

  • a Class Tag (Class.*), the class's identity;
  • Stat Growth: for each stat a Base at level 1 and a Per Level value (Base + PerLevel × (Level − 1));
  • Affinities (elemental weak, resist, immune, absorb) and Granted Tags (traits such as Trait.Move.Levitate);
  • Allowed Equipment Types (Equip.Type.*; a parent tag allows all its children);
  • Abilities: each ability with the level it unlocks at;
  • an optional Command Menu layout and Growth Plan (see Progression);
  • an optional Bag Size.

Stats not listed are zero unless a modifier adds them. Derived stats (Max HP computed from Stamina) follow the foundation's formulas (Game foundation and archetypes). An ability the class lists at level 1 is known from the start; later ones unlock when the character reaches that level.

5.1.6 Levels and experience

A character's level and experience are part of the party's state. The experience needed in total to reach level L is

ExperienceBase × (L − 1) ^ ExperienceExponent + ExperiencePerLevel × (L − 1)

unless an Experience Curve (a float curve of total experience by level) replaces the formula. Defaults: maximum level 99, base 15, exponent 2, per level 0. When a character gains experience, every level reached raises the stats from class growth, raises current HP and MP by the gain in their maximums, and unlocks the class abilities of that level. Experience from a battle is shared among the members still standing. Enemies give EnemyExperienceBase + EnemyExperiencePerLevel × (Level − 1) unless their character sets a reward. All of these are in Project Settings → RPG Saga Engine → Progression.

5.1.7 Party and roster

The party is the list of characters the player controls. Related notions:

  • Starting Members: the new-game party (Project Settings → RPG Saga Engine → Party → New Game).
  • Formation (classic battles): the members that fight in ATB and turn-based battles, in order. The rest are the reserve. By default the first members that can fight in classic battles fill it, up to ATB Party Size (Battle, default 4). The first change in the party menu makes it explicit. Secondary characters cannot join it.
  • Rows: each character is in the front or back row (its default row, or the player's choice). The back row deals and takes less melee physical damage by default (magic and bows are not affected).
  • Tactics roster: every member can be deployed in a grid battle, up to the number of deployment tiles.
  • Vitals: each member's current resources, KO state and lasting statuses between battles.

The party menu (Formation page) is where the player changes these. In exploration, the visible party follows the leader in formation and the player can switch leader; see Exploration.

5.1.8 Recruitment, guests and leaving

Characters join and leave through story effects, dialogs and quests, or from Blueprint:

  • Recruit with the effect Add Member (data) or the node Add Party Member (Blueprint). Main, Secondary and Guest characters all use it. It does nothing if the character is already a member.
  • Guests are simply characters marked Guest: add them when the scene needs them and remove them afterwards. They come with their own equipment, fixed for their stay.
  • Leave with Remove Member or Remove Party Member and a departure kind:
    • Permanent: the character leaves for good and its equipment returns to the inventory (guests always keep theirs);
    • Parallel Scenario: the character leaves for another storyline and will come back, keeping its equipment.
  • Restore Party (Restore Party node) gives full HP and MP, removes KO and statuses, for everyone or one character.
  • Set Level can start a recruit at the party's average or highest level plus an offset (a late joiner catching up), or at an exact level.
  • Give Experience, Learn Ability and Forget Ability are effects too.

A recruit usually comes from an NPC (ARSENPC) whose interaction runs a dialog with the Add Member effect. Make Recruitable builds exactly that. Which characters are available can depend on story state: use conditions such as Member In Party and Member Not KO in dialogs, quests and puzzles.

5.1.9 NPC types

NPC types are archetypes (URSENPCArchetype) that create an NPC's interaction: Merchant, Quest giver, Recruiter, Innkeeper, Card player, Passer-by, Blacksmith, Elder, Priest and more, in /RPGSagaEngine/Data/Archetypes/NPCs. Pick one in 2. Archetypes → New NPC type or the library, then place the NPC (ARSENPC) in the level. NPC routines and barks are covered in Exploration.

5.1.10 Pacts

A Pact is the customization layer of main characters (who have a fixed class): an original summon system with affinities, abilities that extend the class, and a summon, a temporary unit the player controls, in every battle mode.

What a Pact (URSEPactData) gives its holder:

  • Affinities and granted tags (a resistance, a status immunity);
  • Abilities learned with Pact points, each with a point cost, an optional prerequisite ability, and an optional Replaces: a Pact ability that upgrades a class ability takes its place while learned;
  • a summon ability (always available to the holder) that creates the summon character: a unit with its own class, stats and abilities, at the summoner's level or a level you set.

Rules:

  • Only main characters hold Pacts. A character holds one Pact; a Pact is held by one character at a time. Guests keep a fixed loadout.
  • Pacts change only outside battle.
  • The party obtains Pacts from the story, optional bosses or puzzles.
  • The summon costs Resonance (Resource.Resonance): a full bar, consumed. Resonance builds when the holder acts (Resonance On Act, default 15), when it takes a damaging hit (Resonance On Hit, 10) and with the share of max HP lost (Resonance Per Damage Percent, 0.5). The bar's size and its gain rules are the resource's definition in the attribute registry.
  • In Tactics the summon stays on the grid for Summon Turns Tactics of its own turns (default 3) on free tiles near the summoner. In ATB it takes the summoner's place for Summon Turns ATB commands (default 3).
  • If the summon is defeated before it expires the summoner suffers backlash: Backlash Damage Percent of its max HP (default 25) and optionally a status.
  • Winning a battle earns Pact points for each Pact that fought: Points Per Victory (default 10) plus Points Per Enemy Defeated (default 2).

Create a Pact with Advanced tools → Create New → Pact: description, summoned unit and an existing summon ability.

5.2 How it works

5.2.1 From data to a unit in battle

URSECharacterData  ──►  class stat growth at the level
        │                + personal modifiers, affinities, traits
        │                + equipment, Pact, statuses, growth (added by their owners)
        ▼
FRSEAttributeSet (the unit's stats)  ──►  battle unit  ──►  presentation actor

URSECharacterData::InitializeAttributes(Level, OutAttributes) produces the class stats at a level plus the character's personal traits. Equipment, Pacts, statuses and progression add their own sources, aggregated in the order of operations you saw in chapter 3. A battle spawns units from the party's state (level, equipment, resources, Pact, progression) or from an encounter's enemy list, then runs them with no knowledge of actors.

5.2.2 The party state

URSEPartySubsystem owns the party's state for the whole game session (it survives level changes). The state (FRSEPartyState) holds: members, inventory and item containers, money, shop purchases, encounter-rate effects, vitals and equipment per character, the formation and ATB rows, owned Pacts with their holders and progress, learned and forgotten abilities per character, progression (level and experience), the growth state of the progression systems, and each member's battle hotbar order.

The state is read-only to screens: GetState() returns it, and changes go through party commands or through GetStateForApply() for the authority's own systems (battle results, loads, story effects), which marks the Party section changed so the write is never silent. The Party section is saved with the game and replicated in co-op.

Before a battle the director remembers the whole party state (SaveBattleSnapshot); a Retry after defeat puts the party back exactly as it was.

5.2.3 Commands

Party changes are commands on the command bus (Core concepts). The party commands include: Set Formation, Set ATB Row, Move In Formation, Set Battle Menu Order, Cast Field Ability, Use Field Item, Equip Item, Unequip Item, Bind Pact, Unbind Pact, Learn Pact Ability, Buy Item, Sell Item, Rest At Inn, Add Party Member, Remove Party Member, Restore Party, Learn Ability, Set Member Resource, Add Experience, Add Party Experience, Set Level, Give Pact, Award Pact Points, Give Item, Take Item, Add Money and Spend Money. Story-driven ones (adding members, experience, Pacts, items, money) are host-only in co-op; the player's own choices (equipment, formation, Pact binding) are open to every player, subject to the co-op rules (for example Guest Equipment).

5.2.4 Events

Subscribe instead of polling:

  • OnMemberResourceChanged (character, resource, old, new) fires when a member's resource changes outside battle (healing items, inns, story effects). Battles report their own on the battle object.
  • OnAbilityLearned (character, ability, learned) fires when a character learns or forgets an ability for good (story effects, scrolls, nodes).

5.3 Key classes and assets

Class / assetModuleRole
URSEClassDataRSECoreA fixed class: stat growth, abilities by level, allowed equipment.
URSECharacterDataRSECoreA hero, recruit or enemy: class, roster, control, traits, equipment, presentation.
ERSECharacterRoster, ERSEBattleControlRSECoreMain, Secondary, Enemy; Player or AI.
URSEPartySubsystemRSECoreThe party's state for the whole session; resource access and events.
FRSEPartyStateRSECoreThe serializable party: members, equipment, vitals, Pacts, progress.
URSEBlueprintLibrary_PartyRSECoreBlueprint access to members, levels, attributes, equipment, formation and Pacts.
URSEPartySettingsRSECoreParty page: starting members, defeat recovery.
URSEPactData, URSEPactSettingsRSECoreA Pact; global Pact rules.
FRSECmd_* party commandsRSECoreCommands such as FRSECmd_AddPartyMember.
ARSENPCRSEAn NPC actor with an interaction (recruiters, merchants).
URSEPartyFieldSubsystemRSEThe visible party in exploration: followers, leader switching.
URSEPartyMenuWidgetRSEThe party menu screen.

5.4 Settings

WhereWhat
Party → New Game → Starting MembersThe new-game party (global only).
Party → DefeatDefeat Recovery HP Percent (default 0) and Defeat Recovery Min HP (default 1): HP fallen members regain after a story battle the party may lose.
ProgressionMax Level (99), the experience curve (Experience Base 15, Exponent 2, Per Level 0, optional Experience Curve), enemy experience, enemy level scaling and enemy stat growth.
BattleATB Party Size (default 4).
PactsSummon Resource (Resource.Resonance), initial CT and ATB fractions of a summon, Summon Placement Range (3 tiles), Backlash Can Defeat (off), Points Per Victory (10), Points Per Enemy Defeated (2), Award Fallen Members (off).
Party FieldThe visible party's follower rules (pace, drift, idle behaviours).
Character Actions (editor)The recruit flag root and tag source, and the enemy battle mode used by the one-click actions.

Per-Pact numbers (Resonance rates, summon turns, backlash) live on the Pact asset. The full lists are in Appendix B.

5.5 Blueprint usage

The party library is under RPG Saga → Party (nodes take a hidden World Context). The most used nodes:

TaskNodes
MembersGet Party Members, Is Party Member, Add Party Member, Remove Party Member, Restore Party
LevelsGet Level, Get Experience, Get Experience To Next Level, Add Experience, Add Experience To Party, Set Level
StatsGet Member Attribute, Get Member Attributes, Get Member Resource, Get Member Resource Max, Modify Member Resource, Get Member Vitals, Is Member KO
AbilitiesGet Member Abilities, Learn Ability, Forget Ability, Has Learned Ability, Get Learned Abilities
FormationGet ATB Formation, Get Tactics Roster, Is In ATB Formation, Set In ATB Formation, Get ATB Row, Set ATB Row, Get ATB Party Size
EquipmentGet Equipment, Get Equipped Item, Can Equip, Equip, Unequip, Get Equip Candidates, Preview Equip
PactsGet Owned Pacts, Give Pact, Has Pact, Can Bind Pact, Bind Pact, Unbind Pact, Get Bound Pact, Get Pact Holder, Get Pact Points, Award Pact Points, Can Learn Pact Ability, Learn Pact Ability, Get Learned Pact Abilities

Example 1: a treasure room that recruits a hero and gives the party experience.

  1. Event ActorBeginOverlap on your trigger volume.
  2. Add Party Member (Character = DA_Char_Wren). Branch on the returned bool: False means she was already in the party.
  3. Add Experience To Party (Amount = 200, Only Standing = true).

Example 2: show a level-up banner.

  1. In your HUD widget, Event Construct → Get Party Subsystem.
  2. Bind Event to On Ability Learned (your custom event shows "Character learned Ability").
  3. After awarding experience elsewhere, read the Add Experience return value (Level Up Result): Old Level, New Level and New Abilities.

Example 3: bind a Pact outside battle.

  1. Can Bind Pact (Character, Pact). On Ok, Bind Pact.
  2. Otherwise show the refusal reason: Not Owned, Not Main Character, Guest Character, Bound To Other Character or In Battle.

Result enums to know: ERSEFormationResult (Ok, NotMember, TacticsOnly, Full, LastActiveMember, InBattle), ERSEEquipResult, ERSEPactBindResult, ERSEPactLearnResult.

In data, the same changes are story effects: Add Member, Remove Member (with a departure kind), Restore Party, Set Level, Give Experience, Learn Ability, Forget Ability, and conditions Member In Party, Member Not KO. The party library has no story effect for giving a Pact: use the node Give Pact in a Custom (Blueprint) effect (override On Execute), or call it from your own graph. See Appendix A.

5.6 C++ usage

Read party state through the subsystem. Send changes as commands so single player, host and guests all work:

#include "Characters/RSEPartySubsystem.h"
#include "Characters/RSEPartyCommands.h"
#include "Commands/RSECommandSubsystem.h"

void RecruitHero(UGameInstance* GameInstance, URSECharacterData* Hero)
{
	if (URSECommandSubsystem* Bus = GameInstance->GetSubsystem<URSECommandSubsystem>())
	{
		FRSECmd_AddPartyMember Command;
		Command.Character = Hero;
		const FRSECommandResult Result = Bus->Submit(Command);
		if (Result.Status != ERSECommandStatus::Applied)
		{
			UE_LOG(LogTemp, Warning, TEXT("Recruit refused (status %d)"), static_cast<int32>(Result.Status));
		}
	}
}

int32 GetHeroLevel(const URSEPartySubsystem& Party, const URSECharacterData& Hero)
{
	return Party.GetState().GetLevel(Hero);
}

Gate on resources and stats with the subsystem:

const float HP = Party->GetMemberResource(Hero, RSEGameplayTags::Resource_HP);
const float MaxHP = Party->GetMemberResourceMax(Hero, RSEGameplayTags::Resource_HP);
const float Attack = Party->GetMemberAttribute(Hero, RSEGameplayTags::Stat_Attack);

Extension points:

  • A new party action is a new command struct derived from FRSEPartyStateCommand (override Validate, Execute and GetPermission) or from FRSECommand with a registered handler. Because it is a command, it works in co-op with no RPC code.
  • Your own state goes in its own save section, not in the party state (Core concepts).
  • Subscribe to OnMemberResourceChanged and OnAbilityLearned (both BlueprintAssignable) or, in C++, to FRSEPartyState::OnAbilityLearned().

5.7 Advanced

  • Per-character data you can add. Personal Modifiers take any stat modifier operation (Add, Percent, Multiply, Override, Clamp Min, Clamp Max). Use Override for a scripted boss phase and Clamp Max for a curse.
  • Presentation overrides. Presentation Overrides give a character its own look for an ability (a hero from a character pack swinging its own staff), and Attack Presentations with Attack Order (Random or Sequential) turn plain attacks into a combo. Presentation only: rules ignore them.
  • Per-character inventory. When the inventory mode is Per Character, Bag Size on the character or class sets each member's bag. See Items, inventory and economy.
  • Battle snapshots. SaveBattleSnapshot and RestoreBattleSnapshot give Retry. There is no saving or suspending during a battle.
  • Quiet settles. Setup writes (level start effects, rules applied) are not loot. Wrap them in FRSEQuietSettleScope so containers settle without toasts.
  • Co-op. In a session, each member is controlled by the companion AI, the host or a guest. Guests change only the equipment and Pacts of the member they play (host rule Guest Equipment). The visible party and delegated commands are in URSEPartyFieldSubsystem.
  • Simulating parties. The battle simulator, Balance My Campaign and the Progression Designer build party members with a typical build for the progression system in use, so balance stays valid whichever you choose.
  • Debug commands (development builds): RSE.Party.List, RSE.Party.Add <Character>, RSE.Party.Set <Character...>, RSE.Party.Restore [Name], RSE.Party.KO <Name>, RSE.Party.SetHP <Name> <HP>, RSE.Party.GiveExperience <Member|all> <Amount>, RSE.Party.SetLevel <Member|all> <Level>, RSE.Party.Levels.

5.8 Troubleshooting

SymptomCauseFix
A recruit cannot join ATB battlesRoster is Secondary (Tactics only)Make it Main, or use it only in Tactics.
Set In ATB Formation returns FullThe classic party is at ATB Party SizeRemove someone from the formation first, or raise Battle → ATB Party Size.
Set In ATB Formation returns Last Active MemberAt least one member must stay in the classic partyAdd the replacement before removing the last one.
A hero's equipment cannot be changedThe character is a GuestBy design; untick Guest for a permanent member.
A Pact will not bindNot owned, not a main character, guest, held elsewhere, or in battleRead the Pact Bind Result; give the Pact first (Give Pact) and bind outside battle.
A new-game party is emptyParty → Starting Members is emptyUse Add to Starting Party on a character or fill the list.
Equipment returned to the inventory when a member leftDeparture was PermanentUse Parallel Scenario for a member who will come back.
The enemy gives no experienceExperience Reward is 0 and the enemy formula gives 0Set the character's reward or Progression → Enemy Experience Base / Per Level.
A character shows grey placeholder shapesNo Appearance or no body installedSee Character visuals and animation.

5.9 See also