Skip to content

API Action Contexts

Piggo41 edited this page Oct 16, 2026 · 14 revisions

Action contexts

Lua API / Action contexts

Live helpers below are valid only during their callback. Queries cannot mutate gameplay. Methods marked mutable raise an error in a read-only context or after expiration. Gameplay tick and tile callbacks share the world actions below while retaining their own context fields: ticks, events, tiles.

On this page

Block context

Field Meaning
x, y, z Integer block coordinates.
position Coordinate snapshot with x/y/z.
id, damage Block ID and initial metadata snapshot.
face Physical face string when the operation supplies one; otherwise nil.
target { kind = "block", block = blockAccess }.
state State access for this block.
redstone Input inspection and neighbor notification.
world World action access.
player Entity access when a player is supplied; otherwise nil.
stack Held stack access when supplied; otherwise nil.
tileEntity.data Scoped tile data access when the block has a Lua tile.

Callback-specific fields are documented with each callback.

Item context

Field Meaning
world World action access, with effect origin at the supplied interaction position.
stack Live item stack access.
player Entity access when a player exists.
target.kind block, entity, or miss.
target.block Block access for a block target.
target.entity Entity access for an entity target.
position, face Present for a direct block target.

Query-only tool callbacks use their smaller query context.

ctx:rayTrace(options)

Item-context method. Required options table accepts distance (number greater than 0 and at most 64; default 5) and liquids (boolean, default false).

Returns { kind = "miss" } or { kind = "block", block, position, face }. Traces blocks from the player's view; requires a player. Returned live block methods share the callback lifetime.

local hit = ctx:rayTrace { distance = 6, liquids = false }

ctx:schedule(delay)

Block-context method. Schedules a block gameplay tick after a positive delay (1–1000000). Requires mutable context and an appropriate registered block tick handler.

ctx:schedule(20)

ctx:random()

Block-context method. Returns a random number in [0, 1). Requires an active context.

local roll = ctx:random()

State access

ctx.state:get(name)

Returns the declared boolean/enum value. Unknown fields or missing schemas raise an error. Reads current metadata when the same block remains, otherwise uses captured metadata.

local active = ctx.state:get("active")

ctx.state:set(name, value)

Mutable. Writes a declared value to metadata and notifies the world when changed. Requires the original block to remain at the position. Invalid values/fields raise an error.

ctx.state:set("active", true)

Block target access

ctx.target.block.id is the block ID; ctx.target.block.state exposes the state methods above.

ctx.target.block:rotate(direction)

Mutable. Direction is clockwise or counterclockwise. Rotates a compatible facing state through north/east/south/west. Returns true on rotation, false if no supported facing state; invalid direction raises an error when facing exists.

local rotated = ctx.target.block:rotate("clockwise")

Redstone access

ctx.redstone:isPowered(side)

Returns whether input power is present. Optional face string restricts inspection to one neighbor; omitted checks aggregate indirect power. Relative faces require horizontal orientation.

local powered = ctx.redstone:isPowered("north")

ctx.redstone:notifyNeighbors()

Mutable. Notifies adjacent blocks of a change at this block. Requires the original block at the position.

ctx.redstone:notifyNeighbors()

World action access

The world handle is scoped to the current callback's world. These read methods are available in entity AI and other action callbacks:

Method Result
getTime() Total world ticks.
getDayTime() Time of day, 0–23999.
isDaytime() Current sky daylight state.
getDifficulty() Native difficulty setting, 0–3.
getSpawnPoint() Detached { x, y, z } world spawn coordinates.
getDimension() Native dimension ID.
getWeather() { raining, thundering, rainStrength, thunderStrength }.
isLoaded(x, z) Whether the chunk containing the integer coordinates is loaded; does not load it.
getBiome(x, z) Biome display name at integer coordinates.
getHeight(x, z) Terrain height, or nil if the chunk is unloaded.
getLight(x, y, z) { combined, sky, block, brightness }, or nil if unloaded; Y 0–127.
isSolid(x, y, z) Whether the loaded block is a normal solid cube; false if unloaded.
canSeeSky(x, y, z) Whether the loaded block position sees the sky; false if unloaded.
isRainingAt(x, y, z) Whether rain reaches this position in its biome; false if unloaded.
isLiquid(x, y, z) Whether the block material is liquid; false if unloaded.
isPowered(x, y, z) Whether the position receives indirect redstone power; coordinates default to the callback origin. Explicit unloaded coordinates return false.
getClosestPlayer(radius) Closest player within 64 blocks of the callback origin, or nil.
getNearbyEntities(radius) Up to 256 live entity handles within a true radius of at most 32 around the callback block center.
getInfo() Detached current world information.
getBlockView(...), getTile(...), getBiomeData(...), getChunk(...) Rich detached world data views.
getPlayers(options) Bounded nearest-first loaded players.
getSystemData(system) Detached world-service data.
getCapability(...) Operation-only external capability proxy.

X/Z coordinates are integers in -30000000–30000000. getHeight, getLight, and getBlock return nil for unloaded chunks so AI can check availability without loading terrain. Both nearby queries use spherical distance. The world form measures from the callback block center; an entity handle measures from its exact position and excludes itself.

Gameplay block ticks and tile callbacks expose this same world action interface. Client display ticks expose only safe block reads, particles, and sounds.

ctx.world:getBlock(x, y, z)

Returns a detached { id, damage } snapshot, or nil when the chunk is unloaded. X/Z coordinates are integers in -30000000–30000000 and Y must be 0–127. The lookup does not load terrain.

local above = ctx.world:getBlock(ctx.x, ctx.y + 1, ctx.z)
if above then
    print("Block ID above this entity: " .. above.id)
end

ctx.world:setBlock(x, y, z, block, damage)

Mutable. Replaces a block and notifies the world. X/Z range -30000000–30000000; Y 0–127. Block is a registered ID or ID-bearing reference, or zero for air. Damage defaults to zero, range 0–15. Returns the engine change boolean.

local changed = ctx.world:setBlock(ctx.x, ctx.y + 1, ctx.z, 0)

ctx.world:notifyNeighbors(x, y, z)

Mutable. Notifies adjacent blocks about the block at the supplied integer coordinates. Omit all three coordinates to use the callback origin. Explicit unloaded coordinates return false; a performed notification returns true.

ctx.world:notifyNeighbors()
ctx.world:notifyNeighbors(12, 64, -4)

ctx.world:playSound(name, volume, pitch)

Mutable. Plays a sound at the context origin's block center. Name is required; volume/pitch default to 1. The second argument may instead be { x, y, z, volume, pitch }; every field is optional and omitted coordinates use the origin.

ctx.world:playSound(betamoon.mc.sounds.random.pop, 0.6, 1.2)
ctx.world:playSound("random.pop", { x = 12.5, y = 65, z = -3.5 })

ctx.world:spawnParticle(name)

Mutable. Spawns a particle at the context origin's block center with zero velocity. An optional table accepts x, y, z, velocityX, velocityY, and velocityZ; every field has the origin/zero default.

name also accepts a custom particle type reference or key, with custom-only scale, color, and seed options. Bare vanilla names retain their native behavior.

ctx.world:spawnParticle(betamoon.mc.particles.smoke)
ctx.world:spawnParticle("smoke", { y = ctx.y + 1, velocityY = 0.02 })

ctx.world:playParticleEffect(effect, options)

Mutable. Play a registered particle effect. Options accept x/y/z, seed, a loaded attachTo actor handle, and attachment offset. Returns a handle, or nil, reason when the local client/world/attachment is unavailable or the handle budget is exhausted. Unknown effects and invalid options raise errors. The handle exposes isActive(), stop(), and unattached setPosition(x,y,z).

ctx.world:spawnEntity(type, options)

Mutable. Spawns a registered entity type in a loaded chunk. type is a type reference or namespaced key. options.position requires numeric x, y, z; options.rotation may provide numeric yaw and pitch. Projectile types also accept a live same-world entity handle as options.owner. Supplying owner for another kind raises an error. Returns live entity access on success, or nil, reason when placement fails or onSpawn removes the entity. Unknown types and invalid arguments raise errors.

local entity, reason = ctx.world:spawnEntity("mymod:entity/lantern", {
    position = { x = 10.5, y = 65, z = 20.5 }
})

An AI or entity callback can attribute a projectile to its entity:

local projectile, reason = ctx.world:spawnEntity("mymod:entity/bolt", {
    position = ctx.entity:getPosition(),
    rotation = ctx.entity:getRotation(),
    owner = ctx.entity
})

The owner is used for impact attribution and ownerGraceTicks. Player and BetaMoon-entity owners retain stable identity through save/load. Other native or modded entities work as owners while the original object remains loaded, but currently have no stable identity to restore after reload.

ctx.world:createExplosion(options)

Mutable. Creates a configurable explosion and returns a detached result snapshot. strength is required. Block destruction, entity damage, knockback, drops, fire, sound, particles, source attribution, and affected-position output can be selected independently.

local result = ctx.world:createExplosion {
    position = ctx.entity:getPosition(),
    strength = 2.5,
    source = ctx.entity,
    blocks = "none"
}

See Explosions for all options, defaults, results, callback fields, and limits.

Entity access

Entity handles are documented in Entity access and movement. They remain live only for the current callback and expose methods according to the target's supported capabilities.

Stack access

stack.id identifies the item. These methods operate on the live stack.

stack:getCount()

Returns current integer stack size.

local count = ctx.stack:getCount()

stack:getDamage()

Returns current integer damage/metadata.

local damage = ctx.stack:getDamage()

stack:consume(count)

Mutable. Count is integer 1–32767. Returns false without change if insufficient; otherwise subtracts count and returns true.

local consumed = ctx.stack:consume(1)

stack:damage(amount)

Mutable; requires a player. Amount is integer 0–32767. Applies normal durability damage, including break behavior.

ctx.stack:damage(1)

Multiblock controllers

Block contexts expose ctx.multiblock when the current block is a registered automatic controller. Use ctx.multiblock:isFormed() as a cached processing gate; it becomes false as soon as relevant geometry changes and while verification is pending. It is absent for other blocks. Removed-block callbacks do not receive a replacement controller as the old one. See multiblock access and lifecycle.

Scoped world access also provides checkMultiblock(definition, x, y, z, options?) for pure detached reports and getMultiblock(x, y, z) for a controller instance, or nil. See world checks.

Controllerless multiblock actions

Scoped world access supports findMultiblocks(definition, options) for bounded pure discovery and getMultiblocksAt(x, y, z, options?) for known memberships. Item callbacks additionally expose ctx:activateMultiblock(definition, x, y, z, options?) to activate a chosen placement using the current player and held item. For ray-traced onUse, supply options.clicked and options.face from the hit. See manual discovery and activation for options, partial results, validation, and interaction handling. Instance handles provide isActive(), activate() and deactivate(); see manual activation and deactivation.

Clone this wiki locally