RevFramework — Status Effects • FAQ¶
This FAQ answers decision questions about the Status Effects system.
It is not a feature list and does not repeat the README content.
Use this when you’re asking:
- “Am I using this correctly?”
- “Is this the right extension point?”
- “Why does this behave like this?”
If you're new to the system, start with the Mental Model page first.
The FAQ assumes you already understand the controller‑driven lifecycle of status effects.
🔒 Core Rule (Read This First)¶
The StatusEffectController is the only supported mutation entry point.
All status application, refresh, and removal must go through the controller.
If you bypass the controller, behaviour is undefined.
How do I integrate Status Effects into my project?¶
Minimum setup:
- Add
StatusEffectControllerto any actor that should receive statuses - Apply effects via:
ApplyStatus(...), orApplyOrRefresh(...)(preferred)
That’s it.
Everything else — UI, Auras, Authority, Integration bridges — is optional.
| Feature | Required |
|---|---|
| StatusEffectController | ✅ Yes |
| Definitions / Effects | ✅ Yes |
| UI | ❌ No |
| Auras | ❌ No |
| Authority | ❌ No |
| Integration (Health, Shields) | ❌ No |
Should I use ScriptableObject definitions or build effects directly?¶
Both are supported. Choose based on intent:
| Use case | Recommendation |
|---|---|
| Designer‑tuned content | Use Definitions |
| Procedural / code‑driven | Build effects directly |
| Item / Pickup usage | Definitions (via Bridges) |
| Tests / simulations | Direct construction |
Definitions are data blueprints that build runtime effect instances.
They do not change runtime behaviour — they only configure it.
Why does my effect not tick or expire?¶
Almost always one of these:
| Cause | Explanation |
|---|---|
requireAuthority = true with no binder |
Effects freeze by design |
Custom ITimeSource returning 0 |
Time is paused |
| Effect duration = 0 | Instant or expired effect |
| Effect removed by cleanse/dispels | Working as intended |
If none of these apply, it may be a real issue.
Why doesn’t Status Effects replicate over the network?¶
Because it is not a netcode framework.
Status Effects:
- Applies logic locally
- Exposes authority hooks
- Leaves replication to your netcode
You must replicate:
- Active status IDs
- Remaining time
- Stack counts
- Context (if needed)
This keeps the system netcode‑agnostic by design.
Should I enable requireAuthority?¶
Only if you are doing multiplayer or deterministic simulation.
| Scenario | Setting |
|---|---|
| Single‑player | requireAuthority = false |
| Server‑authoritative multiplayer | true |
| Client‑side prediction | true (with custom binder) |
If enabled without a binder, everything no‑ops by design.
Is it safe to delete folders I don’t use?¶
Yes — by design.
| Folder | Safe to delete? |
|---|---|
| UI | ✅ |
| Auras | ✅ |
| Integrations | ✅ |
| Movement | ✅ |
| Timing | ✅ |
| Authority | ✅ |
Only Abstractions and Core are required.
Where should stacking rules live?¶
Always in the controller.
Do not:
- Encode stacking inside effects
- Track stacks manually in effects
- Query other effects from an effect
Use:
StatusStackingRuleSetStackCap(...)SetPerSourceStacks(...)
Why doesn’t potency affect my effect?¶
Only effects implementing IAdjustableMagnitude respond to potency changes.
Check:
- Does the effect implement
IAdjustableMagnitude? - Are you recomputing potency via the controller?
- Is a potency provider present on the target?
Potency is absolute, not compounding.
Why does my UI flicker when effects refresh?¶
Replace/Refresh stacking briefly removes and re‑adds effects.
The provided UI:
- Uses a destroy‑grace window
- Coalesces rapid refreshes
- Uses unscaled time for stability
If you write your own UI, replicate this behaviour.
Can I apply statuses without a StatusEffectController?¶
No.
This is a hard requirement.
Without a controller:
- No stacking
- No timing
- No authority
- No events
The system will warn (in editor) and safely no‑op.
Where should gameplay rules live?¶
| Concern | Location |
|---|---|
| Behaviour | Effect implementation |
| Rules / stacking | Controller |
| Scaling | Providers + math service |
| UI | UI layer |
| Authority | Authority binder |
| Integration | Bridges / Integration |
If something feels ambiguous, it likely belongs in Core.
How do I create a custom status effect?¶
Create a class derived from TimedStatusEffect.
Steps:
- Define a
StatusId - Choose a
StatusStackingRule - Implement behaviour in
OnTick(...) - Optionally expose metadata via
IStatusMetadata
Example:
public sealed class BleedStatus : TimedStatusEffect, IStatusMetadata
{
public override StatusId Id => "bleed";
public override StatusStackingRule Stacking => StatusStackingRule.Stack;
protected override void OnTick(GameObject target, float dt)
{
// custom behaviour here
}
}
Register in StatusRegistry if needed.
Can I extend this system safely?¶
Yes — that’s the point.
Safe extension points:
- New effects (
TimedStatusEffect) - New definitions
- New potency/resistance providers
- New sinks (movement, mana, stamina)
- Custom authority binders
- Custom math services
Unsafe changes:
- Modifying controller internals
- Adding logic to definitions
- Letting effects mutate global state
Before contacting support¶
Check:
- Is
requireAuthorityenabled without a binder? - Does the target have a
StatusEffectController? - Are you reusing effect instances?
- Are you mutating effect state directly?
- Are you expecting replication that doesn’t exist?
If it still looks wrong after that, it may be a real bug.
Final note¶
Status Effects is intentionally strict about ownership and responsibility.
That strictness ensures:
- predictable behaviour
- multiplayer safety
- low support overhead
If you work with the system boundaries, it becomes very hard to break.