Altay
Plugins

Events

Listeners, priorities, cancellation, and the order everything happens in.

Events are how a plugin changes behaviour without touching server code. Something is about to happen, every registered handler gets a look at it, and then the server does it, unless somebody said not to.

Registering a listener

A listener is any class implementing Listener. Register it once, usually in onEnable():

use pocketmine\event\Listener;
use pocketmine\plugin\PluginBase;

class Main extends PluginBase implements Listener{

    protected function onEnable() : void{
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }
}

The second argument is the plugin that owns the listener, so the server can unregister everything when the plugin is disabled.

Handlers

Any public method taking exactly one event parameter becomes a handler. The method name is irrelevant; the parameter type is what the server dispatches on.

use pocketmine\event\block\BlockBreakEvent;

public function onBreak(BlockBreakEvent $event) : void{
    $player = $event->getPlayer();

    if(!$player->hasPermission("myplugin.build")){
        $event->cancel();
        $player->sendMessage("Not here.");
    }
}

Two handlers in the same class must not take the same event type. Split them across classes if you genuinely need two.

Cancelling

An event that implements Cancellable can be stopped:

$event->cancel();
$event->isCancelled();

Cancelling prevents the action. It does not undo anything, because nothing has happened yet. That is the whole point of doing it here rather than reacting afterwards.

Events without Cancellable, such as PlayerJoinEvent, describe something that already happened. You can still react, you just cannot stop it.

Priority

Handlers run in priority order. Declare it in the docblock:

/**
 * @priority HIGH
 */
public function onBreak(BlockBreakEvent $event) : void{}
PriorityRunsUse it for
LOWESTfirstSetting up state other plugins will read.
LOWEarly adjustments.
NORMALdefaultAlmost everything.
HIGHOverriding what other plugins decided.
HIGHESTlast before monitorThe final word on whether this happens.
MONITORafter everythingObserving the outcome. Never modify here.

Never modify at MONITOR

MONITOR exists for logging and statistics. Changing the event there breaks every plugin that trusted the order, which is why it is the one rule people will actually shout about.

Cancelled events

By default a handler is skipped once the event has been cancelled. To see cancelled events anyway, for example to log refused actions:

/**
 * @priority MONITOR
 * @handleCancelled
 */
public function onBreakLogged(BlockBreakEvent $event) : void{
    if($event->isCancelled()){
        $this->getLogger()->debug("break refused");
    }
}

Calling your own events

$event = new MyCustomEvent($player);
$event->call();

if(!$event->isCancelled()){
    // proceed
}

Extend Event, add CancellableTrait if it should be cancellable, and other plugins can hook your plugin the same way you hook the server.

Keep handlers cheap

Every handler runs inside the tick. BlockBreakEvent fires for every block every player breaks; PlayerMoveEvent fires several times per second per player.

Nothing slow belongs in a handler. See Async tasks.

The full event list is in the API documentation under pocketmine\event.

On this page