5 min

Entity Effects

Applying buffs, debuffs, and status effects to entities in Hytale.

Overview

Entity effects (buffs/debuffs) are managed through the EffectControllerComponent. Effects can modify stats, visuals, and behavior of entities.

EffectControllerComponent

This component manages all active effects on an entity.

1public class EffectControllerComponent implements Component {
2 // Add effects
3 public boolean addEffect(
4 Ref ref,
5 EntityEffect effect,
6 ComponentAccessor accessor
7 );
8
9 public boolean addEffect(
10 Ref ref,
11 EntityEffect effect,
12 float duration,
13 OverlapBehavior overlapBehavior,
14 ComponentAccessor accessor
15 );
16
17 public boolean addInfiniteEffect(
18 Ref ref,
19 int index,
20 EntityEffect effect,
21 ComponentAccessor accessor
22 );
23
24 // Remove effects
25 public void removeEffect(
26 Ref ref,
27 int effectIndex,
28 ComponentAccessor accessor
29 );
30
31 public void removeEffect(
32 Ref ref,
33 int effectIndex,
34 RemovalBehavior behavior,
35 ComponentAccessor accessor
36 );
37
38 public void clearEffects(
39 Ref ref,
40 ComponentAccessor accessor
41 );
42
43 // Query effects
44 public Int2ObjectMap getActiveEffects();
45 public int[] getActiveEffectIndexes();
46 public ActiveEntityEffect[] getAllActiveEntityEffects();
47
48 // Invulnerability
49 public boolean isInvulnerable();
50 public void setInvulnerable(boolean invulnerable);
51}

ActiveEntityEffect

Represents a currently active effect on an entity.

1public class ActiveEntityEffect implements Damage.Source {
2 // Constructors
3 public ActiveEntityEffect(
4 String effectId,
5 int level,
6 float initialDuration,
7 float remainingDuration,
8 boolean isInfinite,
9 boolean isDebuff,
10 String sourceId,
11 float damagePerTick,
12 boolean invulnerable,
13 DamageCalculatorSystems.Sequence damageSequence,
14 boolean showIcon
15 );
16
17 // Simple constructor for basic effects
18 public ActiveEntityEffect(
19 String effectId,
20 int level,
21 float duration,
22 boolean isDebuff,
23 String sourceId,
24 boolean showIcon
25 );
26
27 // Query methods
28 public int getEntityEffectIndex();
29 public float getInitialDuration();
30 public float getRemainingDuration();
31 public boolean isInfinite();
32 public boolean isDebuff();
33 public boolean isInvulnerable();
34
35 // Tick (called each world tick)
36 public void tick(...);
37}

Effect Configuration

EntityEffect Asset

Effects are defined as assets in the game. The EntityEffectclass holds the effect definition.

1// EntityEffect is loaded from assets
2public class EntityEffect {
3 // Effect definitions include:
4 // - Visual overlays
5 // - Stat modifiers
6 // - Damage over time
7 // - Model overrides
8 // - Application/removal behavior
9}

OverlapBehavior

Controls what happens when applying an effect that's already active:

behaviordescription
REPLACENew effect replaces the existing one
EXTENDAdds duration to existing effect
REFRESHResets duration to new value
STACKIncreases effect level/intensity

RemovalBehavior

Controls how an effect is visually removed:

behaviordescription
INSTANTEffect disappears immediately
FADEEffect fades out gradually

Model Override Effects

Effects can override an entity's model temporarily:

1// Set model change from effect
2effectController.setModelChange(
3 entityRef,
4 entityEffect,
5 modelIndex,
6 accessor
7);
8
9// Try to reset model change
10effectController.tryResetModelChange(
11 entityRef,
12 modelIndex,
13 accessor
14);

Usage Example

EffectExample.javajava
1public class EffectExample extends JavaPlugin {
2
3 @Override
4 protected void start() {
5 // Register command to apply effect
6 getCommandRegistry().register(
7 CommandSpec.builder()
8 .name("buff")
9 .permission("effects.buff")
10 .executor(this::buffCommand)
11 .build()
12 );
13 }
14
15 private void buffCommand(CommandContext ctx) {
16 if (!(ctx.getSender() instanceof Player player)) {
17 ctx.getSender().sendMessage("Players only");
18 return;
19 }
20
21 World world = player.getWorld();
22
23 world.execute(() -> {
24 Ref ref = player.getReference();
25 ComponentAccessor accessor = world.getEntityStore();
26
27 // Get effect controller component
28 // Note: Actual implementation requires getting the component
29 // through the entity store system
30
31 // For effects, you typically:
32 // 1. Load the EntityEffect from assets
33 // 2. Create ActiveEntityEffect with desired params
34 // 3. Add to the EffectControllerComponent
35
36 player.sendMessage("Effect system example");
37 });
38 }
39}
asset-based effects
Most effects in Hytale are defined as game assets (JSON files). You need to reference existing effect assets or create your own in the appropriate asset directories.

Checking Active Effects

1// Get all active effects on an entity
2EffectControllerComponent effectController = /* get from entity */;
3
4// Get map of effect index -> effect
5Int2ObjectMap effects = effectController.getActiveEffects();
6
7// Get just the indexes
8int[] effectIndexes = effectController.getActiveEffectIndexes();
9
10// Get as array
11ActiveEntityEffect[] allEffects = effectController.getAllActiveEntityEffects();
12
13// Check each effect
14for (ActiveEntityEffect effect : allEffects) {
15 if (effect.isDebuff()) {
16 // Handle debuff
17 float remaining = effect.getRemainingDuration();
18 }
19}

Invulnerability

Effects can grant temporary invulnerability:

1// Check if entity is invulnerable from effects
2if (effectController.isInvulnerable()) {
3 // Entity cannot take damage
4}
5
6// Set invulnerability directly
7effectController.setInvulnerable(true);

Key Classes

classpackagepurpose
EffectControllerComponentserver.core.entity.effectManages active effects
ActiveEntityEffectserver.core.entity.effectRuntime effect instance
EntityEffectserver.core.asset.type.entityeffect.configEffect definition asset
OverlapBehaviorserver.core.asset.type.entityeffect.configEffect stacking rules
RemovalBehaviorserver.core.asset.type.entityeffect.configEffect removal animation