ECS Events
Package: com.hypixel.hytale.server.core.event.events.ecs + modules.entity.damage
ECS events are a separate event mechanism from the event bus. They are dispatched through the ECS store (store.invoke) rather than IEventBus, and handlers are registered as ECS systems rather than with eventRegistry.register().
| Event Bus | ECS Events | |
|---|---|---|
| Dispatch | eventBus.dispatch(event) | store.invoke(ref, event) or store.invoke(event) |
| Listen | eventRegistry.register(Class, handler) | storeRegistry.registerSystem(new MySystem()) |
| Handler | lambda / Consumer<Event> | class extending EntityEventSystem or WorldEventSystem |
| Entity access | event.getPlayer() etc. | handler parameters (ArchetypeChunk, Ref) |
| Filtering | keyed registration | getQuery() archetype matching |
Two Handler Types
Section titled “Two Handler Types”EntityEventSystem
Section titled “EntityEventSystem”For entity-scoped events dispatched to a specific entity via store.invoke(ref, event). The handler receives the entity’s archetype chunk and index, providing direct access to all of its components.
public class MyBreakBlockHandler extends EntityEventSystem<EntityStore, BreakBlockEvent> { public MyBreakBlockHandler() { super(BreakBlockEvent.class); }
@Override public void handle(int index, ArchetypeChunk<EntityStore> archetypeChunk, Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer, BreakBlockEvent event) { // get entity reference Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
// access components on the entity Player player = archetypeChunk.getComponent(index, Player.getComponentType());
Vector3i blockPos = event.getTargetBlock(); if (shouldPrevent(player, blockPos)) { event.setCancelled(true); } }
@Override public Query<EntityStore> getQuery() { return Player.getComponentType(); // only fire for entities with Player component }}The handle parameters:
| Parameter | Description |
|---|---|
index | Entity’s index within the archetype chunk |
archetypeChunk | The chunk containing the entity — use to read components |
store | The ECS store |
commandBuffer | Buffered mutations (add/remove entities/components), applied after all handlers run |
event | The event object |
WorldEventSystem
Section titled “WorldEventSystem”For world-scoped events dispatched without an entity reference via store.invoke(event). No entity context or query filtering — the handler receives only the store.
public class MyPrefabPasteHandler extends WorldEventSystem<EntityStore, PrefabPasteEvent> { public MyPrefabPasteHandler() { super(PrefabPasteEvent.class); }
@Override public void handle(Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer, PrefabPasteEvent event) { int prefabId = event.getPrefabId(); if (isBlockedPrefab(prefabId)) { event.setCancelled(true); } }}Registration
Section titled “Registration”Register ECS event systems in your mod’s setup() method. PluginBase provides two store registries:
@Overridepublic void setup() { // entity events (BreakBlockEvent, Damage, PlaceBlockEvent, etc.) this.getEntityStoreRegistry().registerSystem(new MyBreakBlockHandler());
// chunk events (ChunkSaveEvent, ChunkUnloadEvent) this.getChunkStoreRegistry().registerSystem(new MyChunkSaveHandler());}Systems registered through these registries are automatically unregistered when your mod shuts down.
Query Filtering
Section titled “Query Filtering”EntityEventSystem implements QuerySystem, which means getQuery() controls which entities receive the event. The event is only delivered to entities whose archetype matches the query.
// only fire for entities with the Player component@Overridepublic Query<EntityStore> getQuery() { return Player.getComponentType();}
// fire for entities with BOTH Player and Health components@Overridepublic Query<EntityStore> getQuery() { return Query.and(Player.getComponentType(), Health.getComponentType());}
// fire for all entities (no filtering)@Overridepublic Query<EntityStore> getQuery() { return Query.any();}See Entity Queries for the full query API (Query.and, Query.or, Query.not).
WorldEventSystem does not have getQuery() — world events are always delivered to all registered handlers.
Dispatching ECS Events
Section titled “Dispatching ECS Events”To fire an ECS event from your own code:
// entity-scoped: dispatches to all EntityEventSystems registered for this event type// whose query matches the target entity's archetypeMyEvent event = new MyEvent(data);store.invoke(targetRef, event);
// world-scoped: dispatches to all WorldEventSystems registered for this event typestore.invoke(event);Both Store, CommandBuffer, and ComponentAccessor expose invoke. When dispatching from inside a handler, use the commandBuffer to dispatch (it forks the buffer for re-entrant safety).
After dispatch returns, check the event object for modifications:
store.invoke(ref, damageEvent);if (damageEvent.isCancelled()) { return; // a handler cancelled the damage}float finalAmount = damageEvent.getAmount(); // handlers may have modified thisCancellation
Section titled “Cancellation”ECS events can be cancellable by extending CancellableEcsEvent:
public class MyEvent extends CancellableEcsEvent { // ...}When a handler calls event.setCancelled(true), all subsequent handlers skip the event. The base EventSystem class checks shouldProcessEvent() before each handler — if the event implements ICancellableEcsEvent and isCancelled() returns true, the handler is not invoked.
For events with multiple inheritance constraints, implement ICancellableEcsEvent directly instead of extending CancellableEcsEvent.
Store Types
Section titled “Store Types”Two ECS stores exist, each with their own component registry:
| Store | Events | Registration |
|---|---|---|
EntityStore | BreakBlockEvent, PlaceBlockEvent, Damage, ChangeGameModeEvent, PrefabPasteEvent, and others | getEntityStoreRegistry() |
ChunkStore | ChunkSaveEvent, ChunkUnloadEvent | getChunkStoreRegistry() |
Chunk store events operate on WorldChunk entities rather than game entities. See Chunk Saving for a full ChunkStore handler example.
Event Reference
Section titled “Event Reference”Damage
Section titled “Damage”The primary damage event.
Class: com.hypixel.hytale.server.core.modules.entity.damage.Damage
This event is cancellable.
| Property | Value |
|---|---|
| Extends | CancellableEcsEvent, IMetaStore<Damage> |
| Cancellable | Yes |
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getSource() | @Nonnull Source | Returns the source of the damage |
setSource(@Nonnull Source source) | void | Sets the source of the damage |
getDamageCauseIndex() | int | Returns the index referencing a DamageCause asset |
setDamageCauseIndex(int damageCauseIndex) | void | Sets the damage cause index |
getCause() | @Nullable DamageCause | Returns the DamageCause asset (deprecated) |
getAmount() | float | Returns the current damage amount |
setAmount(float amount) | void | Sets the damage amount |
getInitialAmount() | float | Returns the original damage amount before modifications |
getDeathMessage(@Nonnull Ref<EntityStore> targetRef, @Nonnull ComponentAccessor<EntityStore> componentAccessor) | @Nonnull Message | Returns the death message for this damage |
getMetaStore() | @Nonnull IMetaStoreImpl<Damage> | Returns the meta store for accessing additional damage data |
Inner Classes
Section titled “Inner Classes”Damage.Source (interface)
Section titled “Damage.Source (interface)”Base interface for all damage sources.
| Method | Return Type | Description |
|---|---|---|
getDeathMessage(@Nonnull Damage info, @Nonnull Ref<EntityStore> targetRef, @Nonnull ComponentAccessor<EntityStore> componentAccessor) | @Nonnull Message | Returns the death message for this damage source |
Damage.EntitySource
Section titled “Damage.EntitySource”Damage originating from an entity.
| Method | Return Type | Description |
|---|---|---|
getRef() | @Nonnull Ref<EntityStore> | Returns the reference to the source entity |
Damage.ProjectileSource (extends EntitySource)
Section titled “Damage.ProjectileSource (extends EntitySource)”Damage originating from a projectile.
| Method | Return Type | Description |
|---|---|---|
getRef() | @Nonnull Ref<EntityStore> | Returns the reference to the shooter entity (inherited) |
getProjectile() | @Nonnull Ref<EntityStore> | Returns the reference to the projectile entity |
Damage.CommandSource
Section titled “Damage.CommandSource”Damage originating from a command.
No additional public getters beyond the inherited getDeathMessage() method.
Damage.EnvironmentSource
Section titled “Damage.EnvironmentSource”Damage originating from the environment.
| Method | Return Type | Description |
|---|---|---|
getType() | @Nonnull String | Returns the environment damage type identifier |
Damage.Particles
Section titled “Damage.Particles”Particle effects for damage impact.
| Method | Return Type | Description |
|---|---|---|
getModelParticles() | @Nullable ModelParticle[] | Returns model particles for the impact |
setModelParticles(@Nullable ModelParticle[] modelParticles) | void | Sets the model particles |
getWorldParticles() | @Nullable WorldParticle[] | Returns world particles for the impact |
setWorldParticles(@Nullable WorldParticle[] worldParticles) | void | Sets the world particles |
getViewDistance() | double | Returns the view distance for particles |
setViewDistance(double viewDistance) | void | Sets the view distance for particles |
Damage.SoundEffect
Section titled “Damage.SoundEffect”Sound effect for damage impact.
| Method | Return Type | Description |
|---|---|---|
getSoundEventIndex() | int | Returns the sound event index |
setSoundEventIndex(int soundEventIndex) | void | Sets the sound event index |
Damage.CameraEffect (record)
Section titled “Damage.CameraEffect (record)”Camera effect for damage impact.
| Method | Return Type | Description |
|---|---|---|
cameraEffectIndex() | int | Returns the camera effect index (record component) |
getEffectIndex() | int | Returns the camera effect index |
Meta Keys
Section titled “Meta Keys”Additional data accessible via damage.getIfPresentMetaObject(key):
Damage.HIT_LOCATION-Vector4dDamage.HIT_ANGLE-FloatDamage.IMPACT_PARTICLES-Damage.ParticlesDamage.IMPACT_SOUND_EFFECT-Damage.SoundEffectDamage.PLAYER_IMPACT_SOUND_EFFECT-Damage.SoundEffectDamage.CAMERA_EFFECT-Damage.CameraEffectDamage.DEATH_ICON-StringDamage.BLOCKED-Boolean(default:false)Damage.STAMINA_DRAIN_MULTIPLIER-FloatDamage.CAN_BE_PREDICTED-Boolean(default:false)Damage.KNOCKBACK_COMPONENT-KnockbackComponent
Usage Example
Section titled “Usage Example”Damage.Source source = damage.getSource();if (source instanceof Damage.EntitySource entitySource) { Ref<EntityStore> attackerRef = entitySource.getRef();}if (source instanceof Damage.ProjectileSource projectileSource) { Ref<EntityStore> projectile = projectileSource.getProjectile();}if (source instanceof Damage.CommandSource cmdSource) { // command-initiated damage}if (source instanceof Damage.EnvironmentSource envSource) { String type = envSource.getType();}Block Events
Section titled “Block Events”Block events fire during player interaction chains. The flow depends on game mode:
- Adventure mode —
DamageBlockEventfires on each hit. When the block’s health reaches zero,BreakBlockEventfires. - Creative mode —
BreakBlockEventfires immediately (no damage phase). - Placing —
PlaceBlockEventfires after validation (Y range, collision, WorldConfig flags). - Using —
UseBlockEvent.Prefires before the block’s interaction chain,UseBlockEvent.Postfires after.
setTargetBlock() on BreakBlockEvent, PlaceBlockEvent, and DamageBlockEvent lets listeners redirect the operation to a different position — the server reads the value back after dispatch.
BreakBlockEvent
Section titled “BreakBlockEvent”Fired when a block is broken.
Class: com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getItemInHand() | @Nullable ItemStack | Item held when breaking, or null if empty |
getTargetBlock() | @Nonnull Vector3i | Position of the block being broken |
setTargetBlock(@Nonnull Vector3i) | void | Redirect the break to a different position |
getBlockType() | @Nonnull BlockType | Type of block being broken |
PlaceBlockEvent
Section titled “PlaceBlockEvent”Fired when a block is placed.
Class: com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getItemInHand() | @Nullable ItemStack | Item held when placing, or null if empty |
getTargetBlock() | @Nonnull Vector3i | Position where the block will be placed |
setTargetBlock(@Nonnull Vector3i) | void | Redirect the placement to a different position |
getRotation() | @Nonnull RotationTuple | Rotation of the placed block |
setRotation(@Nonnull RotationTuple) | void | Override the placed block’s rotation |
DamageBlockEvent
Section titled “DamageBlockEvent”Fired when a block takes damage (during mining in adventure mode). Fires every hit — use setDamage() to modify the damage dealt, which the server reads back after dispatch.
Class: com.hypixel.hytale.server.core.event.events.ecs.DamageBlockEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getItemInHand() | @Nullable ItemStack | Item held when damaging, or null if empty |
getTargetBlock() | @Nonnull Vector3i | Position of the block being damaged |
setTargetBlock(@Nonnull Vector3i) | void | Redirect the damage to a different position |
getBlockType() | @Nonnull BlockType | Type of block being damaged |
getCurrentDamage() | float | Accumulated damage on the block before this hit |
getDamage() | float | Damage this hit will deal |
setDamage(float) | void | Modify the damage this hit will deal |
UseBlockEvent
Section titled “UseBlockEvent”Fired when a block is used/interacted with. Has Pre and Post phases.
Class: com.hypixel.hytale.server.core.event.events.ecs.UseBlockEvent
Methods (Base Class)
Section titled “Methods (Base Class)”| Method | Return Type | Description |
|---|---|---|
getInteractionType() | @Nonnull InteractionType | Type of interaction |
getContext() | @Nonnull InteractionContext | Interaction context (contains entity ref via getEntity()) |
getTargetBlock() | @Nonnull Vector3i | Position of the block being used |
getBlockType() | @Nonnull BlockType | Type of block being used |
UseBlockEvent.Pre
Section titled “UseBlockEvent.Pre”Fired before the block interaction occurs. This event is cancellable.
Inherits all methods from UseBlockEvent.
UseBlockEvent.Post
Section titled “UseBlockEvent.Post”Fired after the block interaction occurs. Not cancellable.
Inherits all methods from UseBlockEvent.
Accessing Entity
Section titled “Accessing Entity”// useBlockEvent provides entity access through contextRef<EntityStore> entityRef = event.getContext().getEntity();DropItemEvent
Section titled “DropItemEvent”Fired when items are dropped. Has subclasses for different drop types.
Class: com.hypixel.hytale.server.core.event.events.ecs.DropItemEvent
This event is cancellable.
Subclasses
Section titled “Subclasses”DropItemEvent.PlayerRequest
Section titled “DropItemEvent.PlayerRequest”Fired when a player requests to drop an item from their inventory. This event is cancellable.
| Method | Return Type | Description |
|---|---|---|
getInventorySectionId() | int | Returns the inventory section identifier |
getSlotId() | short | Returns the slot ID of the item to drop |
DropItemEvent.Drop
Section titled “DropItemEvent.Drop”Fired when an item is actually being dropped into the world. This event is cancellable.
| Method | Return Type | Description |
|---|---|---|
getItemStack() | @Nonnull ItemStack | Returns the item stack being dropped |
setItemStack(@Nonnull ItemStack itemStack) | void | Sets the item stack to drop |
getThrowSpeed() | float | Returns the throw speed of the dropped item |
setThrowSpeed(float throwSpeed) | void | Sets the throw speed of the dropped item |
InteractivelyPickupItemEvent
Section titled “InteractivelyPickupItemEvent”Fired when an item is picked up interactively.
Class: com.hypixel.hytale.server.core.event.events.ecs.InteractivelyPickupItemEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getItemStack() | @Nonnull ItemStack | Returns the item stack being picked up |
setItemStack(@Nonnull ItemStack itemStack) | void | Sets the item stack being picked up |
SwitchActiveSlotEvent
Section titled “SwitchActiveSlotEvent”Fired when hotbar slot changes.
Class: com.hypixel.hytale.server.core.event.events.ecs.SwitchActiveSlotEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getInventorySectionId() | int | Returns the inventory section identifier |
getPreviousSlot() | int | Returns the previously active slot index |
getNewSlot() | byte | Returns the new slot index to switch to |
setNewSlot(byte newSlot) | void | Sets the new slot index to switch to |
isServerRequest() | boolean | Returns true if the slot change was initiated by the server |
isClientRequest() | boolean | Returns true if the slot change was initiated by the client |
CraftRecipeEvent
Section titled “CraftRecipeEvent”Fired when crafting. Has Pre and Post phases, both cancellable. See Crafting & Recipes for usage examples and scope details.
Class: com.hypixel.hytale.server.core.event.events.ecs.CraftRecipeEvent
This event is cancellable.
Methods (Base Class)
Section titled “Methods (Base Class)”| Method | Return Type | Description |
|---|---|---|
getCraftedRecipe() | @Nonnull CraftingRecipe | Returns the recipe being crafted |
getQuantity() | int | Returns the quantity being crafted |
Subclasses
Section titled “Subclasses”CraftRecipeEvent.Pre
Section titled “CraftRecipeEvent.Pre”Fired before crafting occurs. Cancel to prevent crafting. This event is cancellable.
Inherits all methods from CraftRecipeEvent.
CraftRecipeEvent.Post
Section titled “CraftRecipeEvent.Post”Fired after crafting occurs. Cancel to prevent giving the crafted item. This event is cancellable.
Inherits all methods from CraftRecipeEvent.
DiscoverZoneEvent
Section titled “DiscoverZoneEvent”Fired when a zone is discovered. Base class is not cancellable.
Class: com.hypixel.hytale.server.core.event.events.ecs.DiscoverZoneEvent
Methods (Base Class)
Section titled “Methods (Base Class)”| Method | Return Type | Description |
|---|---|---|
getDiscoveryInfo() | @Nonnull WorldMapTracker.ZoneDiscoveryInfo | Returns information about the discovered zone |
Subclasses
Section titled “Subclasses”DiscoverZoneEvent.Display
Section titled “DiscoverZoneEvent.Display”Fired when zone discovery UI would be shown. This event is cancellable.
Inherits all methods from DiscoverZoneEvent.
ChangeGameModeEvent
Section titled “ChangeGameModeEvent”Fired when game mode changes.
Class: com.hypixel.hytale.server.core.event.events.ecs.ChangeGameModeEvent
This event is cancellable.
Methods
Section titled “Methods”| Method | Return Type | Description |
|---|---|---|
getGameMode() | @Nonnull GameMode | Returns the game mode being changed to |
setGameMode(@Nonnull GameMode gameMode) | void | Sets the game mode to change to |