Event Specification
Overview
The Yeow event system is the mechanism by which the runtime delivers game events to plugins. Plugins subscribe to events via event.subscribe, and the runtime delivers event data through the cb channel.
Registration and Unregistration
Plugins manage event subscriptions through the event.subscribe and event.unsubscribe methods on the task channel. See the Event System task specification for details.
Two subscription modes (the mode field of event.subscribe)
mode | Semantics | Runtime behaviour |
|---|---|---|
| absent | intercept | After delivery it waits for event.complete; r carries _eventId, write-back fields (mods) are applied on completion; 5s timeout as backstop |
"watch" | observe | Delivery continues immediately — no _eventId, no waiting, no write-back applied; observers never spin the game thread |
Observers are the default offered to beginners:
yeow-api'seventWatch()sendsmode: "watch", whileeventIntercept()omits the field.permissionCheckwas extracted into its own request/response API (the handler must return{ allowed }), so implementations must route it through the intercept path even when the caller usedeventWatch.Observers and interceptors may coexist for the same event: implementations should deliver observers first (without waiting) and then process interceptors (waiting).
Field Adaptation Rules
In event data:
- The
playerfield holds the player's UUID string; the caller can look up the Player by UUID - The
from,to, andrespawnLocationfields hold location objects of the form{ "x": <double>, "y": <double>, "z": <double>, "yaw": <double>, "pitch": <double>, "world": "<name>" } - Events use the
_cancellablefield to indicate whether they can be cancelled
Event Name Table
All event names use camelCase format. Complete list:
| Event name | Category | Cancellable | Description |
|---|---|---|---|
playerJoin | Player | No | Player joined |
playerQuit | Player | No | Player quit |
playerChat | Player | Yes | Player chatted |
playerMove | Player | Yes | Player moved |
playerInteract | Player | Yes | Player interacted |
playerCommand | Player | Yes | Player ran a command |
playerDeath | Player | No | Player died |
playerRespawn | Player | No | Player respawned |
playerTeleport | Player | Yes | Player teleported |
playerItemConsume | Player | Yes | Player consumed an item |
playerDropItem | Player | Yes | Player dropped an item |
playerPickupItem | Player | Yes | Player picked up an item |
playerBucketFill | Player | Yes | Player filled a bucket with liquid |
playerBucketEmpty | Player | Yes | Player emptied a bucket |
playerExpChange | Player | No | Player experience changed |
playerLevelChange | Player | No | Player level changed |
playerGameModeChange | Player | No | Player game mode changed |
playerAdvancementDone | Player | No | Player completed an advancement |
playerToggleSneak | Player | No | Player toggled sneaking |
playerToggleFlight | Player | No | Player toggled flying |
foodLevelChange | Player | Yes | Player hunger changed |
entityDamage | Entity | Yes | Entity damaged |
entityDeath | Entity | No | Entity died |
entitySpawn | Entity | No | Entity spawned |
entityExplode | Entity | Yes | Entity exploded |
entityRegainHealth | Entity | No | Entity regained health |
entityTarget | Entity | No | Entity changed target |
projectileLaunch | Entity | No | Projectile launched |
projectileHit | Entity | No | Projectile hit |
blockBreak | Block | Yes | Block broken |
blockPlace | Block | Yes | Block placed |
blockFade | Block | Yes | Block faded |
blockGrow | Block | No | Block grew |
blockSpread | Block | No | Block spread |
blockExplode | Block | Yes | Block exploded |
inventoryOpen | Inventory | Yes | Inventory opened |
inventoryClose | Inventory | No | Inventory closed |
inventoryClick | Inventory | Yes | Inventory clicked |
serverPing | Server | No | Server pinged |
serverCommand | Server | Yes | Console command |
playerResourcePackStatus | Resource Pack | No | Resource pack status changed |
Permission Check (separate channel, not an event)
Ordinary plugins should not register a checker: it is asked on every Yeow permission check and the main thread spins while waiting — this is an extension point reserved for permission management plugins.
The Yeow ecosystem permission check is request/response: no event object, nothing to cancel, no observer mode — so it does not belong to the event system. It uses dedicated task types on the task channel:
| Task type | Payload | Meaning |
|---|---|---|
permission.subscribeCheck | { pluginName, callbackId } | Register a checker (results are delivered to callbackId as a cb frame) |
permission.unsubscribeCheck | { pluginName } | Remove every checker of that plugin |
permission.complete | { checkId, allowed } | Answer one check (no reply; omitting allowed means "not handled") |
The runtime delivers:
$hm(t="cb", p="<callbackId>", r={ "target": "<uuid|CONSOLE>", "node": "myplugin.home",
"permission": { "node": "myplugin.home", "default": "all" }, "_checkId": "perm#1" })_checkId must be passed back to permission.complete. While waiting, the implementation must drain the scheduler (same spin as event dispatch); the timeout follows profile.callback-timeout-event-ms (5s default, treated as "not handled").
- Trigger scope (Yeow ecosystem only): the
player.hasPermissiontask and the execution-time check of Yeow-registered commands; other Java plugins'hasPermission/ command execution never triggers it - Priority: an answer overrides Paper-side
hasPermission; otherwise it falls back to Paper; with several checkers the last answer wins - Node fusion: nodes are still registered into the Paper permission system (classic plugins / permission plugins can manage them)
- API wrapper:
onPermissionCheck(handler)(yeow-api, see Permission)
| Field | Type | Meaning |
|---|---|---|
target | string | Subject: a player UUID or "CONSOLE" |
node | string | Permission node (e.g. myplugin.home) |
permission | object | { node, default? } (default is the registered default, omitted when unregistered) |
_checkId | string | Unique id of this check; pass it back in the answer |
Module Documentation
| Module | Description |
|---|---|
| player-events | 21 player events |
| entity-events | 6 entity events + 2 projectile events |
| block-events | 6 block events |
| inventory-events | 3 inventory events |
| server-events | 3 server events |