The packets global sends; the packet_send and packet_receive events
observe. Fields mirror the wire format, so coordinates arrive as raw x, y, z scalars rather
than vec3.
module:event("packet_receive", function(e)
if e.name == "minecraft:sound" then e:cancel() end -- mute server-played sounds
end)Packets are matched by stable snake_case names, the same strings e.name reports and
packets.send accepts. The events fire for every packet: unmapped ones arrive under their
vanilla protocol id (a name with a colon, like "minecraft:set_entity_motion") carrying no
decoded fields, still cancellable. The names below add decoded fields and packets.send
support.
| Function | Does |
|---|---|
packets.list() |
Sorted names packets.send can build |
packets.send(name, fields) |
Builds and sends a C2S packet, true on success |
packets.send raises on an unknown name and returns false when a required game object is
missing. It goes through the normal client pipeline, so it fires packet_send as well: a
module that cancels its own scripted packets swallows them.
local pos = player:position()
packets.send("move_position", { x = pos.x, y = pos.y + 0.05, z = pos.z, on_ground = false })
packets.send("client_command", { mode = "start_sprinting" })
packets.send("player_action", { action = "swap_item_with_offhand", x = 0, y = 0, z = 0 })
local target = world:player("Notch")
if target then
packets.send("attack_entity", { entity_id = target:id() })
endFor attacking, breaking blocks and clicking slots, interaction is the
better tool: it gets swing timers and sequence numbers right. Raw packets are for when you
want the wire format yourself.
Sendable packets
Optional fields show their defaults. hand is "main" / "off" (default "main"), side
is "up" · "down" · "north" · "south" · "east" · "west" (default "up"), and
sequence defaults to 0.
All 22 sendable packets
| Name | Fields |
|---|---|
move_full |
x, y, z, yaw, pitch, on_ground = true, horizontal_collision = false |
move_position |
x, y, z, on_ground = true, horizontal_collision = false |
move_look |
yaw, pitch, on_ground = true, horizontal_collision = false |
move_on_ground |
on_ground = true, horizontal_collision = false |
client_command |
mode — "stop_sleeping" · "start_sprinting" · "stop_sprinting" · "start_riding_jump" · "stop_riding_jump" · "open_inventory" · "start_fall_flying"; jump_height = 0 |
client_status |
mode — "perform_respawn" · "request_stats" |
hand_swing |
hand |
player_action |
action — "start_destroy_block" · "abort_destroy_block" · "stop_destroy_block" · "drop_all_items" · "drop_item" · "release_use_item" · "swap_item_with_offhand" · "stab"; x, y, z, side, sequence |
attack_entity |
entity_id, sneaking = false |
interact_entity |
entity_id, hand, sneaking = false |
interact_entity_at |
entity_id, x, y, z (hit point), hand, sneaking = false |
interact_block |
x, y, z, side, hit_x/hit_y/hit_z (default block center), inside = false, hand, sequence |
interact_item |
hand, yaw, pitch (default current rotation), sequence |
select_slot |
slot — hotbar 0–8 |
close_screen |
sync_id |
teleport_confirm |
id |
keep_alive |
id |
command |
command — without the leading / |
player_input |
forward, backward, left, right, jump, sneak, sprint — all false |
sign_update |
x, y, z, front = true, line1..line4 = "" — the text a sign editor would submit |
pick_item_from_block |
x, y, z, include_data = false |
pick_item_from_entity |
entity_id, include_data = false |
Decoded event fields
Both events always carry name. The packets below decode their payload too; everything else
fires with name alone.
Outgoing. Most sendable packets decode with the same fields they take, except that
move_* carry x/y/z only when the position changed and yaw/pitch only when the look
changed. Five carry name only: interact_entity, attack_entity, interact_entity_at,
pick_item_from_block, pick_item_from_entity.
Incoming.
All 16 decoded incoming packets
| Name | Fields |
|---|---|
keep_alive |
id |
disconnect |
reason |
player_position_look |
teleport_id, x, y, z, vel_x, vel_y, vel_z, yaw, pitch |
entity_velocity |
entity_id, vel_x, vel_y, vel_z |
entity_position |
entity_id, x, y, z, yaw, pitch, on_ground |
entity_position_sync |
entity_id, x, y, z, yaw, pitch, on_ground |
entity_damage |
entity_id, source_cause_id, source_direct_id |
damage_tilt |
entity_id, yaw |
health_update |
health, food, saturation |
explosion |
x, y, z, radius, knockback_x/y/z? — knockback only when you were pushed |
block_update |
x, y, z, block — block id |
select_slot |
slot |
open_screen |
sync_id, kind — menu type id like "minecraft:generic_9x6"; title |
container_content |
sync_id, revision, size — the server syncing every slot of a handler |
container_slot |
sync_id, revision, slot, item, count — a single slot update |
open_sign_editor |
x, y, z, front — cancel it and answer with sign_update to write a sign without the editor |