🛡️ Health — Shields¶
Shields intercept incoming damage before it reaches health.
They are opt-in, modular components that plug into HealthSystem
and participate in the damage pipeline after PRE rules and
before health mutation.
All gameplay shields implement IShield.
Many also implement IShieldPreview to support accurate damage previews.
📦 What Shields Are (and Aren’t)¶
Shields are - Damage interception layers - Victim-side protection systems - Fully compatible with rules, authority, DOT/HOT, and previews
Shields are not
- Rules (they do not run in PRE / POST phases)
- Health owners
- UI-only aggregates (see ShieldPool for aggregation utilities)
- Networking systems
Health works without shields — add them only where needed.
🧩 Built-in Shield Types¶
CapacityShield¶
A capacity-based shield pool that absorbs damage until depleted.
Behaviour - Absorbs damage up to current capacity - Breaks when capacity reaches zero - Optional flat and percent reduction applied before capacity consumption
Events
- ShieldDamaged(int absorbed)
- ShieldBroken()
- UnityEvent equivalents for designer hooks
Preview
- Implements IShieldPreview
- Accurately previews flat/percent reduction and remaining capacity
Typical Uses - Energy shields - Barrier spells - Temporary protection buffs
RechargeableShield¶
A capacity-based shield that regenerates over time.
Behaviour
- Any call to absorption refreshes the regen cooldown
- Regenerates via accumulated per-second ticks (frame-rate independent)
- Capacity-based absorption identical to CapacityShield
Fields
- maxCapacity
- regenDelay
- regenPerSecond
Events
- ShieldDamaged(int absorbed)
- ShieldBroken()
Preview
- Implements IShieldPreview (capacity-only preview)
Typical Uses - Sci‑fi shields - Rechargeable barriers - Regenerating armour layers
ReductionShield¶
A stateless mitigation shield.
Behaviour - Applies flat and percent reduction to every hit - Never breaks - No internal capacity
Events - None (pure reduction)
Preview
- Implements IShieldPreview (returns remainder after reduction)
Typical Uses - Armour plates - Passive resistances - Environmental mitigation
OverhealShield¶
A temporary HP pool that decays over time.
Behaviour - Soaks damage before real health - Decays gradually over time - Decay pauses briefly after damage or when temp HP is added - Decay behaviour and max temp can be adjusted at runtime via supported configuration seams
Configuration
- SetMaxTemp(int value, bool clampCurrent = true)
- ConfigureDecay(float perSecond, float delayAfterHit)
- SetUseUnscaledTime(bool value) (optional)
Inspector values define defaults; runtime calls may override them.
Events
- ShieldDamaged(int used)
- ShieldBroken()
Preview
- Implements IShieldPreview
Typical Uses - Overheal mechanics - Temporary buffs - RPG-style bonus HP
ShieldChain¶
Aggregator that runs multiple shields in sequence.
Behaviour - Executes shields in component (Inspector) order - Passes remaining damage to the next shield - Stops once damage is exhausted - Can optionally skip disabled shield components
Preview
- Implements IShieldPreview
- Uses per-shield previews where available
Typical Uses - Layered defences - Hybrid setups (reduction + capacity + overheal) - Composite boss shields
ShieldPool (Not an IShield)¶
A ticket-based shield value accumulator.
Important
- Does not implement IShield
- HealthSystem will never route damage through it
Purpose - Aggregation of shield values from many sources - UI display - Gameplay systems that need a combined total
Use instead
- CapacityShield, RechargeableShield, or OverhealShield for real absorption
🔄 Shield Execution Order¶
Within the damage pipeline:
PRE Damage Rules
→ Shields (IShield / ShieldChain)
→ HealthSystem.ApplyDamage
→ POST Damage Rules
If a shield fully absorbs damage:
- Health takes 0
- POST rules still execute with FinalApplied = 0
🧮 Preview Support¶
IShieldPreview enables non-mutating damage estimates.
Used by:
- HealthSystem.PreviewDamage(...)
- AI heuristics
- UI preview widgets
If a shield does not implement IShieldPreview:
- Preview assumes no absorption
- Live gameplay absorption still works
- UI/AI estimates may be pessimistic
Best practice:
Always implement IShieldPreview for gameplay shields.
🧠 Custom Shields¶
You can implement custom shields easily:
public class MyShield : MonoBehaviour, IShield, IShieldPreview
{
public bool TryAbsorb(ref int damage)
{
// mutate damage
return damage <= 0;
}
public int PreviewRemainder(int incoming)
{
// non-mutating preview
return incoming;
}
}
Tips
- Clamp inspector fields in OnValidate()
- Keep shields deterministic and side-effect free where possible
- Combine with ShieldChain for complex behaviour
❌ What Shields Should Not Do¶
- Do not modify health directly
- Do not implement gameplay rules
- Do not assume authority or networking
- Do not replace rule pipelines
- Do not encode UI logic
Shields exist to intercept damage — nothing else.