Skip to content

Enemies and AI

All · 15 min read

What the player sees: enemies patrol or wander, notice the party by sight, sound or ether, fight with an auto-attack and their own Arts, give up and walk home if you run far enough, and drop a chest when the last one of a group falls. A lvl.N label over each one is coloured by how dangerous it is compared with your party leader.

Everything that makes one enemy different from another (mesh, level, stats, Arts, loot, how it notices you) is a setting on its Blueprint or a data asset it points at. The AI that drives every enemy is shared, so a new enemy type needs no AI of its own: the enemy's data decides what it can do, and the shared AI decides when. An enemy fights with the same AI as a companion; only where its target comes from differs.

See the Glossary for Engage, disengage, Detection, Aggro, Squad and Pawn data.

What you can change

How it fits together

Piece Sample asset Job
Enemy pawn Characters/Enemies/Core/B_XenoCore_Enemy_Base → Characters/Enemies/Minion/B_XenoCore_Minion_Melee Level, name, stats, rewards, loot, death, overhead widgets
Pawn data PawnData_XenoCore_Minion_Melee Ability sets (and tag relationships) the enemy is initialised with
Ability sets AbilitySet_XenoCore_Enemy_Common, AbilitySet_XenoCore_Minion_Melee Death (common); auto-attack, hit react, Topple and Daze knock-downs, guard, recoil and dodge (minion)
Arts Characters/Enemies/Minion/Arts/DA_XenoCore_Minion_Rend, DA_XenoCore_Minion_Sweep Ordinary Art definitions on the enemy's Arts list. See Give an enemy Arts
Aggro Threat and Aggro Indicator components, built into every enemy Who the enemy attacks, and the red ring under that character. See Aggro
Anim Blueprint Characters/Enemies/Minion/ABP_XenoCore_Minion_Melee Locomotion on the 2D blend space Minion/Animations/BS_XenoCore_Minion_Locomotion2D
Stats effect Battle/Attributes/GE_XenoCore_BaseStats_Minion_Melee Statline read from CT_XenoCore_EnemyStats at the enemy's level
AI controller Characters/Enemies/Core/BP_AIC_XenoCore_Enemy Team, aggro target, leash, level rule; hosts the StateTree component
StateTree Characters/Enemies/Core/AI/ST_XenoCore_EnemyFreeroam Patrol, chase, auto-attack, choose and use Arts
Overhead widgets Characters/Enemies/Core/W_XenoCore_EnemyLabel, W_XenoCore_OverheadHealth lvl.N label and chevron over every enemy; HP bar while engaged
Spawner XenoCore Enemy Spawner in Place Actors Keeps one squad alive, links its aggro, respawns it out of sight. See Place enemies
Enemy types Characters/Enemies/Minion/Variants/ Seven sample types, each a child of B_XenoCore_Minion_Melee. See The sample enemy types
Drop table and chest Inventory/Loot/DA_XenoCore_Drops_Minion (the base minion), one table per family for the sample types (DA_XenoCore_Drops_Grunt, _Skirmisher, _Bulwark, _Brute), and BP_XenoCore_TreasureChest Entries can be limited to a band of the dying enemy's level. See Loot
Training dummy Characters/Enemies/Dummy/B_XenoCore_Dummy A target with no AI of note

Ability sets on the sample minion:

Ability Tag the AI uses Notes
GA_XenoCore_Minion_Attack Ability.XenoCore.AutoAttack Auto-attack. An Art pauses it; the fight task restarts it afterwards
GA_XenoCore_Minion_HitReact none Directional flinch
GA_XenoCore_Minion_Topple, GA_XenoCore_Minion_Daze none Knock-downs, triggered by the reaction tag arriving and held for as long as it lasts. See Reactions and statuses
GA_XenoCore_Minion_Guard, _Recoil, _Evade none Plays when the minion blocks, is blocked, or dodges. Clips retargeted onto the minion's skeleton. See Blocks and dodges
GA_Hero_Death (Lyra) none Death. Without it the enemy cannot die

The minion's two Arts are not in the ability set. They are Art definitions on the enemy Blueprint's Arts list, granted at level 1 when it spawns: the same kind of Art the party uses. Like a party Art, an enemy Art roots the enemy for the length of its animation.

Lifecycle

Spawn. The enemy receives the abilities in its Enemy Pawn Data and applies its Stats Effect at its Enemy Level. The controller records the pawn's start position as home and gives the pawn its team (2 by default). An enemy made by a spawner rolls its level from the spawner's range, and its home is where it spawned.

Waiting. Until it is provoked its aggro target is empty and the StateTree keeps it in Freeroam: it walks its Patrol Points back and forth at Patrol Speed (105 cm/s, its walk), pausing Patrol Wait (2 s) at each point; with no points it wanders within Wander Radius of home, or stands still if that is 0. A spawner sets the wander radius for its squad.

Noticing. An enemy is provoked by taking damage, or by its Detection:

Detection Provoked when…
None (passive) never; only damage provokes it
Sight the party leader is inside Sight Radius (1400) and the view cone (Sight Half Angle, 55°; 180 sees all round)
Sound the leader runs (faster than the controller's Running Speed, 280 cm/s) inside Sound Radius (1000). Walking past is safe
Ether the party uses an ether art inside Ether Radius (1500), even a harmless one

Detection obeys the level rule: an enemy Ignore When Levels Below (6) or more levels under the party leader does not notice the party at all. The rule never applies to being attacked: hit an under-levelled enemy and it fights back. A Unique Monster, or a controller with Always Aggro, skips the rule.

Link aggro. An enemy made by a spawner belongs to a squad. When one member is provoked, every living member within the spawner's Link Radius is provoked too. This is XC2/XC3's documented behaviour, chosen for XenoCore; XC1's own rule for groups is not sourced. Untick Link Aggro on a spawner for a loose group whose members fight only when each one is provoked.

Engaging. Once provoked, the controller's aggro target is the party member holding the most aggro on it (see Aggro), so a companion who hits harder than you can draw the enemy off. It engages while that pawn is within Engage Radius (1600). Once engaged, the radius grows by Disengage Radius Scale (2.5 ×) so the enemy does not flicker in and out at the edge. Each of these, and Leash Radius, is the controller's default unless the enemy sets its own override (below).

Fighting. The tree's Fight state chases the target, keeps the auto-attack swinging at it, and every Decision Interval scores the Arts on the enemy's Arts list, using the best one that is ready. Scoring is the companions' (see How a companion chooses an art): a Topple Art is held until the target is Broken, so the minion opens with Rend (Break) and follows with Sweep (Topple). Its AI Profile paces it; Post-Art Cooldown is the brake. When aggro moves to another party member, the enemy turns on them.

Moving. The minion's anim Blueprint plays a 2D blend space over Direction and Ground Speed, so it walks on patrol, jogs in a chase, and strafes or backs off with side and back clips while it shuffles round its attackers. A hit's knockback is not treated as movement: while the shove lasts the legs hold their pose and the body slides underneath, with the flinch on the torso.

Knocked down. While the enemy is Toppled or Dazed it plays its knock-down, stops chasing, does not auto-attack, and uses no Arts. It picks up where it left off when the reaction ends. A Dazed enemy gains no aggro.

Giving up. If the enemy strays more than Leash Radius (7000) from home, or the party outruns it (the target leaves the disengage radius), it disengages, forgets it was provoked and its aggro, recovers to full health (Heal On Give Up), and walks home at the chase task's return speed. It then resumes its patrol or wander. A party wipe does the same to every enemy at once. A Blueprint can do it to one enemy with the controller's Reset Aggro node (XenoCore › AI).

Dying. On death the enemy announces its defeat (see Events), awards the party EXP, Art Points and Skill Points through the progression component (Experience Reward, Art Point Reward and Skill Point Multiplier, scaled by level difference), rolls a chest tier and spawns the chest hidden for Chest Drop Delay, plays one of its Death Montages, ragdolls after a random Ragdoll Delay Min–Max, then vanishes after Death Vanish Delay with its Death Effect, if one is set (empty by default - the body simply disappears). The effect is a soft reference: it starts loading when the enemy is first provoked, so idle enemies on a map do not hold it in memory. In a squad, only the last member killed drops a chest, upgraded to at least silver. A spawner brings fallen members back after its Respawn Delay, only while the party is out of sight of the spot and not fighting that squad.

Widgets. Every enemy wears a lvl.N label with a chevron, coloured by how its level compares with the party leader's. It fades out with distance and is always shown in battle. A Unique Monster's label is gold, carries its name and shows from further away. The text, the colour bands and the distances are in Project Settings › Game › XenoCore Enemies › Level Label. The HP bar is hidden until the enemy is engaged. Neither widget costs anything while it has nothing to show: the label switches itself off beyond its fade distance (re-checked every Label Tick Check Interval, 0.4 s). While the enemy fights, a red ring lies under whoever it is after. No line is drawn between the enemy and its target. See Seeing who an enemy is after.

What you can change

On the enemy Blueprint (Class Defaults)

Settings marked per placement can also be changed on a placed enemy in the level.

Setting Category What it does
Enemy Pawn Data XenoCore › Enemy Ability sets. Required: empty logs an error and the enemy cannot die
Enemy Level XenoCore › Enemy Level for every stat curve and the level-difference rules. Per placement
Display Name XenoCore › Enemy Name on the target badge. Per placement
Unique Monster XenoCore › Enemy Skips the level rule; gold, named label. Tick Always Gold Chest too. Per placement
Detection, Sight Radius, Sight Half Angle, Sound Radius, Ether Radius XenoCore › AI › Detection How it notices the party before being hit (table above). Per placement
Wander Radius XenoCore › AI › Patrol With no Patrol Points: wander this far from home. 0 = stand still. A spawner overrides it. Per placement
Experience Reward XenoCore › Enemy Base EXP before level-difference scaling. A new enemy class starts at 24; the sample minions pay 15 (a basic Grunt, XC1's first field enemy) up to 50 (Violet Brute). Per placement
Experience Level Scale XenoCore › Enemy Curve row multiplying Experience Reward at Enemy Level. The minions use Minion.ExperienceScale (XC1's EXP-to-next ÷ 40: ×1 at Lv 1, ×3.75 at Lv 10). Empty = flat
Skill Point Multiplier XenoCore › Enemy Scales the SP this kill pays. Per placement
Art Point Reward XenoCore › Enemy Art Points this kill pays before level-difference scaling. -1 (default) uses XC1's 2 × level + 2. Set it for a boss. Per placement
Stats Effect XenoCore › Enemy Statline effect applied at Enemy Level
Chevron Widget Class, Chevron Height, Label Height XenoCore › Enemy The marker and its height (132), and the height of the bottom of the lvl.N label (112)
Health Bar Widget Class, Health Bar Height XenoCore › Enemy The engaged HP bar and its height (100)
Label Tick Check Interval XenoCore › Enemy How often the enemy decides whether its label needs to tick. Default 0.4 s
Drop Table, Chest Class, Chest Spawn Height XenoCore › Loot See Loot. Empty Drop Table = no chest
Always Gold Chest XenoCore › Loot Always drop gold. Per placement
Chest Drop Delay XenoCore › Enemy › Loot Seconds before the chest appears. Per placement
Death Montages, Ragdoll Delay Min/Max, Ragdoll Impulse Bone/Strength, Death Vanish Delay, Death Effect, Death Effect Scale XenoCore › Death The death sequence. Death Effect loads when the enemy is provoked
Engage Radius Override XenoCore › AI This enemy's engage radius, in cm. -1 (default) uses the controller's. Per placement
Leash Radius Override XenoCore › AI This enemy's leash radius. -1 uses the controller's. Per placement
Disengage Radius Scale Override XenoCore › AI This enemy's disengage scale. -1 uses the controller's; 0 to 1 counts as 1. Per placement
Patrol Points XenoCore › AI › Patrol Points to walk between while unprovoked, relative to where the enemy was placed. Drag them in the viewport. Empty = stand at home. Per placement
Patrol Speed XenoCore › AI › Patrol Walking speed on patrol. Default 105 cm/s, matched to the minion's walk clip. Per placement
Patrol Wait XenoCore › AI › Patrol Seconds it pauses at each point of the route, ends included. Default 2. Per placement
Arts XenoCore › Enemy › Arts Art definitions this enemy can use, granted at level 1. Per placement
AI Profile XenoCore › Enemy › Arts Decision interval, post-art cooldown, reliability. Seek Positional Bonus is off for enemies. Per placement
Anim Profile XenoCore › Animation This enemy's own reaction and death clips. See Give a character its own combat animations

On the AI controller (BP_AIC_XenoCore_Enemy, Class Defaults)

Setting Category What it does
Engage Radius XenoCore › AI How close the target must be to fight. Default 1600
Leash Radius XenoCore › AI Distance from home at which the enemy gives up. Default 7000
Disengage Radius Scale XenoCore › AI Engage radius multiplier once fighting. Default 2.5
Ignore When Levels Below XenoCore › AI Ignore a party this many levels higher. Default 6
Always Aggro XenoCore › AI Skip the level rule. Noticing the party still needs a Detection other than None
Running Speed XenoCore › AI › Detection Leader speed above which Sound detection hears it. Default 280
Detection Interval XenoCore › AI › Detection How often, in seconds, the enemy checks whether it has noticed the party. Default 0.2
Heal On Give Up XenoCore › AI Restore full health when the enemy gives up a fight. Default on
Team Id XenoCore › Teams Team the pawn joins. Default 2

The three radii here are the defaults for every enemy the controller possesses. One enemy type, or one placed enemy, can differ through its own … Override settings above, with no new controller. -1 means "use the controller's"; 0 is a real value (an engage radius of 0 never engages, even when provoked). An override changed while the game runs applies on the next check. In a Blueprint, Get Effective Engage Radius, Get Effective Leash Radius and Get Effective Disengage Radius Scale on the controller return the values in force.

In the StateTree

The tree ST_XenoCore_EnemyFreeroam has two states:

State Entered when Runs
Fight The controller has an aggro target XenoCore Chase Aggro Target, XenoCore Fight Target, XenoCore Use Best Art
Freeroam It has none XenoCore Enemy Patrol
Node Parameters What it does
XenoCore Has Aggro Target (condition) Invert The controller has a target
XenoCore Chase Aggro Target (task) Acceptable Radius (140), Repath Interval, Chase Speed (380), Return Speed (150), Home Tolerance Chases, then walks home when the target is gone
XenoCore Fight Target (task) Retry Interval Keeps the auto-attack swinging at the target; never restarts it under an Art
XenoCore Use Best Art (task) none Scores and uses the enemy's Arts, paced by its AI Profile
XenoCore Enemy Patrol (task) none Walks the enemy's Patrol Points back and forth; hands over to Fight the moment the enemy is provoked

The tree reads its numbers from the enemy (patrol route, Arts, AI Profile), so one tree serves every enemy type. The older nodes XenoCore In Attack Range, XenoCore Ability Ready, XenoCore Target Has Tag and XenoCore Activate Ability By Tag are still available for a tree of your own.

Fails silently: an enemy Art that borrows the auto-attack's montage

Using an Art stops the auto-attack's swing by montage. An Art playing the same montage asset is stopped on its first frame: no hit, nothing logged. Give every Art its own montage copy.

Fails silently: a Stats Effect using Add

Every modifier on a stats effect must use Override. Re-applying it on a level change would otherwise stack the numbers.

The enemy won't fight

Check, in order: its Detection (None waits to be hit; Sound only hears running); is it 6 or more levels below the party leader (then it notices nothing, but still fights back when hit); is it further than Engage Radius.

The sample enemy types

The seven types in Characters/Enemies/Minion/Variants/ are empty child Blueprints of B_XenoCore_Minion_Melee. They change only class defaults (name, detection, mesh, material, stats effect, drop table, rewards), so every fix to the minion reaches all of them.

Blueprint Name Detection Body
B_XenoCore_Minion_Grunt Plains Grunt Sound Melee
B_XenoCore_Minion_Grunt_Rust Rust Grunt Sight Melee, rust skin
B_XenoCore_Minion_Skirmisher Skirmisher Sight Ranged
B_XenoCore_Minion_Skirmisher_Jade Jade Skirmisher Ether Ranged, jade skin
B_XenoCore_Minion_Bulwark Bulwark None (passive) Siege
B_XenoCore_Minion_Brute Brute Sight Super
B_XenoCore_Minion_Brute_Violet Violet Brute Sight, all round Super, violet skin

Skins are material instances of the minion material, not new textures. The ranged, siege and super bodies are on skeletons that share the melee body's bone chain and are marked compatible with SK_Minion_Core, so they run the melee minion's anim Blueprint, montages, abilities and Arts unchanged. The tougher types use their own stats effects (GE_XenoCore_BaseStats_Minion_Skirmisher, _Bulwark, _Brute), which read the same Minion_Melee.* rows of CT_XenoCore_EnemyStats times per-type multipliers on the effect: Strength ×0.9, ×1.15 and ×1.45, and HP ×0.8, ×1.9 and ×3.0, for Skirmisher, Bulwark and Brute (each also shifts Agility, and Ether or the defences). The rows themselves are anchored on an early XC1 field enemy: a level 1 minion has 900 HP and 69 Strength, plus 100 HP and 10 Strength a level.

Extending it

  • A new enemy type: right-click B_XenoCore_Minion_Melee and choose Create Child Blueprint Class, in your own folder, as the seven sample types do. Duplicate its pawn data, ability set and stats effect only if it needs different ones (those are data assets). See Your first enemy, Add an enemy, Enemy statline and Place enemies.
  • Different Arts: put different Art definitions on the enemy's Arts list, and steer them with each Art's Companion AI settings. See Give an enemy Arts.
  • A squad: place a XenoCore Enemy Spawner. See Place enemies.
  • A patrol: set Patrol Points on a hand-placed enemy. See Place enemies.
  • A unique monster: tick Unique Monster on a spawner (with a Unique Name) or on a placed enemy, and override Enemy Level, Experience Reward and Always Gold Chest as needed.
  • Never edit B_XenoCore_Enemy_Base, BP_AIC_XenoCore_Enemy or the shared StateTree in place.
For programmers: a C++ enemy

AXenoCoreEnemyCharacter and AXenoCoreEnemyController are exported, so your own module can subclass them. Enemies do not derive from AXenoCoreCombatantCharacter (the party's base); both derive from Lyra's ALyraCharacterWithAbilities. The pawn owns its own Ability System Component and has no PlayerState.

Why it's built this way

For programmers
  • No PlayerState. Lyra's PlayerState route would give every enemy the experience's default pawn data (the player's kit), because the only per-pawn hook, ALyraGameMode::GetPawnDataForController, is not virtual. Deriving from ALyraCharacterWithAbilities gives the pawn its own ASC. It is the same shape as Lyra's own B_ShootingTarget, and it lets enemies simply be placed in a level.
  • Two small C++ classes. The pawn exists to call InitializeAbilitySystem, which is not a UFUNCTION; without it the health component never initialises. The controller exists because Lyra's team interface cannot be implemented in Blueprint, and a pawn's team must come from its controller.
  • Level on the instance. Ability sets apply effects at a level fixed on the asset, so a per-placement level needs its own stats effect path.
  • Data, not states, in the tree. One tree serves every enemy. What an enemy can do is on the enemy (its Arts and AI Profile), and cooldowns are asked of GAS rather than duplicated in the tree.
  • One AI for both sides. Enemies and companions share the fight and art tasks, so an Art behaves the same whoever uses it.