# Vitals

> Give a character resource pools: health that hits take, stamina that refills on its own, and any other pool you name, spent by moves, drained over time and read by a HUD.

Markdown version of https://rigbak.com/docs/universal-player-combat/vitals, a page of the Universal Player Combat documentation. Link that page when citing it.

## Set it up (2 minutes)

1. **Find the Vitals component**

   The UPC Character Base carries **UPC Vitals** (**VitalsComponent**) with one row, Health at 100, which hits drain with no wiring. On another pawn, add **UPC Vitals**; depleted tags and events also need an ability system on that pawn.
2. **Add stamina that refills itself**

   Press **+** on **Vitals** for a stamina row with a regeneration rate and a delay.

   In **VitalsComponent**, under Vitals > Index [1], set:

   | Property | Value |
   | --- | --- |
   | Vital Tag | UPC.Vital.Stamina |
   | Max Value | 100.0 |
   | Regen Rate Per Second | 15.0 (replaces 0.0) |
   | Regen Delay Seconds | 1.5 (replaces 0.0) |

   *15 a second, starting 1.5 seconds after anything last changed the pool.*
3. **Spend it on a move**

   On any node of your own graph, such as `AG_MySword`'s attack from [First Combo](https://rigbak.com/docs/universal-player-combat/first-combo), press **+** on **Costs** and pick **Vital**. The [Gates quick start](https://rigbak.com/docs/universal-player-combat/gates-costs-cooldowns) builds a `Dodge` node with this cost.

   In **AG_MySword**, under Costs > Index [ 0 ] (Vital), set:

   | Property | Value |
   | --- | --- |
   | Vital Tag | UPC.Vital.Stamina |
   | Amount | 25.0 (replaces 0.0) |

   *25 stamina per use. With less than 25 left, the move does not start.*
4. **Play, and watch the pools**

   Press Play and run `UPC.Debug.Vitals 1` to see each character's pools above its head. Use the move: stamina drops and climbs back.

> **Warning**
>
> A pool with no row reads as 0: a mistyped tag leaves a move that never runs, and a character with no Health row takes no damage. Keep that row when you edit **Vitals** on a Blueprint child.

---

## Author a pool

**Details panel: UPC Vitals** (component, in UPC Character Base (VitalsComponent))

**Category: Vitals**

| Property | Value |
| --- | --- |
| Vitals | 1 Array element |
| Vitals > Index [0] > Vital Tag | UPC.Vital.Health |
| Vitals > Index [0] > Max Value | 100 |
| Vitals > Index [0] > Regen Rate Per Second | 0 |
| Vitals > Index [0] > Regen Delay Seconds | 0 |
| Vitals > Index [0] > Depleted Loose Tag | None |
| Vitals > Index [0] > Depleted Result Tag | None |
| Vitals > Index [0] > Depleted Gameplay Event | None |

**Category: Vitals > Debug**

| Property | Value |
| --- | --- |
| Debug Overlay Vitals | false |

*Created on every character built on the UPC character base, with one Health row at 100 and no regeneration. Add a row for stamina, stance, or any other pool.*

| Field | Sets |
| --- | --- |
| **Vital Tag** | Which pool the row is. `UPC.Vital.Health`, `UPC.Vital.Stamina` and `UPC.Vital.Stance` ship; any tag works. |
| **Max Value** | The upper bound. The pool starts full; a row at 0 is skipped with a warning. |
| **Regen Rate Per Second** | How fast it climbs once the delay passes. 0 turns regeneration off. |
| **Regen Delay Seconds** | The wait after any change before it climbs; each change restarts it, and 0 climbs at once. |
| **Depleted Loose Tag** | A tag the character holds from the moment the pool empties until it starts to refill. Put it in a transition's **Blocked Tags** ([Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph#branch-on-more-than-the-button)) to shut a move while the pool is spent. |
| **Depleted Result Tag** | Added to the report of the hit that empties the pool, once, as [poise](https://rigbak.com/docs/universal-player-combat/hit-reactions#poise-flinch-only-when-it-breaks) uses it. |
| **Depleted Gameplay Event** | Sent to the character once per emptying, to start an ability: a stance at zero staggers the character. |

---

## Spend, heal and read

| Node | Does |
| --- | --- |
| **Modify Vital** | Adds or subtracts. A spend the pool cannot pay changes nothing and returns false, so one call checks and spends. A gain stops at the maximum. |
| **Drain Vital** | Takes up to the amount, stops at zero, and returns what came off. |
| **Set Vital**, **Fill Vital** | Set the pool, or fill it. |
| **Get Vital Value**, **Get Vital Fraction** | The current value, regeneration included, or 0 to 1 of the maximum for a bar. 0 for a pool with no row. |
| **Get Vital Max**, **Has Vital**, **Is Vital Depleted** | The maximum, whether the row exists, whether the pool sits at zero. |

The four that change a pool run on the server. The readers work anywhere and are cheap enough to poll each frame. Neither regeneration's climb nor a drain's fall fires an event as the value moves, so a smooth bar polls **Get Vital Fraction**; one that redraws per hit binds **On Vital Changed**.

For a channeled spell, **Start Vital Drain** drains a pool at a steady rate and returns a handle for **Stop Vital Drain**. Regeneration waits for the last drain on the pool to stop, then its delay starts over.

---

## When a pool empties

**On Vital Depleted** fires for any pool that empties, with its tag. With a **Depleted Loose Tag** set on the quick start's stamina, four 25-stamina moves empty it: **On Vital Depleted** fires and the tag goes on; 1.5 seconds later regeneration starts and the tag comes off.

An empty health pool leaves the character standing for your game to decide: a death belongs in **On Damage Taken**, whose **Was Fatal** marks the emptying hit ([Damage and Hit Effects](https://rigbak.com/docs/universal-player-combat/damage-and-hit-effects#how-a-character-takes-a-hit)). **Health Vital Tag** in the class defaults names the pool hits drain; change it and the row together to rename it.

---

## What reads a pool

| Where | Reads it to |
| --- | --- |
| A node's **Vital** cost | Pay to run the move. A negative **Amount** fills the pool, for a meter built per action. |
| A node's **Vital** gate | Allow the move only while the pool meets a level, spending nothing: a finisher at full meter. |
| A transition's **Vital Threshold** condition | Choose another move while the level is not met. |
| A node's **Drain Vital** hook | Drain at **Drain Rate Per Second** while the node runs; **End Behavior** says whether an empty pool keeps it running, finishes it or cuts it. |
| **UPC Sprint**'s **Stamina Vital** | Spend stamina while sprinting ([Sprint and Speed](https://rigbak.com/docs/universal-player-combat/sprint-and-speed)). |
| A defense response's **Cost Vital Tag** | Charge a raised guard ([Defense](https://rigbak.com/docs/universal-player-combat/defense)). |

[Gates, Costs and Cooldowns](https://rigbak.com/docs/universal-player-combat/gates-costs-cooldowns) covers the first three in full.

---

## Debug it

`UPC.Debug.Vitals 1` writes every pool above each character, on a client as well as the server.

<details>
<summary>Drains in detail (Advanced)</summary>

- A drained pool stops at zero and empties as any pool does (**On Vital Depleted**, the **Depleted Loose Tag**, the **Depleted Gameplay Event**); the drain runs on until stopped, so the pool stays empty.
- Two drains on one pool add up; stopping one leaves the other.
- A tag with no row, or a rate of 0 or less, starts nothing and returns a handle naming nothing; stopping it, or a stopped handle, does nothing.
- **Drain Vitals** takes a list of tag-and-amount rows, such as health and stance from one attack, and reports what came off each; a row naming a pool the character lacks drops out. **Can Afford Vital Drain** answers whether every pool holds what the list asks, rows naming one pool adding up. An attack names its extra pools in its damage config's **Additional Vital Damage**.

</details>

<details>
<summary>Every vital event (Advanced)</summary>

| Event | Fires |
| --- | --- |
| **On Vital Changed** | On each change: a spend, damage, a set or fill, regeneration reaching the maximum. Carries the tag, the new and previous value and the maximum. A drain fires nothing until it empties the pool. |
| **On Vital Depleted** | Once per emptying, again only after the pool recovers. The **Depleted Loose Tag** is on when it fires. |
| **On Vital Full** | When the pool reaches its maximum. |

</details>

<details>
<summary>What runs where (Multiplayer)</summary>

- The server owns every value; the change nodes run there and clients receive the result.
- Each change sends one record: the value, the server time it was written, and the rate running from it. Every machine extrapolates the current value against the shared server clock, so a bar stays smooth with no traffic between changes. **Get Vital Anchor** copies that record, for debugging and tests.
- Server and clients fire the same events for the same change, whatever the latency; only the displayed value extrapolates.
- **Refresh Ability State** puts the depleted tags back after the character's ability system appears or changes. **Notify Ability System Ready**, which the UPC Character Base sends, calls it; a pawn of your own with a late ability system on its PlayerState calls one of them. Repeat calls are safe.

</details>

<details>
<summary>Troubleshooting (Advanced)</summary>

**Nothing is spending or refilling**

- **The tag has no row.** Changes do nothing and readers answer 0; **Modify Vital**, **Drain Vital**, **Set Vital** and **Fill Vital** warn with the tag they could not find.
- **The call ran on a client.** The four change nodes do nothing there, and **Modify Vital** returns false as if the pool could not pay. Spend from a server event, or let a **Vital** cost on a node pay on the server.
- **Regen Rate Per Second is 0**, so the pool holds where it was left.
- **Something keeps touching the pool.** Each change restarts **Regen Delay Seconds**, a **Set Vital** to the same value included, so a pool nibbled faster than its delay never climbs.
- **A drain is running.** Regeneration waits until it stops.
- **The Depleted Loose Tag never shows.** It needs an ability system on the character, and goes as regeneration starts: with a rate above 0 and no delay, the pool recovers in the instant it empties.

</details>

Previous page: [Physical Reactions](https://rigbak.com/docs/universal-player-combat/physical-reactions). Next page: [Telegraphs](https://rigbak.com/docs/universal-player-combat/telegraphs)
