Reference
Event reference
The closed list of things a plugin can be told: the variants of Event in
crates/rustmc-plugin/src/event.rs. Fifty events. 44 of them are also a
hook point with the same name. The other six (player_look, player_input
and the four creature_*) are told only to the plugin that asked for them or owns the creature.
How they are delivered:
- A plugin hears the events its manifest names in
events. An empty or missing list hears all of them. - Plugins run in priority order:
first,early,normal,late,observer. The first cancel wins and the rest still run. Afirstplugin's cancel of a cancellable event ends it: onlyobservers are told after it. - Cancelling an event that is not cancellable is ignored.
- A handler that fails (a trap, a panic, out of fuel) counts as having passed, unless the manifest
lists the event in
fail_closed: then it counts as a cancel. - A Wasm guest receives each event as one JSON object: the fields below, plus
"event": "<name>". Positions are[x, y, z], ids are integers, worlds are names, an account is 32 hex digits, and a missing optional (?) isnull. - An event a Wasm guest causes with its own host call (
damage_sayingkilling something,set_block) is queued and told as soon as that call returns. The guest cannot cancel it: the step has already happened.
A ? marks a field that may be null.
| Name | Fields | Cancellable |
|---|---|---|
server_started | none | no |
server_stopping | none | no |
player_joined | player, name | no |
player_left | player, name | no |
player_payload | player, channel, data (the bytes; to a Wasm guest a list of byte values, the form send_payload takes). Every channel but minecraft:brand | no |
player_chat | player, message | yes: the message is not sent |
command_run | player?, command, rest | yes: built-in commands do not run |
block_break | player, world, at, block (the name), state (the whole state, minecraft:oak_stairs[facing=east,...], as set_block reads it) | yes: the block stays |
block_place | player, world, at, block, state (as for block_break) | yes: nothing is placed |
player_interact | player, world, at, face, holding (with components), hand (main or off: one right-click can come from each), sneaking | yes |
damage | victim, attacker?, cause, amount | yes: no damage is taken |
death | victim, killer?, message | no |
player_move_block | player, world, from, to | no |
game_mode_changed | player, mode (survival, creative, adventure, spectator) | no |
inspect_change | player (the staff member), account (the target's, 32 hex digits), name, view, changes (item, count) | no |
container_change | player, world, at, block, changes (item, count) | no |
entity_interact | player, target, kind, hand, sneaking | yes: nothing happens |
block_hit | player, world, at, face (down, up, north, south, west, east), hand (main) | yes: the dig does not start, and its finish is refused |
entity_attack | player, target, kind | yes: nothing is struck |
reserved_exploded | world, at (the blast's centre), blocks | no |
ores_exploded | world, at (the blast's centre), player?, nearby (player, distance), blocks (at, block) | no |
blocks_pushed | world, moved (from, to, block, for each block a piston carries; never its arm) | no |
inventory_click | player, slot? (the player's own slot, as inventory_slot numbers it; none for a container's), click (Bukkit's ClickType, lower case: left, swap_offhand, ...) | yes: nothing moves, and the window is sent back |
player_swing | player, hand (main) | yes: nobody else sees the swing and the attack charge is kept |
player_use_item | player, world, holding (with components), hand (main or off), sneaking | yes: the item is not used |
player_swap_hands | player, main_hand, off_hand (the stacks about to change places) | yes: neither moves |
player_drop_item | player, slot (0-8), item (the stack in the slot), whole_stack | yes: it stays in the hand |
player_pickup_item | player, entity (the item entity), item, count, components, world, at, own (they threw it or died with it) | yes: it stays on the ground |
player_hotbar_change | player, from, to (0-8) | yes: the old slot stays selected |
player_look | player, yaw, pitch | no |
player_input | player, forward, backward, left, right, jump, sneak, sprint | no |
entity_mounted | rider, vehicle (entity ids; a player's is their player id) | yes: it stays off |
entity_dismounted | rider, vehicle | yes, when the rider crouched or a plugin's dismount asked: it stays on |
player_edit | player, world, at, action (bucket_empty, bucket_fill, ignite, place_entity, place_partner, sign_edit, projectile) | yes: it does not happen |
entity_harm | player, target, kind, world, at, cause | yes: no hurt |
mob_death | victim, kind, world, at, killer?, cause (the last blow's damage type; minecraft:generic for none) | no |
world_changed | player, from, to | no |
item_crafted | player, item, count, recipe | no |
fish_caught | player, item, world, at, table | yes: nothing comes up |
loot_generated | source (container or entity), table, world, at, player?, entity?, slots?, items (item, count) | yes: the container stays empty, the creature drops nothing from its table |
advancement_done | player, advancement | no |
statistic_changed | player, stat, key, value, amount | no |
settings_changed | plugin, keys | no |
player_resource_pack | player, pack (its UUID), status (accepted, declined, downloaded, loaded, failed_download, failed_reload, discarded, invalid_url) | no |
player_respawn | player, world, at | no |
creature_order_done | entity, order, outcome (reached, blocked, no_path, target_gone, out_of_range, replaced, died, removed) | no |
creature_sees | entity, target, kind (minecraft:player or the creature's type) | no |
creature_damaged | entity, attacker?, cause, amount, health | no |
creature_gone | entity | no |
network_message | from (the publishing server's network name), channel, payload (base64 to a Wasm guest). Told only to plugins that network_subscribed to the channel, on the tick after it arrived | no |
tick | tick | no |
loot_generated is told whenever a container's table is rolled for one of these: a player
opening it (player set), a hopper about to pull from or push into it, or the block breaking
(both with no player, as the game's unpackLootTable(null) has none). A chest or hopper
minecart is told when a player opens it. Other readers that roll a table on first look -- a
comparator, /data, /loot, a crafter or dispenser reaching a loot chest -- roll it untold.
Every creature's death drops are told too, with the table, the victim and the player who killed it.
To change the stacks, hook it: a prepend's items are what is placed, so a plugin adds or
removes stacks there. A stack left as it was rolled keeps its enchantments and name. A new
stack is split at its item's stack size (a count of 5000 diamonds is 79 stacks), a count of
nought or less is ignored, and new stacks go into the slots the roll left empty; what does not
fit in the container is dropped and logged.
statistic_changed is told for every counter the statistics screen shows except the five
that move every tick (play_time, total_world_time, time_since_death, time_since_rest,
sneak_time), which would be a hundred events a second per player; read those when you need
them. Even so it is the busiest event there is -- a moving player counts distance on every
movement packet, up to twenty a second per kind of movement -- so hear it only if you need it.
With nothing hearing or hooking it, it costs nothing.
A Wasm guest receives the same fields as flat JSON, plus "event": "<name>". Positions are
[x, y, z]. A holding stack is {item, count, damage, components, slot, stamp}, the
components each id and its SNBT as inventory_slot reports them, slot where it is held (0-8
the hotbar, 40 the off hand, as inventory_slot numbers it) and stamp its stamp (empty for an
empty hand) -- what edit_slot takes, so a plugin can edit the stack it was told about without
reading it again.
player_pickup_item is told before an item on the ground goes into a player's inventory, and
only when some of it would fit. Cancelled, it stays where it lies -- for a plugin to take it its
own way (remove_entity takes an item entity away, give_item gives the stack as it likes).
The game tries a pickup every tick a player stands over an item, so a refused one is told again
the next tick while it would still fit.
player_resource_pack is every answer a client gives to a pack -- the server's own or one a
plugin pushed -- progress (accepted, downloaded) as well as the last. An answer given while
the player was still joining is told once they have joined, after player_joined. The game has
already acted on the answer: a declined required pack disconnects them whatever a plugin does.
player_respawn is told once a player is back after dying, where they now stand.
block_hit is told when a player starts digging a block -- any block, one they cannot break
(a barrier, bedrock, a reserved state with no break time) included, and before anything else
about the dig: a note block's punch, a creative or instant break, a reserved block's clock.
Cancelled, nothing of the dig happens, the client is sent the block back, and the finish its own
clock sends later is refused. A held dig on a reserved block whose break a block_break handler
refuses starts again by itself, so it is told as block_break each time, not block_hit.
entity_attack is told for every left click on an entity before anything is struck: a player,
a creature, a vehicle, a stand, and an interaction entity -- a plugin's private one
(spawn_entity_for) included, which nothing else answers. Cancelled, nothing is struck: no
damage, knockback, hunger or wear. The swing's charge is spent either way, as the client spends it.
reserved_exploded is told once a blast is done, if it reached blocks of reserved
states: those are never broken by an explosion (a plugin's block is
its own to break), so the event lists them for their owner to act on -- break them with
set_block, drop something, or leave them. Their own block's resistance still stops the blast.
Pistons treat a reserved block as obsidian: never pushed or pulled.
game_mode_changed is also told, and its hook asked, for the mode a player's file brings back as they join, before player_joined. A plugin that overrides the hook with false leaves them in the server's default mode.
ores_exploded is told once a blast is done, if it destroyed anything ending _ore, or ancient
debris. Only ore is listed, because every block of a crater would be a heavy call for each TNT of a
chain. player is who lit the TNT or slept in the bed. It is missing when nobody can be named, as for
TNT lit by redstone or a creature's blast. Then nearby lists the players in that world in survival or
adventure as it went off, nearest first, at most 8, at any distance: a plugin looking later would find
whoever walked up to look. It is a list of who was there, not of who did it. Blocks a claim kept, and
reserved blocks, did not go and are not listed.
The five input events are the keys and buttons that are not a block or a creature. In 26.3:
player_swingis the client'spunchpacket: a left click at the air, or at something out of reach. The client sends nothing else for a swing; a left click on a block is a dig and one on a creature an attack, and neither is told here.player_use_itemis a right click the game reads as the item's: at the air, or after a click on a block the block did nothing with (that one is told asplayer_interactfirst). It is not told for an item that is cooling, which the game does not use;set_item_cooldownstarts a cooldown anditem_cooldownreads one, for the server's items and a plugin's own groups.player_swap_handsandplayer_drop_itemare F and Q outside a screen. Inside one they are aninventory_click. Nothing is told for Q with an empty hand.player_hotbar_changeis a number key or the scroll wheel.player_lookis told only to a plugin that asked withwatch_look(player, true), only about the players it asked about, and at most once a tick per player, with where they look by then (the last of that tick's turns). Nothing is told while they hold still.
The four creature_* events are about the creatures a plugin made with spawn_creature, and
are told only to the plugin that made them (see creatures):
creature_order_doneends every order butidle, once: how it went,replacedwhen another order (or another mind) took its place,died, orremovedwhen the creature left the world another way. Orders that do not end by themselves (wander,follow,look_at) end only so.creature_seesis told for a creature with asight_range, twice a second at most, as a player (and, withsees_creatures, a creature) comes into its line of sight; not again until it has been out of it. Spectators are never seen.creature_damagedis told after every blow that lands, with what came off and what is left. Not cancellable:invulnerablekeeps a creature from harm.creature_goneis told when one leaves the world without dying: its chunk unloaded, the game despawned it, orremove_entitytook it. A death ismob_death, which every plugin may hear.player_inputis told only to a plugin that asked withwatch_input(player, true), only about the players it asked about, once for each change of the keys the client reports (ServerboundPlayerInputPacket): what a vehicle's driver steers with. Nothing while they hold the same keys.entity_mountedis asked before anything gets on anything: a player's click on a saddled horse, a boat or a harnessed happy ghast,/ride, a plugin'smountand a creature a boat scoops up. A plugin'sset_passengersonly tells it.entity_dismountedis asked when a player crouches off and when a plugin'sdismountasks, and only told -- the rider comes off whatever the answer -- for/ride dismount, a spear's stab, a mount that dies or throws its rider, a boat or cart that breaks, andset_passengers. A player disconnecting is not told:player_leftis.
From docs/api/reference/events.md in the RustMC repository at bbd81209ad.