RevFramework — Status Effects • Abstractions¶
Core contracts and enums that define the Status Effects system. These are stable, public APIs and safe for other modules to depend on.
Nothing in this folder performs runtime logic or mutates state.
Table of Contents¶
- Overview
- What Belongs Here (and What Doesn’t)
- Quick Start
- Composition Cheatsheet
- Interfaces
- Enums
- Extending
- Related Docs
Overview¶
The Abstractions folder defines the public contracts for RevFramework’s Status Effects system.
These types describe what a status is, how it is identified, and which extension seams exist — without imposing any runtime behaviour, authority rules, or gameplay logic.
This makes the abstractions:
- Safe to depend on from other systems (Health, Pickups, UI, AI, etc.)
- Stable across versions
- Usable in tests, tools, and editor-only code
Concrete runtime behaviour lives in sibling folders such as Core, Effects, Authority, Timing, and UI.
Key Responsibilities¶
- Defining the status lifecycle contract (
IStatusEffect) - Describing magnitude and duration scaling (
IAdjustableMagnitude,IStatusPotency,IStatusResistance) - Expressing immunity, dispels, and metadata (
IStatusImmunity,IStatusMetadata,IDispellable) - Providing strongly-typed identifiers (
StatusId) - Exposing injectable seams (
IStatusMathService,ITimeSource,IStatusEffectController) - Standardising shared enums (
StatusTag,DispelType,StatusStackingRule)
What Belongs Here (and What Doesn’t)¶
This folder contains only contracts and enums.
✔ Belongs here:
- Interfaces
- Enums
- Immutable value types (e.g. StatusId)
✘ Does not belong here: - Controllers or managers - Time sources with behaviour - Math implementations - Gameplay logic - Authority resolution - UI logic
If a type has side effects, ticks, mutates state, or touches Unity time — it belongs elsewhere.
About StatusId¶
StatusId is a readonly struct designed for safe, efficient identification of status effects.
It provides:
- Cached ordinal hash (fast comparisons)
- Implicit conversion to and from
string(non-breaking migration) - Value-type semantics (safe dictionary key, no GC churn)
All of the following are valid and equivalent:
StatusId id = "poison";
StatusId id = new StatusId("poison");
string s = StatusRegistry.Id.Poison;
Prefer StatusId in gameplay and runtime code to avoid stringly-typed APIs.
Quick Start¶
Most runtime effects derive from TimedStatusEffect, but you may also implement IStatusEffect directly for instant or passive behaviours.
Example custom effect:
public sealed class BleedStatus : TimedStatusEffect, IStatusMetadata, IDispellable
{
public override StatusId Id => "bleed";
public override StatusStackingRule Stacking => StatusStackingRule.Stack;
public StatusTag Tags => StatusTag.Debuff | StatusTag.DOT;
public DispelType Dispel => DispelType.Physical;
public int DispelTier => 1;
private readonly float dps;
public BleedStatus(float duration, float dps) : base(duration)
{
this.dps = dps;
}
protected override void OnTick(GameObject target, float dt)
{
if (target.TryGetComponent<IDamageable>(out var dmg))
dmg.TryTakeDamage(Mathf.RoundToInt(dps * dt));
}
}
This class defines behaviour only. Stacking, authority, refresh rules, and UI are handled elsewhere.
Composition Cheatsheet¶
| Category | Interface | Responsibility |
|---|---|---|
| Core (Effect-side) | IStatusEffect |
Runtime instance lifecycle (Apply / Tick / Remove / Refresh). |
IAdjustableMagnitude |
Allows potency scaling; must recompute from base values. | |
| Receiver-side | IStatusPotency |
Multiplies incoming magnitude (auras, zones, difficulty). |
IStatusResistance |
Scales duration (0–1). | |
IStatusImmunity |
Pre-apply immunity check by id/tags. | |
| Metadata & Math | IStatusMetadata |
Tags, dispel type, dispel tier. |
IStatusMathService |
Computes final potency & duration (optional DI seam). | |
| Controllers & Timing | IStatusEffectController |
Minimal apply/remove/query surface. |
ITimeSource |
Custom deltaTime provider. | |
| Cleansing | IDispellable |
Marks effects eligible for dispel/cleanse. |
Note:
IStatusEffectControllerexposes only a minimal surface. Stacking rules, per-source caps, authority, context, and dispels are implemented in Core.
Interfaces¶
IStatusEffect¶
Defines the full status lifecycle:
ApplyTickRemoveRefresh
Uses StatusId for identity. Effects must not tick or remove themselves.
IAdjustableMagnitude¶
Allows external potency scaling.
Implementations must: - Store a base magnitude - Recompute from base values - Never compound multipliers
IStatusPotency¶
Receiver-side magnitude multiplier (auras, difficulty scaling, zones).
IStatusResistance¶
Receiver-side duration multiplier in range [0..1].
IStatusImmunity¶
Pre-apply immunity check by status id and tag mask. Handled automatically by the controller.
IStatusMetadata¶
Optional metadata exposed by effects: - Tags - Dispel type - Dispel tier
IStatusMathService¶
Injectable math seam for final potency/duration computation.
If absent, runtime falls back to default helpers in Core.
IStatusEffectController¶
Minimal interface for interacting with controllers from other modules or tests.
Exposes: - Apply - Remove - Query
It intentionally omits stacking, authority, and context management.
ITimeSource¶
Custom deltaTime provider.
Useful for: - Turn-based systems - Paused gameplay - Bullet time - Local or per-entity time sources
Default implementations live in the Timing folder.
IDispellable¶
Marks effects eligible for removal via Dispel() or tag-based cleanses.
Enums¶
[System.Flags]
public enum StatusTag
{
None = 0,
Buff = 1 << 0,
Debuff = 1 << 1,
DOT = 1 << 2,
HOT = 1 << 3,
CC = 1 << 4,
Movement = 1 << 5,
Poison = 1 << 6,
Fire = 1 << 7,
Magic = 1 << 8
}
StatusTag— Categorisation flags for filtering, resistance, and UIDispelType— None, Magic, Poison, Curse, PhysicalStatusStackingRule— Replace / Refresh / Stack
Extending¶
You may safely extend the system by:
- Adding new tags or dispel buckets for your game
- Implementing
IStatusEffectfor new behaviours (bleed, freeze, charm, fracture) - Implementing
IStatusPotencyto scale magnitude - Implementing
IStatusResistanceto scale duration - Providing a custom
ITimeSource - Writing a custom
IStatusMathServicefor centralised or testable math - Using
IStatusEffectControllerwhen applying/querying statuses from other modules
Avoid introducing runtime behaviour or logic into abstractions.