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
- Mental Model
- Quick Start
- Definitions (Authoring)
- Implementations (Runtime)
- Gotchas
- Extending
- See Also
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 timeBurnStatus— fire DoT with optional spreadRegenStatus— heal over time
Multipliers¶
SlowStatus— movement speed viaMovementSpeedScalerHasteStatus— cooldown scaling viaICooldownScaleSinkVulnerabilityStatus— damage taken viaIDamageTakenModifier
Utility¶
ShieldStatus— shield tickets viaIShieldTicketPoolStunStatus— disables behaviours by type nameThornsStatus— damage reflection via Health bridges
Support¶
SimpleShieldTicketPool— minimalIShieldTicketPoolimplementation
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
ShieldLegacyBridgemay wipe all shield values — preferIShieldTicketPoolStunStatusrequires fully-qualified type names- FX hooks are optional and must not mutate gameplay state
- Effects that don’t implement
IAdjustableMagnitudewill not respond to recompute
Extending¶
To add new effects:
- Implement a new runtime effect (
TimedStatusEffectorIStatusEffect) - Add optional metadata (
IStatusMetadata,IDispellable) - Create a matching definition deriving from
StatusEffectDefinitionBase - (Optional) Register it in
StatusRegistryfor 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, mathAbstractions— contracts and enumsAuras— area-based modifiersBridges— Pickups integrationUI— status display components