Everything here goes through the vanilla client paths, so packets, swing timers and sequence numbers come out right. For raw wire-format control see Packets.
Hands are "main" / "off" (default "main"), sides are "up" · "down" · "north" ·
"south" · "east" · "west" (default "up"), and interactions return "success" ·
"fail" · "pass".
| Function | Does |
|---|---|
interaction.gamemode() |
Current game mode, e.g. "survival" |
interaction.attack(entity_id) |
Attacks an entity with a main-hand swing |
interaction.interact(entity_id[, hand]) |
Right-clicks an entity |
interaction.use_item([hand]) |
Uses the held item |
interaction.attack_with_piercing_weapon([hand]) |
Spear stab or lunge, false when not holding one |
interaction.use_block(pos[, side[, hand[, point]]]) |
Right-clicks a block; point is the exact hit position sent in the packet (default block center) — pass the raycast intersection to match your server-visible rotation |
interaction.stop_using() |
Releases a bow, stops eating, lowers a shield |
interaction.swing([hand]) |
Swings an arm: animation plus packet |
interaction.pick_block(pos[, include_data]) |
Pick-block |
interaction.pick_entity(entity_id[, include_data]) |
Pick-block on an entity |
Breaking
| Function | Does |
|---|---|
interaction.attack_block(pos[, side]) |
Starts breaking |
interaction.update_breaking(pos[, side]) |
Continues breaking, call every tick while holding |
interaction.cancel_breaking() |
Aborts |
interaction.break_block(pos) |
Finishes instantly, in creative or when fully cracked |
interaction.breaking() |
true while breaking |
interaction.breaking_progress() |
Stage 0–10, -1 when idle |
Screen handlers
| Function | Does |
|---|---|
interaction.sync_id() |
Sync id of the open handler, 0 for the inventory |
interaction.click_slot(sync_id, slot, button[, action]) |
Clicks a slot like a mouse click |
interaction.click_button(sync_id, button) |
Clicks a handler button: stonecutter, loom, … |
Actions are "pickup" (default), "quick_move" (shift-click), "swap" (button is hotbar
0–8, or 40 for the offhand), "clone", "throw", "quick_craft" and "pickup_all".
slot is a handler index, which container reads. To close a screen,
call screen.close().
module:event("pre_interaction", function()
for _, p in ipairs(world:players() or {}) do
if not p:is_self() and p:distance() < 3 then
interaction.attack(p:id())
break
end
end
end)