Buff & Status Effect Manager

v1.2.2

Core Concepts

Understand the fundamental concepts of the Buff & Status Effect Manager.

Status Effects

A Status Effect is any temporary or permanent modifier applied to an entity. This includes buffs (positive effects), debuffs (negative effects), and crowd control (movement/action restrictions).

Buffs

Positive effects like healing, speed boosts, damage increases, shields.

Debuffs

Negative effects like poison, curses, stat reductions, DoT damage.

Crowd Control

Movement/action restrictions like stun, freeze, silence, root.

Each effect is defined by a StatusEffectDefinitionScriptableObject asset. At runtime, when applied to a target, an instance is created with its own duration timer, stack count, and tick tracker.

Categories

Categories group related effects together and provide shared configuration like UI colors and concurrent limits.

Category Properties

Display NameName shown in UI
Category TypeBuff, Debuff, or CrowdControl
ColorUI tint color for icons
Max ConcurrentMax active effects of this category (0 = unlimited)
Replace OldestWhen at limit, replace oldest effect?
ExclusiveOnly one effect of this category at a time; the higher Priority wins (v1.2)
Equal Priority ReplacesWhen Exclusive: does an equal Priority replace (true) or get blocked (false)?

Duration Modes

Timed

Effect expires automatically after the specified duration. Most common for buffs and debuffs.

Duration: 10 seconds

Permanent

Effect never expires on its own. Must be manually removed via dispel, cleanse, or API call. Useful for auras, passive abilities, and persistent states.

Stacking Rules

Defines what happens when the same effect is applied to a target that already has it active.

ModeBehaviorUse Case
NoneApplication rejected if already activeUnique buffs, toggles
StackAdds a stack (up to max), independent timersBleed, combo points
RefreshResets duration to full, no stackingStandard buffs/debuffs
RefreshAndStackResets duration AND adds a stackStacking poisons
ExtendAdds the full duration on top of the remaining time (no cap)Extendable shields
Scale with Stacks: Enable this option to multiply stat modifiers and tick damage by the current stack count. Perfect for ramping effects like bleed.

Tick System

The tick system handles periodic events like damage over time, healing over time, or any repeating logic during an effect's lifetime.

Tick Configuration

Has TickEnable periodic tick events
Tick IntervalSeconds between ticks (e.g., 1.0)
Tick On ApplyFire first tick immediately on application
Max TicksLimit total ticks (0 = unlimited until duration expires)

Subscribe to the OnEffectTicked event or use the GC2 Event On Any Effect Ticked to execute logic on each tick.

Immunity System

The immunity system prevents certain effects from being applied to a target. Supports both permanent and temporary immunities.

Permanent Immunity

Defined via ImmunityProfile ScriptableObject. Assign to StatusEffectManager.

  • • Immune to specific effects
  • • Immune to entire categories
  • • Immune to effects with specific tags

Temporary Immunity

Granted at runtime via API or Visual Scripting. Expires after a specified duration.

  • • AddTemporaryImmunity(effect, duration)
  • • AddTemporaryImmunityByCategory(cat, duration)
  • • AddTemporaryImmunityByTag(tag, duration)

Cooldown System

Cooldowns prevent effects from being re-applied too quickly. Perfect for balancing powerful buffs that shouldn't be spammed.

Cooldown Configuration

Has CooldownEnable cooldown for this effect
Cooldown DurationSeconds before effect can be reapplied
Cooldown Starts On ApplyIf true, cooldown starts when applied. If false, starts when effect ends.
Example: A powerful 10-second shield with a 30-second cooldown that starts on apply. The player can't re-apply the shield until 20 seconds after it expires.

Cleanse Types

Cleanse types control which dispel abilities can remove which effects. This allows for strategic depth - a magic dispel won't cure poison!

TypeDescription
AnyCan be removed by any dispel ability
MagicOnly removed by magic dispels (arcane curses, enchantments)
PhysicalOnly removed by physical cleanses (bandages, rest)
CurseOnly removed by curse-breaking abilities
DiseaseOnly removed by disease cures
PoisonOnly removed by antidotes
UndispellableCannot be removed by any dispel (only expires naturally)

VFX & Audio Feedback

Each effect can spawn visual effects and play sounds at key moments.

VFX Hooks

  • • Apply VFX: Spawns when effect is applied
  • • Remove VFX: Spawns when effect ends
  • • Tick VFX: Spawns on each tick
  • • VFX Lifetime: Auto-destroy delay

Audio Hooks

  • • Apply Sound: Plays when effect starts
  • • Remove Sound: Plays when effect ends
  • • Tick Sound: Plays on each tick
  • • Volume: Master volume (0-1)

Aura System

The StatusEffectAura component automatically applies effects to entities within a radius. Perfect for healing zones, poison clouds, or buff auras around NPCs.

Aura Configuration

EffectThe status effect to apply to targets
RadiusRange of the aura in world units
Target ModeAll, Allies Only, Enemies Only, or Self Only
Remove On ExitRemove effect when targets leave the aura
Update IntervalHow often to scan for targets (seconds)
Performance Tip: Increase the update interval for large-radius auras. 0.25s is a good default, but slow-moving auras can use 0.5s or higher.

Effect Interactions (Reactions)

Interactions let effects react to each other: Wet + Shock → Electrocuted, Burn melts Frozen, Oil + Fire → Explosion. A rule fires when an Incoming effect is applied while a matching Present effect is already active on the target. Rules are plain ScriptableObjects, grouped in an EffectInteractionSet.

1. Match

Incoming and Present matchers select effects by Definition, Category, Category Type, Tag or Any. Optional minimum stack count on the present effect.

2. Resolve

Incoming: Apply or Block. Present: Keep, Remove, Remove Stacks or Refresh, plus an optional duration bonus.

3. Result

Optionally apply a Result Effect (with the present effect's stacks transferred), spawn reaction VFX and play a sound. The On Effect Reaction event fires.

Evaluation Rules

  • • Rules run after immunity, cooldown and resistance checks and before stacking, so a re-applied effect can trigger a rule too (Burn + Burn → Inferno).
  • • Rules are evaluated by descending Priority; only the first matching rule fires.
  • • Chance (0–1) lets a rule fire probabilistically. Disabled rules are skipped.
  • • A Result Effect goes through the normal apply pipeline and can chain into further rules (depth-limited to 4).
  • • A set is assigned per StatusEffectManager; managers without a set fall back to EffectInteractionSet.Global.
Example: Rule "Wet + Shock → Electrocuted": Incoming = Shock, Present = Wet, Incoming Action = Block, Present Action = Remove, Result Effect = Electrocuted. Applying Shock to a Wet target consumes both and leaves the target Electrocuted. Try it in the BSM_ReactionsScene example.

Priority & Exclusive Categories

Every effect definition has an integer Priority (default 0). Mark a category as Exclusive and only one effect of that category can be active at a time:

Incoming vs. ActiveResult
Higher PriorityActive effect is dispelled, incoming is applied (Stun 10 replaces Slow 1)
Lower PriorityIncoming is blocked, On Effect Blocked fires
Equal PriorityBlocked by default; replaces when Equal Priority Replaces is enabled
Same DefinitionHandled by the Stacking Mode as usual (Refresh, Stack, ...)
Exclusive categories work alongside Max Concurrent; the exclusive check runs first. Query the winner with GetHighestPriorityEffect(category) or the Category Priority At Least condition.

Resistance & Apply Chance

Effects no longer have to land every time. Three optional settings on the definition control it; a failed roll fires On Effect Resisted (not Blocked) and nothing is applied.

Apply ChanceBase probability 0–1 that the application succeeds (1 = always)
Resist Chance StatGC2 Stat on the target, read as a 0–100 % chance to fully resist (e.g. "Poison Resistance")
Duration Resist StatGC2 Stat on the target, read as a 0–100 % reduction of the duration (25 → 25 % shorter). Timed effects only
Stat-based resistance reads the target's GC2 Traits component. Without Traits (or without GC2 Stats) the stat values count as 0 and only Apply Chance is used. The scaled duration is reflected in progress bars and Refresh.

Source Tracking

Every instance can remember who applied it. The Apply Status Effect instruction has a Source field (default: Self, i.e. the object running the instruction), auras report their owner, and code can callApplyEffect(definition, sourceGameObject).

  • • Re-applying with a new source updates the instance (last non-null applier wins)
  • • Query with Has Effect From Source, remove with Remove Effects From Source
  • • Instruction lists on the definition receive the source as Target; the On Effect Reaction event passes it as the trigger's Target
  • • Sources are scene objects and are intentionally not saved by StatusEffectRemember
Use cases: kill credit for a poison, "remove all curses cast by this shaman" when the shaman dies, or letting the caster of a mark react to its expiry.