Vitals

Documentation Unreal Engine AI Vitals Health

Give a pawn resource pools: health that kills it at zero, stamina that refills on its own, and any other pool you name.


Health, stamina, poise, mana, ammo. One component holds them all, spends them, refills them on a timer, and tells the rest of the plugin the moment one runs out.

Set it up

45 seconds
  1. 1

    Find the Vitals component

    The plugin's enemy character ships with a SEC Vitals component already on it, carrying one row: Health at 100 with no regeneration. Open the enemy Blueprint and select Vitals in the Components list.
    On any other pawn, press Add Component and pick SEC Vitals.
  2. 2

    Set how much health it has

    Set Max Value on the Health row. The pool starts full, and the plugin's enemy takes melee damage into it with no wiring of your own.
    Vitals
    Vitals > Index [0]
    Vital Tag 
    Max Value100.0
    One row is one pool. Max Value is the whole first pass.
  3. 3

    Add a pool that refills itself

    Press + on the Vitals array for a second row. Point Vital Tag at SEC.Vital.Stamina and give it a regeneration rate and a delay. This one recovers 15 a second, starting 1.5 seconds after anything last touched it.
    Vitals
    Vitals > Index [1]
    Vital Tag 
    Max Value100.0
    Regen Rate Per Second0.0
    Regen Delay Seconds0.0
    Regen Delay Seconds is the pause after any change before the pool starts climbing again.
  4. 4

    Play, and watch the pools

    Press Play and run SEC.Debug.Vitals 1. Every pawn carrying vitals gets its pools above its head, value against maximum. Hit the enemy and Health drops; empty it and the AI shuts down.
A pool the pawn has no row for reads as nothing at all: a Vital Gate pointed at it passes, a Vital Scorer pointed at it scores flat, and health reads as full. Those readers say nothing in the log, so a mistyped tag, or a health pool renamed without updating Health Vital Tag in Project Settings, leaves an enemy that cannot be gated and cannot die. The write side is louder: Modify Vital, Drain Vital, Set Vital and Fill Vital each warn with the tag they could not find, and the damage path warns once per enemy class the first time a hit lands on a pawn carrying no health pool.

Author a pool

Each row in the Vitals array is one pool. A row needs a tag and a maximum; the rest is optional.
Details
SEC Vitals Component
Vitals
Vital Tag
SEC.Vital.Health
Max Value
100
Regen Rate Per Second
0
Regen Delay Seconds
0
Depleted Loose Tag
None
Depleted Result Tag
None
Depleted Gameplay Event
None
Default component on the enemy pawn, authored with one Health row at 100 and no regeneration. Add a row for stamina, stance, or any other pool.
FieldSets
Vital TagWhich pool this row is. SEC.Vital.Health, SEC.Vital.Stamina and SEC.Vital.Stance ship with the plugin, and any tag you author works the same way.
Max ValueThe pool's upper bound. The pool starts full. A row at 0 is skipped with a warning.
Regen Rate Per SecondHow fast the pool climbs back once the delay elapses, in units per second. 0 turns regeneration off.
Regen Delay SecondsSeconds after any change before the pool starts climbing; each change restarts the wait. 0 resumes in the same instant.
Depleted Loose TagHeld on the pawn's ability system while the pool sits at zero with no regeneration running. Dropped when regeneration starts or the pool refills.
Depleted Result TagAdded to the hit report on the exact blow that empties the pool, so the attack that broke it can answer with its own effect. Later hits on the empty pool do not add it again.
Depleted Gameplay EventSent to the pawn once per depletion, on the server. Skipped when the pawn has no ability system.
Two rows naming one tag keep the first. A pawn with an empty Vitals array carries no pools and does nothing.

Spend it, heal it, read it

These nodes change a pool. Each runs on the server; a client call is ignored with a warning.
NodeDoes
Modify VitalAdds or subtracts. A spend the pool cannot pay in full changes nothing and returns false, so one call is both the affordability check and the spend. A gain clamps at the maximum.
Drain VitalTakes up to the amount asked, floors at zero, and returns how much came off. A pool at 30 drained by 50 empties and returns 30.
Set VitalSets the pool, clamped between zero and the maximum. Restarts the regeneration delay even when the value does not move.
Fill VitalSets the pool to its maximum.
Five more read a pool. They work on any machine, at any time, and cost nothing to poll every frame.
NodeReturns
Get Vital ValueThe current value, regeneration included. 0 for a pool with no row.
Get Vital FractionThe same value as 0 to 1 of the maximum. Bind a bar to this.
Get Vital MaxThe authored maximum.
Has VitalWhether the pawn carries a row for the tag.
Is Vital DepletedWhether the pool sits at zero.
Regeneration's smooth rise fires no events. For a bar that climbs, poll Get Vital Fraction on Tick; for a bar that only redraws on a hit, bind On Vital Changed instead.

Make something happen when a pool empties

Three fields on the row cover the usual jobs, so a guard break or an exhaustion state needs no event graph at all.
  • Depleted Loose Tag holds a tag on the pawn while the pool is empty. Put that tag in an action's or a reaction's Block Tags and the move stops being available while the pool is spent.
  • Depleted Gameplay Event fires an ability directly. Point a stagger ability's activation at it and a stance pool at zero staggers the enemy.
  • Depleted Result Tag rides back on the blow that broke the pool, so the attacker can play a guard-break impact on that hit alone. See Melee Trace.
The loose tag and the gameplay event both go through the pawn's ability system, so a pawn without one gets neither. The result tag rides the hit report and needs no ability system.
For anything else, bind On Vital Depleted, which carries the tag of the pool that emptied.

Health, stamina, and death

Two tags in Project Settings, under Plugins → Soulslike Enemy Combat → Vitals, tell the AI which of your pools is which.
SettingDefaultDrives
Health Vital TagSEC.Vital.HealthDeath, the Health Scorer, and the health fraction the AI scores against.
Stamina Vital TagSEC.Vital.StaminaThe stamina value the AI reads, and the Stamina Gate.
An AI carrying no vitals component, or no row for the configured tag, reads as full health (1.0) and 100 stamina wherever those feed. That is why a health pool renamed without changing the setting produces an enemy that shrugs off everything.
Auto Handle Death On Health Depleted on the SEC Combat Controller component is on by default. The moment the health pool empties it stops the brain, cancels the running action and reaction, stops melee tracing, unregisters the combat role, clears focus, and broadcasts On Death. The pawn itself is left standing, ready for your ragdoll, dissolve or destroy. Untick it when a project drives death on its own trigger and calls Handle Death itself.

Bringing one back

Handle Revive puts a dead enemy back under AI control. Death unequips whatever it carried, dropping it when Drop Weapon On Death is ticked, so re-arm it afterwards with Equip Starting Loadout.


Cost and score actions against a pool

Two entries on an action's Scoring list read any pool by tag, alongside the other scorers and gates.
EntryDoes
Vital GateBlocks the action unless the pool holds at least Min Value. This is how a move declares its stamina cost. Tick Use Fraction to compare against 0 to 1 instead of raw units.
Vital ScorerFavours or disfavours the action as the pool rises or falls, shaped by a Range curve. Use Fraction is on by default, so an authored range survives a change to the pool's maximum.
A stamina-costed dodge is a Vital Gate on SEC.Vital.Stamina with Min Value 30. A desperate move that wants a low pool is a Vital Scorer with its range peaking near the bottom.
Both pass or score flat on a pawn that carries no row for the tag, so putting either in a shared Action Set does not disable an enemy type that lacks the pool. The same two work on reactions: see Reaction System.
A gate checks the pool. It does not spend it. Take the cost off in the ability that runs the move, with Modify Vital, or let a defensive answer charge it through Cost Vital Tag on the Defense System.

Debug it

SEC.Debug.Vitals 1        // Every pool above each pawn, value against maximum
SEC.Debug.All 1           // Every overlay section at once
SEC.Debug.WatchPawn Grunt // Narrow the overlays to one pawn by name
The overlay reads on a client as well as the server. To leave it on for one pawn without touching the console, tick Debug Overlay Vitals on that pawn's SEC Vitals component.
AdvancedNothing is spending or refilling
  • The tag has no row. Mutators do nothing and readers answer 0. Modify Vital, Drain Vital, Set Vital and Fill Vital each warn with the tag they could not find, so the log names the typo; Has Vital answers the same question in one node.
  • The call ran on a client. Modify, Drain, Set and Fill are server-only and log a warning when a client calls them. Route the spend through a server event, or let the ability that runs the move do it on the authority.
  • Max Value is 0. The row is skipped at BeginPlay with a warning in the log.
  • Regen Rate Per Second is 0. The pool holds wherever it was left.
  • Something keeps touching the pool. Every change restarts Regen Delay Seconds, so a pool nibbled at faster than its delay never starts climbing.
  • The Depleted Loose Tag is not appearing. It needs an ability system on the pawn, and it is dropped as soon as regeneration starts. A row with a rate above 0 and a delay of 0 begins recovering in the same instant it empties, so the tag is not held at all.
AdvancedDraining several pools in one call
An attack that takes health and stance together does it in one call. Drain Vitals takes a list of tag-and-amount rows and reports how much came off each, one entry per row that landed. A row naming a pool the target does not carry drops out in silence, and a row bigger than its pool reports what the pool had left.
Can Afford Vital Drain answers the same list before you commit: true when every pool named holds at least what the list asks of it. Rows naming one pool add up, so two rows of 30 against a pool of 50 answer false. An empty list is affordable.
The attack side of this is Additional Vital Damage on the Damage Config, one row per extra pool a swing drains beyond health. See Melee Trace.
AdvancedEvery vital event
EventFires
On Vital ChangedOn each discrete change: a spend, damage, a set or fill, or regeneration reaching the maximum. Carries the tag, the new value, the previous value and the maximum. Regeneration's rise between those points fires nothing.
On Vital DepletedOnce per depletion episode, not again until the pool recovers and empties anew. The Depleted Loose Tag is already applied when it fires.
On Vital FullWhen the pool reaches its maximum, by a gain or by regeneration finishing.
All three fire on the server and on clients, for the same transition on both sides.
MultiplayerMultiplayer: anchor replication and late-arriving ability systems
The server owns every value. Mutators run there and clients receive the result on their own.
Replication is anchor-based rather than per-tick: the server sends one record per discrete change, holding the value, the server timestamp it was written at, and the regeneration rate running from it. Every machine works out the current value by extrapolating that record against the shared server clock, so a regenerating bar renders smooth while costing no bandwidth between changes. Client UI polls Get Vital Value with no extra wiring.
Event edges derive from the raw record values on both sides, so the server and each client fire the same event for the same transition whatever the latency. Only the displayed value extrapolates.
Refresh Ability State re-applies the depleted tags after the pawn's ability system appears or changes. Single-player needs no call. In multiplayer, call it where a custom pawn initializes its ability system, since a PlayerState ability system arriving late would otherwise miss a tag applied before it existed. It is safe to call repeatedly.
The Vitals array is authored config, read at BeginPlay on every machine, and does not replicate. Only the runtime records do.
AdvancedReading the raw replication record
Get Vital Anchor copies the live record for a tag: the raw value, the server timestamp it was written at, and the regeneration rate running from it. It exists for debugging and tests. Gameplay reads Get Vital Value.