Skip to content

Set an enemy's statline

Designer · 30 min · No code

Result: your enemy type has its own HP, Strength, Ether, Agility and defences at every level, from your own curve table, so one number on a placed enemy (its level) sets all of them.

Before you start

How an enemy gets its stats

  1. The enemy Blueprint's Stats Effect (Class Defaults, under XenoCore › Enemy) names a gameplay effect.
  2. When the enemy spawns, that effect is applied at the enemy's Enemy Level.
  3. Each modifier in the effect reads one row of a curve table at that level, and overrides one attribute with the result.
  4. The enemy's level attribute itself is set straight from Enemy Level.

The sample is Battle/Attributes/GE_XenoCore_BaseStats_Minion_Melee, reading rows Minion_Melee.* from Battle/Attributes/CT_XenoCore_EnemyStats. Enemy stats rise in a straight line with level. The melee minion's HP and Strength follow an XC1 Colony 9 field enemy (HP 900 + 100 per level, Strength 69 + 10 per level); its other rows are placeholders to be tuned for your game.

The other minion types (Brute, Bulwark, Skirmisher) have their own effects that read the same Minion_Melee.* rows and multiply them: each modifier's coefficient Value is that type's multiplier (Strength: Melee 1.0, Brute 1.45, Bulwark 1.15, Skirmisher 0.9). That is how one table row serves several enemy types.

What each stat means on an enemy

Enemy stats are read differently from party stats. This is intended.

Row Attribute On an enemy
MaxHealth Health and Max Health HP. The effect sets both from this one row, so it spawns at full health.
Strength Strength Damage of its physical attacks: Strength − the target's Physical Defence
Ether Ether Damage of ether attacks. The shipped enemies have none.
Agility Agility Hit and evade chance. Each point of difference from the party is 1%.
PhysicalDefence Physical Defence A fraction, 0 to 0.9. 0.2 takes 20% off the party's physical hits.
EtherDefence Ether Defence A fraction, like Physical Defence

On party members the two defences are flat points; on enemies they are fractions. Never copy a party defence value onto an enemy.

Steps

1. Make your curve table

The easiest route is a spreadsheet saved as CSV. The first column is the row name, and the header row holds the levels:

Name,1,99
Golem.MaxHealth,300,30000
Golem.Strength,40,900
Golem.Ether,0,0
Golem.Agility,8,120
Golem.PhysicalDefence,0.1,0.4
Golem.EtherDefence,0.05,0.3

Two columns are enough: with linear interpolation, level 50 falls on the straight line between them.

  1. Save it as CT_MyGame_EnemyStats.csv.
  2. Drag it into MyGame/Enemies in the Content Browser.
  3. In the import dialog, set Import As to CurveTable (it opens on DataTable) and Choose Curve Interpolation Type to Linear, then click Apply.
  4. Double-click the new asset and check the rows.

You can also duplicate Battle/Attributes/CT_XenoCore_EnemyStats and edit its cells in the curve table editor. It already has rows for Minion_Melee, Minion_Ranged, Minion_Siege and Minion_Super, plus Minion.ExperienceScale (see EXP for a kill).

Change the numbers by re-importing the CSV

Re-import an edited CSV over your own curve table (right-click › Reimport) rather than deleting and re-creating it. It stays the same asset, so every stats effect pointing at it keeps working. On a duplicate of a shipped table, use Reimport With New File instead: the shipped tables remember a source file that is not on your machine.

2. Point your stats effect at it

  1. In Plugins › XenoCore Content › Battle › Attributes, right-click GE_XenoCore_BaseStats_Minion_Melee, choose Duplicate, move the copy into MyGame/Enemies and name it GE_MyGame_BaseStats_Golem.
  2. Open it and expand Modifiers.
  3. For every modifier, keep Modifier Op as Override.
  4. For every modifier, under Scalable Float Magnitude, set Curve Table to CT_MyGame_EnemyStats and Row Name to the matching Golem.* row.
  5. For every modifier, set the coefficient Value to 1.0, unless you want this type to scale another type's rows.
  6. Click Compile, then Save.

Fails silently: a coefficient you did not mean

The coefficient Value multiplies the curve row, and nothing on the table shows it. If you duplicated the Brute, Bulwark or Skirmisher effect, your copy carries that type's multiplier (for example Strength ×1.45). Set Value to 1.0 on every modifier unless you meant it.

Fails silently: Add instead of Override

Every modifier must be Override. With Add, applying the effect again stacks the numbers on top of the old ones.

3. Use it

  1. Open your enemy Blueprint and click Class Defaults.
  2. Under XenoCore › Enemy, set Stats Effect to GE_MyGame_BaseStats_Golem.
  3. Click Compile, then Save.

4. EXP for a kill

Two settings on the enemy Blueprint's Class Defaults, under XenoCore › Enemy (both can also be changed on a placed enemy):

Setting What it does
Experience Reward The type's base EXP. A Brute is worth more than a Grunt at the same level. Shipped minions pay 15 to 50.
Experience Level Scale A curve row that multiplies Experience Reward at the enemy's level: pick a Curve Table and a Row Name. The minions use CT_XenoCore_EnemyStats › Minion.ExperienceScale. Empty = the same EXP at every level.

The party's level difference from the enemy then scales the result again.

5. Balance against the party

Three numbers decide how a fight feels:

  • Enemy Strength against party defence. Party defence is flat points summed from armour. If a full set of armour approaches an enemy's Strength, that enemy barely scratches the party.
  • Agility difference. Hit chance is 100% plus the attacker's Agility minus the defender's, one percent per point, never below 5% (Agility Hit Per Point and Hit Chance Floor on Battle/Attributes/BP_XenoCoreDamageExecution). Armour Weight comes off the wearer's Agility for this roll.
  • Level difference. Damage in both directions is scaled by the gap between the two levels, from Battle/Attributes/CT_XenoCore_DamageLevelDiff. A few levels matter a lot.

Test it

  1. Place the enemy in Maps/L_XenoCore_Gym at Enemy Level 1, and a second one at 99.
  2. Press Play. Open the console (~) and enter Log LogXenoDamage Verbose.
  3. Let each hit you. The Output Log's damage line shows stat= for each, matching your curve at those levels.
  4. Lock on (target mode): the level-99 enemy's health bar drains far slower.

If it doesn't work

Fails silently: a row name typo

A modifier whose Row Name does not exist in the table evaluates to 0. The enemy spawns with 0 in that stat and no error shows in game. Open the effect and check each row is found.

Symptom Fix
All stats are 0 and it dies in one hit Stats Effect is empty. The Output Log says the enemy "has no StatsEffect".
One type's stats are a multiple of what the table says The modifier's coefficient Value is not 1.0 (see the warning in step 2).
Stats stack up higher every time A modifier is Add instead of Override.
Changing Enemy Level during play does nothing The level is read once, when the enemy spawns. A spawner sets it before then; a Blueprint can re-level a live enemy with Set Enemy Level (XenoCore › Enemy), which also heals it to full.

Going further