🧠 Health System — Mental Model¶
This document explains how to think about the RevFramework Health system.
If you understand this page, you understand the architecture.
🧱 The Core Principle¶
Health has one central responsibility:
Own HP state and coordinate supported health mutation.
HealthSystem is the host responsible for:
- owning
CurrentandMax - running the supported mutation pipeline
- integrating shields, rules, authority, and lifecycle hooks
- finalizing damage and healing outcomes
- emitting events and reports
Everything else in the system is layered around this responsibility.
🔐 HP Ownership¶
Only HealthSystem performs direct HP mutation.
Other components influence or trigger mutation through supported APIs, but never modify HP state directly.
| Component | Can mutate HP directly? |
|---|---|
| Authority | ❌ |
| Rules | ❌ |
| Shields | ❌ |
| Effects | ❌ |
| Handlers | ✔ (via supported APIs only) |
| HealthSystem | ✔ |
This rule guarantees that all HP mutation flows through the same pipeline.
🔄 Damage Mental Model (True Order)¶
When damage is applied:
DamageContext created
↓
Authority gate (optional; runs before PRE rules)
↓
State guards
- dead check
- invincibility
- damage lock
↓
PRE Damage Rules (ordered by Priority)
- mutate RawAmount / Multiplier / FlatDelta
- may Cancel
↓
Damage evaluation
(RawAmount * Multiplier + FlatDelta)
↓
Shields (IShield)
- absorb or reduce damage
- skipped if BypassShields == true
↓
HP mutation (Current -= applied)
↓
POST Damage Observers
- observe finalized outcome
↓
Death interception (IBeforeDeathHandler)
↓
Death pipeline
- IHealthDeathHandler
- UnityEvents
- C# event (Died)
Important details:
- PRE rules change how much damage happens.
- Shields change whether HP is touched.
HealthSystemis the only thing that mutates HP.- POST observers must not modify the current damage outcome.
However:
POST observers may trigger new mutations through supported Health APIs.
Those mutations run through a completely new damage or heal pipeline.
Additional clarification:
In the default
HealthSystem, POST damage observers run after HP mutation but before death finalization.
💚 Heal Mental Model¶
When healing is applied:
Authority gate (optional)
↓
State guards (dead check)
↓
PRE Heal Rules (ordered)
- mutate Multiplier / FlatDelta
- may Cancel
↓
Damage evaluation
↓
Healing Modifiers (IHealingModifier)
↓
HP mutation (Current += applied)
↓
Optional overheal spill (OverhealShield)
↓
POST Heal Observers
Important:
- Healing modifiers run after heal rules but before HP mutation.
- Healing modifiers stack multiplicatively.
- Heal rules and modifiers may reduce healing to zero.
- Lifecycle calls (
Revive,SetCurrent, etc.) intentionally bypass the heal rule pipeline.
🧩 Extension Point Responsibilities¶
| Layer | Can mutate HP? | Can change outcome? | Purpose |
|---|---|---|---|
| Authority | ❌ | ✔ | Block mutation entirely |
| PRE Rules | ❌ | ✔ | Modify damage/heal math or cancel |
| Shields | ❌ | ✔ | Intercept damage before HP |
| HealthSystem | ✔ | ✔ | Own HP state and finalize mutation pipeline |
| POST Rules | ❌ | ❌ (current attempt) | Observe finalized outcome |
| Handlers | ✔ (via supported APIs only) | ✔ | Lifecycle / coordination |
Additional clarification:
Not all handlers alter outcomes.
IBeforeDeathHandlercan cancel death, while most handlers are lifecycle or side‑effect components.
Handlers must never mutate HP fields directly and must use supported Health APIs.
🛡 Shields vs Rules¶
Rules change damage/heal calculation.
Shields change damage interception.
Use the following guideline:
| Behaviour | Implementation |
|---|---|
| Resistances | Rule |
| Crit | Rule |
| Execute | Rule |
| Damage cap | Rule |
| Reflect | POST Rule |
| Capacity-based absorption | Shield |
| Regenerating barrier | Shield |
| Temporary HP | Shield |
🌐 Authority Mental Model¶
Authority answers one question:
"Is mutation allowed right now?"
It runs before PRE rules.
Authority does not:
- replicate state
- define networking ownership
- perform transport
- implement prediction
If authority denies mutation:
No PRE rules run
No shields run
No HP mutation happens
The attempt is rejected immediately.
⚰ Death Model¶
Death is idempotent.
When HP reaches zero:
BeforeDeathHandlers (may cancel)
↓
DeathHandler (side effects)
↓
UnityEvents
↓
C# event (Died)
Only IBeforeDeathHandler can cancel death.
If death is cancelled:
- the handler must restore a valid alive state
- the death pipeline stops
Death will only finalize once unless the state is restored to alive.
⚠️ Some direct mutation operations (e.g. silent setters or snapshot restore) may set a dead state without triggering the full death pipeline.
💾 Snapshot Model¶
Snapshots capture only the core HP state.
Max
Current
Dead
Snapshots intentionally do not restore:
- shields
- regeneration timers
- DOT/HOT effects
- rule state
- external components
Snapshots are designed for save/load and respawn initialization, not full system restoration.
🔁 Mutation Model¶
Every health mutation follows the same structure:
1️⃣ Evaluate whether mutation is allowed
2️⃣ Transform the requested mutation
3️⃣ Apply the mutation
4️⃣ Notify observers
Damage, healing, and lifecycle operations all follow this structure.
This ensures gameplay systems interact with Health in a predictable way.
🧠 The Big Rule¶
If something:
| Behaviour | Correct Extension |
|---|---|
| Changes damage math | Rule |
| Intercepts damage | Shield |
| Changes max/current directly | HealthSystem API |
| Reacts to damage/heal | POST Rule |
| Coordinates lifecycle | Handler |
| Blocks mutation | Authority |
Following this separation keeps the system stable and predictable.
❌ What Breaks the Model¶
The following patterns violate the design model:
- Mutating HP outside
HealthSystem - Writing gameplay logic inside Authority
- Using POST rules to change math
- Treating
ShieldPoolas an actual shield - Assuming preview results equal final outcomes
- Assuming every optional companion component participates automatically
🔗 Related Docs¶
- Public API
- Rules
- Shields
- Handlers
- Authority