Overview
Minestom’s event system provides a powerful, hierarchical event graph for handling all server events. The system is based on event nodes that can filter and propagate events to listeners.
Core Components
EventNode
Represents a single node in the event graph. A node can contain children and listeners, filtering events based on conditions before propagating them.
Generic event node that accepts events of type T
Creating Event Nodes
All Events
Type Filter
With Condition
Value-Based Filter
// Accept any event type
EventNode < Event > node = EventNode . all ( "demo" );
Node Methods
Calls an event starting from this node
Execute a cancellable event with a success callback Callback executed if event is not cancelled
Adds a listener to this node listener
EventListener<? extends T>
The listener to add
Returns this for method chaining
Removes a listener from this node listener
EventListener<? extends T>
The listener to remove
Adds a child node Returns this for method chaining
Locates all child nodes with the given name and type recursively The event node name to filter for
The event node type to filter for
Sets the priority of this node The priority value (higher = executed first)
EventListener
Represents an event listener (handler) that executes actions when events trigger.
Creating Listeners
Simple Listener
Builder Pattern
Conditional Expiration
// Create a basic listener
EventListener < PlayerLoginEvent > listener = EventListener . of (
PlayerLoginEvent . class ,
event -> {
System . out . println ( event . getPlayer (). getUsername () + " logged in" );
}
);
Builder Methods
Adds a filter condition - listener only executes if condition passes
Specifies whether to ignore cancelled events (default: true) True to stop processing cancelled events
Removes listener after specified executions Number of times to execute before removal
Expires listener when condition is met Condition to test for expiration
Sets the handler function The event handler function
GlobalEventHandler
Object containing all global event listeners. Accessible from MinecraftServer.getGlobalEventHandler().
GlobalEventHandler globalHandler = MinecraftServer . getGlobalEventHandler ();
// Listen to player login globally
globalHandler . addListener ( PlayerLoginEvent . class , event -> {
System . out . println ( "Player joined: " + event . getPlayer (). getUsername ());
});
EventFilter
Represents a filter for specific event types based on a “handler” target.
Built-in Filters
EventFilter.PLAYER
EventFilter<PlayerEvent, Player>
Filters player events, provides Player as handler
EventFilter.ENTITY
EventFilter<EntityEvent, Entity>
Filters entity events, provides Entity as handler
EventFilter.INSTANCE
EventFilter<InstanceEvent, Instance>
Filters instance events, provides Instance as handler
EventFilter.INVENTORY
EventFilter<InventoryEvent, AbstractInventory>
Filters inventory events, provides AbstractInventory as handler
EventFilter.ITEM
EventFilter<ItemEvent, ItemStack>
Filters item events, provides ItemStack as handler
EventFilter.BLOCK
EventFilter<BlockEvent, Block>
Filters block events, provides Block as handler
Custom Filters
EventFilter < MyEvent , MyHandler > customFilter = EventFilter . from (
MyEvent . class ,
MyHandler . class ,
event -> event . getMyHandler ()
);
Usage Examples
Hierarchical Event System
// Create a main event node
EventNode < Event > mainNode = EventNode . all ( "main" );
// Create specialized child nodes
EventNode < PlayerEvent > playerNode = EventNode . type ( "players" , EventFilter . PLAYER );
EventNode < EntityEvent > entityNode = EventNode . type ( "entities" , EventFilter . ENTITY );
// Add children to main node
mainNode . addChild (playerNode);
mainNode . addChild (entityNode);
// Add listeners to child nodes
playerNode . addListener ( PlayerMoveEvent . class , event -> {
// Handle player movement
});
entityNode . addListener ( EntityDeathEvent . class , event -> {
// Handle entity death
});
// Register main node
MinecraftServer . getGlobalEventHandler (). addChild (mainNode);
Instance-Specific Events
Instance instance = /* get instance */ ;
// Get the instance's event node
EventNode < InstanceEvent > instanceNode = instance . eventNode ();
// Listen to events only in this instance
instanceNode . addListener ( PlayerBlockBreakEvent . class , event -> {
// Only called for blocks broken in this instance
});
Tag-Based Filtering
Tag < Boolean > PVP_TAG = Tag . Boolean ( "pvp_enabled" );
// Create node that only accepts events from entities with the tag
EventNode < PlayerEvent > pvpNode = EventNode . tag (
"pvp-zone" ,
EventFilter . PLAYER ,
PVP_TAG,
enabled -> enabled != null && enabled
);
pvpNode . addListener ( PlayerDamageEvent . class , event -> {
// Only called for players with pvp_enabled tag set to true
});
Event nodes are hierarchical - children only receive events that pass through their parent’s filters.