Skip to content

RevFramework — Status Effects • Effects

Authoring assets and runtime implementations for buffs, debuffs, crowd control, and utility effects.

This folder defines what effects do, not how they are managed. Lifecycle, stacking, authority, timing, and math all live in Core.


Table of Contents


Overview

The Effects folder contains two distinct layers:

Layer Responsibility
Definitions ScriptableObject authoring assets used by designers.
Implementations Runtime IStatusEffect classes that execute behaviour.

Definitions build effects.
Controllers run effects.

If you are looking for stacking rules, authority, refresh behaviour, or ticking logic — you are in the wrong folder.


Mental Model

Effects are stateless behaviour descriptions driven entirely by the controller.

  • Effects do not tick themselves
  • Effects do not decide stacking
  • Effects do not apply immunity or resistance
  • Effects do not handle authority
  • Effects do not talk to UI

An effect should answer only one question:

“What happens when I am applied, ticked, refreshed, or removed?”

Everything else is owned by Core.


Quick Start

Using a definition

var poisonDef = /* StatusEffectDefinitionBase */;
var effect = poisonDef.BuildEffect();

ctrl.ApplyStatus(
    effect,
    StatusContext.FromAbility("firebolt")
);

Building directly

ctrl.ApplyOrRefresh(
    () => new PoisonStatus(5f, 10f),
    StatusContext.FromAbility("firebolt")
);

In both cases: - A new effect instance is created - All rules (stacking, potency, duration, authority) are applied by the controller


Definitions (Authoring)

Definitions are data-only ScriptableObjects. They must never contain runtime logic.

Definition Purpose
PoisonStatusDefinition Damage-over-time (Poison)
BurnStatusDefinition Fire DoT with optional spread
RegenStatusDefinition Heal-over-time
SlowStatusDefinition Movement speed reduction
HasteStatusDefinition Cooldown multiplier
VulnerabilityStatusDefinition Increases damage taken
ShieldStatusDefinition Temporary shield buffer
StunStatusDefinition Behaviour-disabling CC
ThornsStatusDefinition Damage reflection
Base StatusEffectDefinitionBase Abstract builder (BuildEffect)

Example:

public override IStatusEffect BuildEffect()
{
    return new PoisonStatus(duration, dps);
}

Rules: - Always return a fresh instance - Never cache effects - Never mutate state here


Implementations (Runtime)

Implementations are concrete IStatusEffect types, usually subclasses of TimedStatusEffect.

DoTs / HoTs

  • PoisonStatus — damage over time
  • BurnStatus — fire DoT with optional spread
  • RegenStatus — heal over time

Multipliers

  • SlowStatus — movement speed via MovementSpeedScaler
  • HasteStatus — cooldown scaling via ICooldownScaleSink
  • VulnerabilityStatus — damage taken via IDamageTakenModifier

Utility

  • ShieldStatus — shield tickets via IShieldTicketPool
  • StunStatus — disables behaviours by type name
  • ThornsStatus — damage reflection via Health bridges

Support

  • SimpleShieldTicketPool — minimal IShieldTicketPool implementation

Implementations may: - Implement IAdjustableMagnitude for potency scaling - Implement IStatusMetadata / IDispellable for tags and dispels - Integrate with other systems through explicit sink interfaces

They must never: - Query other effects directly - Modify controller state - Assume authority - Assume UI presence


Gotchas

  • Never reuse effect instances — one instance per application
  • Potency and resistance are applied after construction, inside the controller
  • ShieldLegacyBridge may wipe all shield values — prefer IShieldTicketPool
  • StunStatus requires fully-qualified type names
  • FX hooks are optional and must not mutate gameplay state
  • Effects that don’t implement IAdjustableMagnitude will not respond to recompute

Extending

To add new effects:

  1. Implement a new runtime effect (TimedStatusEffect or IStatusEffect)
  2. Add optional metadata (IStatusMetadata, IDispellable)
  3. Create a matching definition deriving from StatusEffectDefinitionBase
  4. (Optional) Register it in StatusRegistry for factory-based creation

When integrating with other systems: - Prefer sink interfaces - Keep effects loosely coupled - Fail safely when dependencies are absent


See Also

  • Core — lifecycle, stacking, authority, math
  • Abstractions — contracts and enums
  • Auras — area-based modifiers
  • Bridges — Pickups integration
  • UI — status display components