Two live globals plus domain libraries around them.
if player then
local pos = player:position()
print(("hp %.1f at %.0f %.0f %.0f"):format(player:health(), pos.x, pos.y, pos.z))
end
for _, e in ipairs(world:entities("minecraft:ender_pearl")) do
print(e:id(), e:distance())
endplayer and world
| Global | What it is |
|---|---|
player |
Your player as an entity handle, or nil outside a world |
world |
The loaded world handle, or nil outside a world |
Both re-resolve on every access, so after a respawn or dimension change the next read
already returns the new object. Guard for nil on the title screen:
module:event("tick", function()
if not player then return end
if player:health() < 8 then
hud.notify("Low HP", ("%.1f left"):format(player:health()), "error")
end
end)Your player is a normal entity with extras: self-only readers (food, xp_level,
attack_cooldown, …) and direct control — set_velocity, jump, set_position,
set_rotation, raycast. See entity handle.
Static data (items, translations) lives in game. World coordinates use
vec3 everywhere.
Live handles
Handles are thin wrappers. Every colon-call re-reads the game, so a handle from last tick already answers with this tick’s state.
| Handle | Sources |
|---|---|
| World | world |
| Entity | player, world:players(), world:entities(), world:entity(id) |
| Item | e:held_item(), e:equipped(slot), inventory.item, game.item |
| Block state | world:block_state(pos), block raycast hit’s state |
| Raycast hit | world:raycast(...), world:raycast_entity(...), player:raycast() |
Exception: text components are snapshots — built by text or copied
from the game (e:display_name(), item:tooltip()).
Server-synced state
| Page | Contents |
|---|---|
| Scoreboard | Objectives, scores, teams |
| Server | Connection, tab list, boss bars |
| Packets | Raw packet stream |