Built-in Effect Executors

BlockEffectExecutor supplies a world anchor; EntityEffectExecutor updates that anchor from an entity and optional auto-rotation mode.
Use the built-in executors when an effect follows a block or entity. Configure them before start(); start() creates and emits the runtime.
Block Anchor
FX fx = FXHelper.getFX(ResourceLocation.parse("mymod:block_aura"));
if (fx != null) {
BlockEffectExecutor executor = new BlockEffectExecutor(fx, level, pos);
executor.setOffset(0, 0.5, 0);
executor.setScale(1.25, 1.25, 1.25);
executor.setDelay(4);
executor.setCheckState(true);
executor.setForcedDeath(false);
executor.setAllowMulti(false);
executor.setOnFinished(runtime -> onAuraEnded());
executor.start();
}The root is centered at the block plus offset. The executor retires the runtime when the chunk unloads, block type changes, or—with checkState—the exact BlockState changes.
Entity Anchor
EntityEffectExecutor executor = new EntityEffectExecutor(
fx, level, entity, EntityEffectExecutor.AutoRotate.LOOK);
executor.setOffset(0, -0.25, 0);
executor.setRotation(0, 90, 0); // degrees convenience overload
executor.setForcedDeath(true);
executor.start();The entity root follows interpolated eye position every frame. Since 2.2.9 the executor also reports the entity as the effect's owner, so beam raycasts and particle collision with Ignore Owner on skip it.
| AutoRotate | Behavior |
|---|---|
NONE | Keep only the configured quaternion |
FORWARD | Rotate from the entity's forward vector |
LOOK | Rotate from the view/look vector |
XROT | Apply the entity visual yaw using Photon's X-oriented convention |
Shared Options
- offset/rotation/scale transform the runtime root.
- delay is assigned to every object after emit/reset, in ticks.
- forcedDeath controls anchor loss:
trueremoves remnants immediately;falselets existing particles drain. - allowMulti=false deduplicates an equal effect on the same anchor: the same
FXdefinition object or the same FX id. - onFinished fires once when the runtime finishes, is destroyed, or becomes invalid because the particle engine discarded it.
- startSection (
setStartSection, set beforestart()) starts the Timeline from a section instead of0. Since 2.2.11
With allowMulti=false, a start is no longer always skipped. Since 2.2.9, if the equal effect already running plays an older load of a definition that has since been reloaded (a resource reload, a rewritten FX Pack), the new start stops it and plays the current definition.
getRuntime() is nullable before a successful start() and when start is skipped. Keep the executor if later code needs its runtime or callback; avoid reaching into the static executor caches.