Skip to content

Event System

Package: com.hypixel.hytale.event (infrastructure) + com.hypixel.hytale.server.core.event.events (concrete events)

Hytale has a dual event system with two parallel hierarchies that use completely separate dispatch mechanisms.

Standard events implement IEvent<KeyType> (synchronous) or IAsyncEvent<KeyType> (asynchronous) and are dispatched through the EventBus. Registration uses Consumer-based callbacks — no annotations.

// In a plugin's setup() or start() method:
getEventRegistry().register(BreakBlockEvent.class, event -> {
BlockType blockType = event.getBlockType();
if (event.isCancelled()) return;
// handle event
});
// With priority:
getEventRegistry().register(EventPriority.EARLY, PlayerChatEvent.class, event -> {
// runs before NORMAL priority listeners
});
// Async event (PlayerChatEvent implements IAsyncEvent):
getEventRegistry().registerAsync(PlayerChatEvent.class, future -> {
return future.thenApply(event -> {
event.setContent(event.getContent().toUpperCase());
return event;
});
});
MethodDispatchScope
register(Class, Consumer)SyncKeyed (specific key)
registerGlobal(Class, Consumer)SyncAll keys
registerUnhandled(Class, Consumer)SyncFallback (no specific listeners)
registerAsync(Class, Function)AsyncKeyed
registerAsyncGlobal(Class, Function)AsyncAll keys
registerAsyncUnhandled(Class, Function)AsyncFallback

Each family has 3 overloads: default priority, EventPriority enum, raw short priority.

PriorityValueDescription
FIRST-21844Highest priority, runs earliest
EARLY-10922Before normal
NORMAL0Default
LATE10922After normal
LAST21844Lowest priority, runs last

Raw short values allow custom priorities between enum values.

Events have a KeyType generic parameter:

  • KeyType=Void — Unkeyed (global dispatch). Example: BootEvent, ShutdownEvent.
  • KeyType=String — Can be dispatched for specific string keys. Example: PlayerReadyEvent, AddPlayerToWorldEvent. Listeners can register for a specific key or use registerGlobal() to receive all keys.

ECS events extend EcsEvent (or CancellableEcsEvent) and are dispatched through the ECS system pipeline using store.invoke(). They do not use the EventBus — this is a completely separate dispatch mechanism.

ECS events are handled by EntityEventSystem subclasses that declare a Query to filter which entities receive the event. Only entities whose archetype matches the system’s query will trigger the handler.

// Entity-level dispatch (most common):
store.invoke(ref, event);
componentAccessor.invoke(ref, event);
// Store-level dispatch:
store.invoke(event);

There are two separate cancellation interfaces with identical method signatures:

InterfaceHierarchyMethods
ICancellableStandard events (IEvent)isCancelled(), setCancelled(boolean)
ICancellableEcsEventECS events (EcsEvent)isCancelled(), setCancelled(boolean)
IBaseEvent<KeyType>
├── IEvent<KeyType> (synchronous)
│ ├── EntityEvent<EntityType, KeyType>
│ │ ├── EntityRemoveEvent
│ │ ├── LivingEntityInventoryChangeEvent
│ │ └── LivingEntityUseBlockEvent (deprecated)
│ ├── PlayerEvent<KeyType>
│ │ ├── PlayerReadyEvent
│ │ ├── PlayerCraftEvent (deprecated)
│ │ ├── PlayerInteractEvent (deprecated)
│ │ ├── PlayerMouseButtonEvent
│ │ └── PlayerMouseMotionEvent
│ ├── PlayerRefEvent<KeyType>
│ │ └── PlayerDisconnectEvent
│ ├── PlayerPermissionChangeEvent
│ │ ├── .GroupAdded
│ │ ├── .GroupRemoved
│ │ ├── .PermissionsAdded
│ │ └── .PermissionsRemoved
│ ├── PlayerGroupEvent
│ │ ├── .Added
│ │ └── .Removed
│ ├── GroupPermissionChangeEvent
│ │ ├── .Added
│ │ └── .Removed
│ ├── BootEvent
│ ├── ShutdownEvent
│ ├── PrepareUniverseEvent (deprecated)
│ ├── PlayerConnectEvent
│ ├── PlayerSetupConnectEvent (+ ICancellable)
│ ├── PlayerSetupDisconnectEvent
│ ├── PlayerChatEvent (IAsyncEvent + ICancellable)
│ ├── AddPlayerToWorldEvent
│ └── DrainPlayerFromWorldEvent
└── IAsyncEvent<KeyType> (asynchronous)
└── PlayerChatEvent
EcsEvent
├── CancellableEcsEvent (+ ICancellableEcsEvent)
│ ├── BreakBlockEvent
│ ├── PlaceBlockEvent
│ ├── DamageBlockEvent
│ ├── ChangeGameModeEvent
│ ├── SwitchActiveSlotEvent
│ ├── InteractivelyPickupItemEvent
│ ├── DropItemEvent
│ │ ├── .Drop
│ │ └── .PlayerRequest
│ └── CraftRecipeEvent
│ ├── .Pre
│ └── .Post
├── UseBlockEvent
│ ├── .Pre (+ ICancellableEcsEvent)
│ └── .Post
└── DiscoverZoneEvent
└── .Display (+ ICancellableEcsEvent)
EventTypeCancellableDescription
BootEventStandardNoServer boot lifecycle
ShutdownEventStandardNoServer shutdown lifecycle
PrepareUniverseEventStandardNoUniverse initialization (deprecated)
EventTypeCancellableDescription
PlayerSetupConnectEventStandardYesEarly connection (before player entity)
PlayerConnectEventStandardNoPlayer entity created and connected
PlayerDisconnectEventStandardNoPlayer disconnects
PlayerSetupDisconnectEventStandardNoSetup-phase disconnect
AddPlayerToWorldEventStandardNoPlayer enters a world
DrainPlayerFromWorldEventStandardNoPlayer leaves a world
PlayerReadyEventStandardNoPlayer signals readiness
PlayerChatEventAsyncYesPlayer sends chat message
PlayerMouseButtonEventStandardYesMouse button press/release
PlayerMouseMotionEventStandardYesMouse drag events
PlayerCraftEventStandardNoCrafting (deprecated)
PlayerInteractEventStandardYesInteraction (deprecated)
EventTypeCancellableDescription
BreakBlockEventECSYesPlayer finishes mining a block
PlaceBlockEventECSYesPlayer places a block
DamageBlockEventECSYesMining progress tick
UseBlockEventECSPre: YesBlock interaction (Pre/Post)
ChangeGameModeEventECSYesGame mode change
SwitchActiveSlotEventECSYesHotbar slot change
InteractivelyPickupItemEventECSYesItem pickup
DropItemEventECSYesItem drop (PlayerRequest/Drop)
CraftRecipeEventECSYesCrafting (Pre/Post)
DiscoverZoneEventECSDisplay: YesZone discovery
EventTypeCancellableDescription
EntityRemoveEventStandardNoEntity removed from world
LivingEntityInventoryChangeEventStandardNoInventory contents changed
LivingEntityUseBlockEventStandardNoBlock use (deprecated)
EventTypeCancellableDescription
GroupPermissionChangeEventStandardNoGroup permissions changed (Added/Removed)
PlayerGroupEventStandardNoPlayer group membership changed (Added/Removed)
PlayerPermissionChangeEventStandardNoPlayer permissions changed (GroupAdded/GroupRemoved/PermissionsAdded/PermissionsRemoved)