Repository navigation
API Events
Lua API / Events
On this page
- betamoon.events:on(name, callback)
- Subscription handle
- subscription:unsubscribe()
- Event catalogue
- world_join
- world_leave
- player_join
- player_leave
- gui_opened
- gui_closed
- gui_tick
- game_tick
- world_tick
- Tick timing
- screen_changed
- key_input
- mouse_input
- block_broken
- block_placed
- item_used
- dimension_changed
- Input context
- Block event context
- Event item reference
- event.item:getId()
- World information
Subscribes callback(event) to a named global event and returns a subscription handle. Event names are trimmed and lowercased. Unknown names or non-function callbacks raise an error. Subscriptions observe events. Lua callback errors are reported.
local subscription = betamoon.events:on("world_join", function(event)
betamoon.chat:send("Entered %s", event.name)
end)active is true while subscribed.
Unsubscribes and changes active to false. Repeated calls are harmless. Script cleanup also unsubscribes tracked listeners.
subscription:unsubscribe()Each event below is subscribed using betamoon.events:on("event_name", callback).
A world becomes active. Context: name (world name), info (world information). Fields are absent if world information is unavailable.
The active world is left. Same world context, describing the departing world.
Player becomes active. Context: name (username when available).
Player leaves. Context: name (departing username when available).
A screen opens. Context: name (new/current screen identifier or nil), previousName (previous screen identifier or nil).
A screen closes. Context uses the current/previous screen names; do not assume name identifies the closed screen.
Runs once after a logical client tick when a GUI/menu/screen is open, including paused singleplayer
screens. Fires after game_tick. Context exposes name (the screen at tick completion) and
previousName where supplied. Requires the BetaMoon Java agent.
Runs once after every logical client tick, including menus, gameplay, and paused or non-pausing screens.
Context: optional worldName and worldInfo; these are absent without an active world. Requires the
BetaMoon Java agent.
Runs after an actual update of the current client world. It stops when singleplayer simulation pauses and continues while a non-pausing screen is open. Remote worlds continue to receive client-world updates; this event does not represent a server tick or grant server-side authority.
Context: name and info (world information), as with world_join. The information
is a detached read-only snapshot. Requires the BetaMoon Java agent.
local clientTicks, worldTicks = 0, 0
betamoon.events:on("game_tick", function(event)
clientTicks = clientTicks + 1
end)
betamoon.events:on("world_tick", function(event)
worldTicks = worldTicks + 1
end)| Client state | game_tick |
gui_tick |
world_tick |
|---|---|---|---|
| Main menu or another screen without a world | Yes | Yes | No |
| World gameplay without a screen | Yes | No | Yes |
| World with a non-pausing screen | Yes | Yes | Yes |
| Paused singleplayer screen | Yes | Yes | No |
| Remote world with a screen | Yes | Yes | When the client world updates |
Logical ticks normally target 20 per second; stalled clients and native catch-up limits affect delivery. Several ticks can run between rendered frames, and a rendered frame can contain no logical tick. These events do not run during blocking loading work when the client tick loop is not advancing.
World services and logical networks update after the native world update, followed by world_tick.
game_tick fires at client-tick completion, followed by gui_tick if a screen was present at that boundary.
The game/GUI contexts use the world/screen captured before publishing the two events; a listener changing
the screen does not add or remove that tick's already-selected GUI notification.
Do not subscribe the same work to both game_tick and gui_tick unless two calls while a screen is open
are intended.
Subscriptions retain explicit unsubscribe and script-cleanup behavior; callback errors are reported and
listeners remain subscribed.
The current screen changes. Context: name and previousName; nil denotes no screen. These values are diagnostic screen identifiers rather than visible titles or stable public IDs.
Keyboard input. Uses input context.
Mouse input. Uses input context.
Successful player block destruction. Uses block event context. Requires the Java agent.
Successful placement. Uses block event context. Requires the Java agent.
Item-use notification. Context: itemId, damage, count snapshots and item (event item reference). Requires the Java agent.
A player dimension transition. Context: integers oldId, newId.
Read these fields directly from the keyboard or mouse event context.
betamoon.events:on("key_input", function(event)
if event.pressed then betamoon.chat:send("Key %d", event.keyCode) end
end)| Field | Type / meaning |
|---|---|
type |
key or mouse. |
keyCode |
Keyboard code; interpret for key events. |
char |
Character string; may contain the null character for non-character events. |
button |
Mouse button; interpret for mouse events. |
x, y
|
Mouse coordinates; interpret for mouse events. |
pressed, released
|
Boolean action flags. |
action |
pressed, held, or released. |
Integer x, y, z, id, damage, side; position contains coordinates. name and displayName are provided when the block can be resolved. Side uses native face numbering, not action-context face strings; it may be unavailable as a sentinel value.
Returns the item ID captured for an item-use event. This small event reference is not a full resource registry reference.
betamoon.events:on("item_used", function(event)
local id = event.item:getId()
end)A snapshot of world-save information. Editing it does not edit the world.
betamoon.events:on("world_join", function(event)
local spawn = event.info.spawnPos
end)| Field | Meaning |
|---|---|
name |
World name. |
seed |
World seed, represented numerically; very large seeds may lose numeric precision. |
getSpawnX, getSpawnY, getSpawnZ
|
Integer spawn coordinates. Despite their names these are properties, not functions. |
spawnPos |
Spawn position with x/y/z. |
worldTime |
Saved world time. |
lastTimePlayed |
Saved last-played timestamp. |
sizeOnDisk |
Saved disk-size metadata. |
dimension |
Saved dimension ID. |
saveVersion |
Save format version. |
raining, thundering
|
Weather flags. |
rainTime, thunderTime
|
Weather timers. |
Examples: All events, input.
- Installation
- Install scripts
- Getting started
- VS Code and LuaLS
- Examples
- Reload and compatibility
- Troubleshooting
- Changelog
Scripts and shared values
- Script lifecycle
- Packaged Lua mods
- Modules
- References and stacks
- Queries
- Overrides
- Minecraft constants
- Chat and positions
- Structured data
- Script configuration
- Particles
Blocks and items
- Multiblocks
- Blocks
- Block state and placement
- Block shapes and rendering
- Block callbacks
- Block ticks and redstone
- Items
- Fluids
- Item callbacks
- Tools and armor
- Materials
- Textures
Entities
- Entities
- Entity access and movement
- Entity lifecycle and data
- Entity health and loot
- Entity inventories and relationships
- Projectiles and pickups
- Entity presentation and sounds
- Living entities and AI
- Entity parts and sensors
Assets and audio
- Assets
- Models and animations
- Built-in Minecraft models
- Model appearances
- Blockbench workflow
- Audio
- Texture-pack overrides
Events and world actions
World generation
World systems
Inventories and screens
Recipes