Skip to main content
The event system in PocketMine-MP allows plugins to react to actions that occur in the server. Events are called when something happens (like a player joining, a block breaking, etc.), and plugins can register listeners to handle these events.

Core Event Classes

Event

The base class for all events in PocketMine-MP.
getEventName()
string
Returns the name of the event class
call()
void
Calls all registered event handlers for this event
hasHandlers()
bool
Returns whether any handlers are registered for this event class. Useful for optimizing hot code paths to avoid unnecessary event object creation.

Cancellable

Interface implemented by events that can be cancelled. Cancelling an event prevents its action from occurring.
isCancelled()
bool
Returns whether the event is currently cancelled
cancel()
void
Cancels the event (provided by CancellableTrait)
uncancel()
void
Uncancels the event (provided by CancellableTrait)

Event Priorities

Event handlers are called in priority order:
  1. LOWEST (5) - Called first, allows other plugins to customize the outcome
  2. LOW (4) - Low importance
  3. NORMAL (3) - Default priority
  4. HIGH (2) - High importance
  5. HIGHEST (1) - Critical, has final say
  6. MONITOR (0) - Called last, for monitoring only (should not modify the event)

Creating Event Listeners

To listen to events, create a class that implements the Listener interface:
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\plugin\PluginBase;

class MyPlugin extends PluginBase implements Listener {
    
    public function onEnable() : void {
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }
    
    public function onPlayerJoin(PlayerJoinEvent $event) : void {
        $player = $event->getPlayer();
        $player->sendMessage("Welcome to the server!");
    }
}

Event Handler Requirements

For a method to be recognized as an event handler, it must:
  • Be public
  • Not be static
  • Accept exactly one parameter of an Event type (or its subclass)
  • The event parameter must not be abstract (unless annotated with @allowHandle)

Handler Annotations

You can use PHPDoc annotations to control handler behavior:
/**
 * @priority HIGHEST
 * @handleCancelled
 */
public function onPlayerChat(PlayerChatEvent $event) : void {
    // This handler runs at HIGHEST priority
    // and will be called even if the event is cancelled
}

/**
 * @notHandler
 */
public function onPlayerMove(PlayerMoveEvent $event) : void {
    // This method will NOT be registered as an event handler
    // even though it meets the criteria
}
Available annotations:
  • @priority <PRIORITY> - Sets the priority (LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR)
  • @handleCancelled - Handler will be called even if the event is cancelled
  • @notHandler - Prevents a method from being registered as a handler

Registering Events

There are two ways to register event listeners:

Method 1: Class implements Listener

class MyListener implements Listener {
    public function onBlockBreak(BlockBreakEvent $event) : void {
        // Handle event
    }
}

// Register in your plugin's onEnable()
$this->getServer()->getPluginManager()->registerEvents(new MyListener(), $this);

Method 2: Manual registration

use pocketmine\event\EventPriority;

$this->getServer()->getPluginManager()->registerEvent(
    PlayerJoinEvent::class,
    function(PlayerJoinEvent $event) : void {
        $event->getPlayer()->sendMessage("Welcome!");
    },
    EventPriority::NORMAL,
    $this
);

Event Inheritance

Event handlers receive the specified event and all its subclasses. For example:
public function onEntityDamage(EntityDamageEvent $event) : void {
    // This will be called for:
    // - EntityDamageEvent
    // - EntityDamageByEntityEvent (extends EntityDamageEvent)
    // - EntityDamageByBlockEvent (extends EntityDamageEvent)
    // - And all other EntityDamageEvent subclasses
    
    if ($event instanceof EntityDamageByEntityEvent) {
        $damager = $event->getDamager();
        // Handle entity-on-entity damage specifically
    }
}

Performance Optimization

Use Event::hasHandlers() to avoid creating event objects unnecessarily:
if (PlayerMoveEvent::hasHandlers()) {
    $event = new PlayerMoveEvent($player, $from, $to);
    $event->call();
    
    if ($event->isCancelled()) {
        // Handle cancellation
    }
}

Base Event Categories

Player Events

Events related to player actions and state changes

Block Events

Events related to block placement, breaking, and changes

Entity Events

Events related to entity spawning, damage, and behavior

World Events

Events related to world loading, chunks, and changes

Server Events

Events related to server operations and networking

Build docs developers (and LLMs) love