EffectControllerComponent
The EffectControllerComponent manages status effects on entities - buffs, debuffs, damage over time, stat modifiers, and visual changes.
Access
Section titled “Access”EffectControllerComponent effects = store.getComponent(ref, EffectControllerComponent.getComponentType());Adding Effects
Section titled “Adding Effects”Effects are defined as JSON assets loaded from Entity/Effects/. Get the effect asset by ID, then apply it:
// get effect by asset IDEntityEffect slow = EntityEffect.getAssetMap().getAsset("Slow");
// apply with default duration from asseteffects.addEffect(ref, slow, store);
// apply with custom duration (seconds) and overlap behavioreffects.addEffect(ref, slow, 30.0f, OverlapBehavior.OVERWRITE, store);Infinite Effects
Section titled “Infinite Effects”For permanent effects that don’t expire:
String effectId = "Immunity_Fire";int effectIndex = EntityEffect.getAssetMap().getIndex(effectId);EntityEffect effect = EntityEffect.getAssetMap().getAsset(effectId);effects.addInfiniteEffect(ref, effectIndex, effect, store);OverlapBehavior
Section titled “OverlapBehavior”Controls what happens when applying an effect the entity already has:
| Behavior | Description |
|---|---|
EXTEND | Add new duration to existing remaining time |
OVERWRITE | Replace with new duration |
IGNORE | Keep existing, ignore new application |
// stack durations - 10s + 10s = 20s totaleffects.addEffect(ref, effect, 10.0f, OverlapBehavior.EXTEND, store);
// reset to fresh durationeffects.addEffect(ref, effect, 10.0f, OverlapBehavior.OVERWRITE, store);
// only apply if not already activeeffects.addEffect(ref, effect, 10.0f, OverlapBehavior.IGNORE, store);Removing Effects
Section titled “Removing Effects”int effectIndex = EntityEffect.getAssetMap().getIndex("Slow");
// remove with default behavior from asseteffects.removeEffect(ref, effectIndex, store);
// remove with specific behavioreffects.removeEffect(ref, effectIndex, RemovalBehavior.COMPLETE, store);RemovalBehavior
Section titled “RemovalBehavior”| Behavior | Description |
|---|---|
COMPLETE | Fully remove the effect immediately |
INFINITE | Remove infinite flag only (starts counting down) |
DURATION | Set remaining duration to 0 (removed on next tick) |
Clear All Effects
Section titled “Clear All Effects”effects.clearEffects(ref, store);Effects are also automatically cleared on death and respawn.
Checking Effects
Section titled “Checking Effects”// get all active effects (index -> ActiveEntityEffect)Int2ObjectMap<ActiveEntityEffect> active = effects.getActiveEffects();
// check if specific effect is activeint effectIndex = EntityEffect.getAssetMap().getIndex("Poison");boolean hasPosion = active.containsKey(effectIndex);
// get active effect indexes as arrayint[] indexes = effects.getActiveEffectIndexes();
// check invulnerability (any effect granting it)boolean invulnerable = effects.isInvulnerable();ActiveEntityEffect
Section titled “ActiveEntityEffect”Each active effect instance provides:
ActiveEntityEffect active = effects.getActiveEffects().get(effectIndex);
float remaining = active.getRemainingDuration(); // seconds leftfloat initial = active.getInitialDuration(); // original durationboolean infinite = active.isInfinite(); // never expiresboolean debuff = active.isDebuff(); // negative effectboolean invuln = active.isInvulnerable(); // grants damage immunityint index = active.getEntityEffectIndex(); // asset indexEffect Assets
Section titled “Effect Assets”Effects are defined as JSON assets loaded from Entity/Effects/. Key properties:
{ "Duration": 10.0, "Infinite": false, "Debuff": false, "StatusEffectIcon": "UI/StatusEffects/MyEffect.png", "OverlapBehavior": "Extend", "RemovalBehavior": "Complete", "Invulnerable": false}Inheritance
Section titled “Inheritance”Effects can inherit from a parent:
{ "Parent": "Poison", "Duration": 8.0}Default Values
Section titled “Default Values”| Property | Default |
|---|---|
Duration | 0.0 (instant) |
Infinite | false |
Debuff | false |
Invulnerable | false |
OverlapBehavior | Ignore |
RemovalBehavior | Complete |
ValueType | Absolute |
Stat Modifiers
Section titled “Stat Modifiers”Stat modifiers adjust a stat’s min or max bound for the duration of the effect. For a list of available stats and the programmatic modifier API, see Entity Stats.
Simple stat modifiers with a value type:
{ "StatModifiers": { "Health": 5, "Stamina": 1.5 }, "ValueType": "Percent"}| ValueType | Description |
|---|---|
Percent | Modifier is a percentage |
Absolute | Modifier is an absolute value |
For more control, use RawStatModifiers with per-stat modifier arrays:
{ "RawStatModifiers": { "Health": [ { "Amount": 30, "CalculationType": "Additive", "Target": "Max" } ] }}CalculationType can be Additive or Multiplicative.
Damage Over Time
Section titled “Damage Over Time”For poison, burning, etc. BaseDamage maps damage causes to values:
{ "DamageCalculator": { "BaseDamage": { "Fire": 5 } }, "DamageCalculatorCooldown": 1.0, "DamageEffects": { "WorldSoundEventId": "SFX_Effect_Burn_World", "PlayerSoundEventId": "SFX_Effect_Burn_Local" }}DamageCalculatorCooldown sets seconds between damage ticks.
Visual Effects
Section titled “Visual Effects”{ "ApplicationEffects": { "EntityBottomTint": "#100600", "EntityTopTint": "#cf2302", "EntityAnimationId": "Hurt", "Particles": [ { "SystemId": "Effect_Fire", "TargetEntityPart": "Entity", "TargetNodeName": "Head" } ], "ScreenEffect": "ScreenEffects/Fire.png", "LocalSoundEventId": "SFX_Effect_Burn_Local", "WorldSoundEventId": "SFX_Effect_Burn_World", "ModelVFXId": "Burn" }}Tint values are hex color strings. Particles support SystemId, TargetEntityPart, TargetNodeName, PositionOffset, and Color.
Movement Modifiers
Section titled “Movement Modifiers”{ "ApplicationEffects": { "HorizontalSpeedMultiplier": 0.5, "KnockbackMultiplier": 0, "MovementEffects": { "DisableAll": true }, "MouseSensitivityAdjustmentTarget": 0.25, "MouseSensitivityAdjustmentDuration": 0.1 }}MovementEffects supports DisableAll (freezes entity) and DisableSprint.
Model Changes
Section titled “Model Changes”Temporarily replace entity model (uses entity type IDs):
{ "ModelChange": "Corgi"}Or override model, texture, and animations:
{ "ModelOverride": { "Model": "VFX/Spells/Roots/Model.blockymodel", "Texture": "VFX/Spells/Roots/Model.png", "AnimationSets": { "Spawn": { "Animations": [{ "Animation": "VFX/Spells/Roots/Spawn.blockyanim", "Looping": false }] } } }}Ability Disabling
Section titled “Ability Disabling”Disable specific interaction types while effect is active:
{ "ApplicationEffects": { "AbilityEffects": { "Disabled": ["Primary", "Secondary", "Ability1", "Ability3"] } }}Available interaction types: Primary, Secondary, Ability1, Ability2, Ability3, Use, Pick, Pickup, Dodge, Held, HeldOffhand, Equipped, etc.
Damage Resistance
Section titled “Damage Resistance”Grant resistance to damage causes:
{ "DamageResistance": { "Fire": [{ "Amount": 1.0, "CalculationType": "Multiplicative" }], "Environmental": [{ "Amount": 1.0, "CalculationType": "Multiplicative" }] }}CalculationType can be Additive or Multiplicative. Amount of 1.0 with multiplicative = full immunity.
Built-in Effects
Section titled “Built-in Effects”Effects are loaded from Entity/Effects/ in the asset directory. The asset ID is the filename without .json.
Status Effects
Section titled “Status Effects”| Effect ID | Duration | Debuff | Description |
|---|---|---|---|
Burn | 3s | Yes | Fire damage (5/sec), cancelled in water |
Lava_Burn | 5s | - | Lava-specific burn variant |
Poison | 16s | Yes | Poison damage (10 per 5s), extends on reapply |
Poison_T1 / T2 | 16s | - | Tiered poison (spider, scarak) |
Poison_T3 | 31s | - | Strong poison (snapdragon) |
Stun | 10s | - | Disables movement (DisableAll) and abilities |
Freeze | instant | - | Disables all movement, ice visuals |
Slow | 10s | - | 50% horizontal speed reduction |
Root | 10s | - | Disables movement, 0 knockback, model override |
Immune | 20s | No | Invulnerability with green tint |
Antidote | 120s | No | Poison cure |
Combat Effects
Section titled “Combat Effects”| Effect ID | Description |
|---|---|
Stamina_Broken | Applied when stamina depleted (hardcoded default) |
Stamina_Broken_Immune | Brief immunity after stamina break |
Stamina_Error_State | Visual flash when stamina insufficient |
Stamina_Regen_Delay_Action | Delays stamina regen after actions |
Dodge_Invulnerability | Brief invulnerability during dodge |
Dodge_Left / Dodge_Right | Dodge movement effects |
Red_Flash | Red tint on damage hit |
Consumable Effects
Section titled “Consumable Effects”| Effect ID | Description |
|---|---|
Food_Instant_Heal_T1 / T2 / T3 | Tiered instant healing |
Food_Health_Regen_Tiny / Small / Medium / Large | Health regeneration |
Food_Health_Boost_Tiny / Small / Medium / Large | Max health boost (RawStatModifiers) |
Food_Stamina_Regen_Tiny / Small / Medium / Large | Stamina regeneration |
Food_Stamina_Boost_Tiny / Small / Medium / Large | Max stamina boost (RawStatModifiers) |
Potion_Health_Instant_Lesser / Greater | Health potions |
Potion_Stamina_Instant_Lesser / Greater | Stamina potions |
Potion_Morph_Dog / Frog / Mouse / Pigeon / Mosshorn | Morph potions (60s, ModelChange) |
Mana Effects
Section titled “Mana Effects”| Effect ID | Description |
|---|---|
Mana / Mana_High / Mana_Low | Mana regeneration (varying rates) |
Mana_Drain | Mana drain (negative stat modifier) |
Mana_Regen / Mana_Regen_High / Mana_Regen_Low | Mana regen buffs |
Immunity Effects
Section titled “Immunity Effects”| Effect ID | Description |
|---|---|
Immunity_Environmental | Full environmental damage resistance |
Immunity_Fire | Full fire damage resistance |
Weapon Effects
Section titled “Weapon Effects”| Effect ID | Description |
|---|---|
Mace_Signature | Mace signature ability |
Battleaxe_Whirlwind | Battleaxe spin attack |
Battleaxe_Downstrike_Jump | Battleaxe downstrike jump |
Dagger_Signature / Dash / Pounce | Dagger abilities |
Sword_Signature_SpinStab | Sword spin-stab |
FlamethrowerSource | Fire staff secondary |
Flame_Staff_Burn | Fire staff projectile burn |
Intangible_Dark / Intangible_Smol | Intangibility effects |
Projectile Effects
Section titled “Projectile Effects”| Effect ID | Description |
|---|---|
Bomb_Explode_Stun | Bomb explosion stun |
Crossbow_Combo_1 / Combo_2 | Crossbow combo stages |
Two_Handed_Bow_Ability2_Slow | Two-handed bow ability slow |
Rubble_Hit / Rubble_Miss | Rubble impact particles |
Deployable / NPC Effects
Section titled “Deployable / NPC Effects”| Effect ID | Description |
|---|---|
Healing_Totem_Heal | Healing totem area heal |
Slowness_Totem_Slow | Slowness totem area slow |
Npc_Heal_Low | NPC low heal |
Return_Home_Healing | NPC returning home heal |
Death (NPC) | NPC death effect |
Drop Rarity Effects
Section titled “Drop Rarity Effects”| Effect ID | Description |
|---|---|
Drop_Uncommon / Rare / Epic / Legendary | Drop rarity visuals |
Misc Effects
Section titled “Misc Effects”| Effect ID | Description |
|---|---|
BlockPlaceSuccess / BlockPlaceFail | Block placement feedback |
Creative | Creative mode activation visual |
Portal_Teleport | Portal teleportation effect |
Examples
Section titled “Examples”Apply a Built-in Effect
Section titled “Apply a Built-in Effect”EffectControllerComponent effects = store.getComponent(ref, EffectControllerComponent.getComponentType());if (effects == null) return;
EntityEffect slow = EntityEffect.getAssetMap().getAsset("Slow");effects.addEffect(ref, slow, 10.0f, OverlapBehavior.OVERWRITE, store);Check and Remove
Section titled “Check and Remove”int poisonIndex = EntityEffect.getAssetMap().getIndex("Poison");
if (effects.getActiveEffects().containsKey(poisonIndex)) { effects.removeEffect(ref, poisonIndex, RemovalBehavior.COMPLETE, store);}Convert Infinite to Timed
Section titled “Convert Infinite to Timed”int effectIndex = EntityEffect.getAssetMap().getIndex(effectId);ActiveEntityEffect active = effects.getActiveEffects().get(effectIndex);
if (active != null && active.isInfinite()) { // remove infinite flag - effect starts counting down effects.removeEffect(ref, effectIndex, RemovalBehavior.INFINITE, store);}Built-in Commands
Section titled “Built-in Commands”| Command | Description |
|---|---|
/player effect apply <player> <effect> [duration] | Apply effect to player |
/player effect clear <player> | Remove all effects from player |
/entity effect <entity> <effect> [duration] | Apply effect to any entity |
Special Behaviors
Section titled “Special Behaviors”Burn Effect
Section titled “Burn Effect”The “Burn” effect is automatically cancelled when the entity enters water. This is handled by LivingEntityEffectSystem.canApplyEffect().
Effect on Death/Respawn
Section titled “Effect on Death/Respawn”All effects are automatically cleared when an entity dies or a player respawns.
Network Sync
Section titled “Network Sync”Effect changes are synced to clients via ComponentUpdateType.EntityEffects. The client receives:
- Effect index
- Remaining duration
- Whether infinite
- Whether debuff
- Status icon for UI
No effect events: There are no dedicated events for effect application or removal. Monitor effects by checking getActiveEffects() or use the interaction system’s EffectConditionInteraction for conditional logic.
Death messages: Effects that deal damage can customize death messages via the Locale property. The effect implements Damage.Source internally. See Death for how death processing works.
Effect conditions: The LivingEntityEffectSystem.canApplyEffect() method handles special cases - currently only the “Burn” effect is cancelled when the entity is in water.