Packets
Raw network control through the packets global and the packet_send /
packet_receive events.
Minecraft's class names are obfuscated at production runtime, so scripts can't match
packets by Java class name. The mod maintains its own stable snake_case mapping: the
same names appear as e.name in the packet events and are accepted by packets.send.
| Function | What it does |
|---|---|
packets.list() | sorted array of names packets.send can build |
packets.send(name, fields) | builds a C2S packet and sends it; returns true on success |
packets.send returns false for an unknown name or when a required game object is
missing (no world, unknown entity id). The send goes through the normal client pipeline,
so it fires packet_send — a module that cancels its own scripted packets will swallow
them too.
packets.send("move_position", { x = p.x, y = p.y + 0.05, z = p.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 })
packets.send("attack_entity", { entity_id = target.id })
For attacking, block breaking and container clicks prefer the
interaction service — it goes through the vanilla client
paths with correct swing timers and sequence numbers. Raw packets are for when you need
to lie to the server on purpose.
Sendable packets (C2S)
Optional fields show their defaults. hand is "main" / "off" (default "main"),
side is "up" | "down" | "north" | "south" | "east" | "west" (default "up"),
sequence defaults to 0.
| 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", 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 default false |
pick_item_from_block | x, y, z, include_data = false |
pick_item_from_entity | entity_id, include_data = false |
Decoded event fields
packet_send and packet_receive tables always carry name; for the packets below
the payload is decoded too. Everything else still fires — just without extra fields.
Outgoing (packet_send) — all the sendable packets above are decoded back with the
same fields (move_* carry x/y/z only when the packet changes position, yaw/pitch
only when it changes look).
Incoming (packet_receive):
| 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? (present when you were pushed) |
block_update | x, y, z, block — block id |
select_slot | slot |
Note: packet events fire on network threads — collect data and act in
tick, don't call rendering orprojectionfrom them.