Skip to content

📈 Health — Max Health Modifiers

📦 Folder Overview

This folder contains runtime helpers that modify effective max health for a co-located HealthSystem.

These components provide stackable, reversible max-health adjustments without modifying core systems.


🎯 Purpose

Max-health modifiers provide:

  • Flat and multiplier-based max-health changes
  • Safe stacking of multiple contributors
  • Stable recomputation from a baseline value

🧩 What Lives Here

MaxHealthModifierStack

MonoBehaviour that requires a co-located HealthSystem.

Supports:

  • Flat modifiers
  • Multiplier modifiers
  • Combined flat and multiplier entries
  • Baseline rebasing
  • Scoped add/remove usage

⚠️ Important Notes

Effective Max Calculation

Effective max health is computed as:

round(baseline * productOfMultipliers) + sumOfFlats

The result is floored to at least 1.


Multiplier Semantics

  • 1.00 → no change
  • 1.20 → +20%
  • 0.75 → -25%
  • 0.00 → collapses multiplier before final floor safeguard

Baseline Model

Modifiers are applied relative to a baseline value.

Baseline can be set via:

  • Auto capture on awake
  • CaptureBaselineFromCurrent()
  • SetBaseline(int)
  • RebaseToCurrent()

The baseline is not the current effective max.

This ensures:

  • Stable add/remove behaviour
  • Order-independent removal
  • Safe coexistence of multiple systems

Clamp Modes

Modifiers apply results using one of three modes:

Silent

  • Updates max health without emitting events

WithEvents

  • May trigger damage-style events or death when clamping

ClampNoDeathEvents

  • Clamps safely without triggering damage or death events

Runtime API

Add modifiers:

int id1 = stack.PushFlat(25);
int id2 = stack.PushPercentMultiplier(1.20f);
int id3 = stack.Push(10, 0.90f);

Remove modifiers:

stack.Remove(id1);

Clear all:

stack.ClearAll();

Reapply:

stack.Reapply();

Scoped Usage

using var scope = stack.PushScoped(25, 1.0f, out int id);
  • Removes modifier automatically on dispose
  • Allocates a small object (avoid in hot paths)

Behaviour

  • Reapply occurs automatically on state changes
  • OnEnable() triggers reapply
  • Baseline is ensured when pushing entries
  • No-op if HealthSystem is missing or component is disabled

Boundaries

Do not:

  • Treat this as a handler
  • Use it as a rules replacement
  • Mutate HealthSystem.Max alongside it
  • Treat multipliers as additive percentages
  • Use scoped modifiers in hot loops

🧠 Usage Guidance

  • Use for stat-style max-health changes
  • Prefer stack-based operations over direct mutation
  • Keep baseline consistent for predictable results

  • Health System
  • Rules
  • Handlers
  • Effects