module:event(name, fn) subscribes. The callback gets one table of fields, or nothing when
the event has none. Names are exact snake_case strings.
Three rules cover the whole list:
Cancellable events carry :cancel().
module:event("chat", function(e)
if e.text:find("spam") then
e:cancel() -- drop the message
end
end)Writable fields are read back after the callback. Assign one and the game uses your value.
module:event("input", function(e)
e.jump = true -- jump this tick
end)The table is dead after the callback returns. Copy out what you need; do not store it.
Numbers are plain Lua numbers (integer marks the whole ones), colors are 0xAARRGGBB, and
positions arrive as raw x, y, z scalars rather than vec3. Callbacks run only
while the module is enabled.
Lifecycle
| Event | Fires |
|---|---|
enable |
Module toggled on |
disable |
Module toggled off |
Ticks
| Event | Fields | Notes |
|---|---|---|
tick |
none | Before the player tick. Cancellable |
post_tick |
none | After the player tick |
pre_interaction |
none | Before attacks and item use are processed |
Input
| Event | Fields | Notes |
|---|---|---|
input |
forward, backward, left, right, jump, sneak, sprint — boolean, all writable |
Cancellable. Drives player movement |
key |
key, action, mods — integer |
Cancellable. GLFW key codes |
char |
char — string; codepoint, mods — integer |
Cancellable. Typed character |
mouse_move |
x, y — number |
Cancellable |
mouse_scroll |
horizontal, vertical — number |
Cancellable |
mouse_look |
delta_x, delta_y — number |
Cancellable. Camera rotation by mouse |
cursor_lock |
state — "lock" / "unlock" |
Cancellable |
slot_drag |
slot — integer (-1 outside a slot); button — integer; shift — boolean |
Cancellable |
Chat and text
| Event | Fields | Notes |
|---|---|---|
chat |
text — string |
Cancellable. A message arrived |
chat_send |
text — string |
Cancellable. You are about to send |
title |
text — string; kind — "title" / "subtitle" / "actionbar" |
A title appeared |
boss_bar |
text — string |
Boss bar text changed |
Combat and interaction
| Event | Fields | Notes |
|---|---|---|
attack |
target — entity |
Cancellable. Before you hit |
post_attack |
target — entity |
After the hit |
auto_attack_target |
target — entity or nil, writable |
Cancellable. Auto Attack’s target for this tick |
auto_attack_rotation |
target — entity; yaw, pitch — number, writable |
Cancellable. Auto Attack’s aim before the rotation service sees it |
item_use |
cooldown — integer, writable |
Cancellable |
block_interact |
hand — "main" / "off"; x, y, z — integer; side — string |
Cancellable |
block_place |
hand; x, y, z; side; item — item |
|
block_breaking |
state — "start" / "stop"; block — block id; x, y, z |
The two auto_attack_* events fire each interaction tick while Auto Attack is on, so you can
steer it instead of replacing it:
module:event("auto_attack_target", function(e)
if e.target and e.target:name() == "Bot" then
e:cancel()
end
end)
module:event("auto_attack_rotation", function(e)
e.pitch = e.pitch - 2
end)rotation below sits lower: it fires for every rotation the service applies, including the
one Auto Attack requests here.
Movement
| Event | Fields | Notes |
|---|---|---|
jump |
yaw — number; cooldown — integer; both writable |
Cancellable |
land |
x, y, z, fall_distance — number |
Touched the ground |
slowdown |
multiplier — number, writable |
Cancellable. Slowdown while using an item |
rotation |
yaw, pitch — number, writable; priority — integer, read-only |
Cancellable. Every rotation the service applies |
Network
| Event | Fields | Notes |
|---|---|---|
packet_send |
name — string, plus decoded fields |
Cancellable |
packet_receive |
name — string, plus decoded fields |
Cancellable |
packet_process |
none | Received packets applied to the world |
movement_packets |
none | After movement packets are sent |
player_packets |
none | After player packets are sent |
name is the stable snake_case packet name that packets.send also accepts. Common packets
carry decoded fields too; the full list is on Packets.
module:event("packet_receive", function(e)
if e.name == "entity_velocity" and e.entity_id == player:id() then
e:cancel() -- ignore knockback aimed at us
end
end)World and modules
| Event | Fields |
|---|---|
chunk_load |
x, z — integer, chunk coordinates |
chunk_unload |
x, z — integer |
module_state |
module — string; enabled — boolean |
Rendering
render_2d, render_gui and render_3d receive a drawing object instead of a field table.
| Event | Fields | Notes |
|---|---|---|
frame |
none | Every frame |
render_2d |
2D canvas | Draw over the game |
render_gui |
2D canvas | Draw during GUI screens |
render_3d |
3D renderer | Draw in the world |
camera |
x, y, z, yaw, pitch — number, all writable; tick_progress — number |
Camera pose each frame, after it is positioned. Free Camera moves through this event, so writing the fields overrides it too |
sky_color |
color — writable; original — the value without you |
|
time_of_day |
time — daytime ticks, writable; original — integer |
Visual only |
skybox |
rendered — boolean, writable; true hides the vanilla sky |
|
fog |
red, green, blue, alpha, environmental_start, environmental_end, render_distance_start, render_distance_end — number, all writable |
Color channels are 0..1, the rest are world distances |
window_resize |
width, height — integer |