Repository navigation
API Block Ticks and Redstone
Lua API / Blocks / Ticks and redstone
On this page
- onTick
- onTick.schedule
- onDisplayTick
- Tick context
- ctx:random()
- ctx:schedule(delay)
- ctx.world:getBlock(x, y, z)
- ctx.world:setBlock(x, y, z, block, damage)
- ctx.world:spawnParticle(name, options)
- ctx.world:playSound(name, options)
- redstone.weakPower
- redstone.strongPower
- redstone.connections
- redstone.onInputChanged
- redstone.onNeighborChanged
Optional block declaration. Required fields: mode and action = function(ctx) ... end. A callback error disables that tick handler.
| mode | Behavior |
|---|---|
default |
Schedules repeated gameplay updates at a one-tick delay while active. |
random |
Uses Minecraft random block ticks. |
scheduled |
Runs explicitly scheduled updates, optionally starting/repeating automatically. |
Only accepted for scheduled block ticks. delay is an optional positive initial delay; if omitted, there is no automatic initial schedule. repeatEvery is an optional positive repeat interval; if omitted, no automatic repeat.
Default ticks and scheduled ticks with both delay and repeatEvery resume automatically when an existing
block's chunk loads, including after rejoining a world. Restarted schedules use the initial delay; their
remaining delay is not saved. Updates wait for Minecraft's surrounding chunks to be available. One-time
and manually started schedules are transient and do not restart automatically after rejoining.
onTick = {
mode = "scheduled",
schedule = { delay = 20, repeatEvery = 20 },
action = function(ctx)
local block = ctx.world:getBlock(ctx.x, ctx.y, ctx.z)
end
}Optional client display callback. Does not change gameplay state.
onDisplayTick = {
chance = 0.25,
action = function(ctx)
ctx.world:spawnParticle("smoke", {
x = ctx.x + 0.5, y = ctx.y + 1, z = ctx.z + 0.5
})
end
}| Field | Type | Default / meaning |
|---|---|---|
action |
function(ctx) | Required. |
chance |
number 0–1 | 1; probability per attempt. |
attempts |
integer 1–64 | 1; attempts per display invocation. |
Display callbacks are driven by client display sampling. Errors disable the display handler.
| Field | Meaning |
|---|---|
x, y, z, position
|
Block coordinates and position snapshot. |
id, damage
|
Block ID and metadata snapshot. |
state |
Scoped state access; writes only in gameplay ticks. |
redstone |
Scoped input/notification access; writes only in gameplay ticks. |
tileEntity |
Scoped tile data access when available. |
world |
Full world action access in gameplay ticks; read/presentation subset in display ticks. |
Returns a number in [0, 1). Valid only while the callback is active.
local chance = ctx:random()Gameplay tick only. Queues an update at this block after a positive integer delay.
ctx:schedule(20)Returns { id, damage } at integer coordinates, or nil when the chunk is unloaded. Available in gameplay and display ticks.
local above = ctx.world:getBlock(ctx.x, ctx.y + 1, ctx.z)Gameplay only. Block is a numeric ID or ID-bearing reference; optional damage chooses metadata explicitly. Returns the engine change boolean and notifies the world. Use registered IDs and valid world coordinates.
ctx.world:setBlock(ctx.x, ctx.y + 1, ctx.z, 0)Spawns a visual particle. The optional table accepts numeric x, y, z, velocityX, velocityY, and velocityZ. Coordinates default to the callback block center and velocities default to 0. Available in both tick kinds.
Accepts custom particle types and keys as well as vanilla names.
Custom sprites additionally accept scale, color, and seed.
ctx.world:spawnParticle("smoke", { x = ctx.x, y = ctx.y + 1, z = ctx.z })Available in both tick kinds. Play a registered burst or emitter effect
at x/y/z, optionally with seed or a loaded attachTo actor and local offset. Returns a handle, or
nil, reason for unavailable presentation or an exhausted handle budget. Handles expose isActive(), stop(),
and unattached setPosition(x,y,z).
Plays a sound. The optional table accepts numeric x, y, z, volume, and pitch. Coordinates default to the callback block center; volume and pitch default to 1. The ordinary (name, volume, pitch) form also works. Available in both tick kinds.
ctx.world:playSound("random.pop", { x = ctx.x, y = ctx.y, z = ctx.z })Gameplay ticks also support every mutable world action, including entity spawning, neighbor notification, and configurable explosions. Display ticks reject gameplay mutations.
Optional digital output: boolean constant, tile-data field-name string, or table specifying exactly one of state / data and optional sides.
redstone = { weakPower = { state = "active", sides = { "south" } } }| Field | Requirement |
|---|---|
state |
Name of a declared boolean metadata field. |
data |
Name of an integer or boolean field on the attached tile entity. |
sides |
Face list; defaults to all six faces. |
A boolean field is active when true; an integer field is active when greater than zero. Output is digital.
Same accepted forms and rules as weakPower, controlling direct/strong output.
redstone = { strongPower = true }Optional list of faces to which wire may visually connect. Defaults to normal provider behavior. Empty list allows no connections. Face names are down/up/north/south/west/east; horizontal facing also enables front/back/left/right. Duplicate names and relative faces without facing are errors.
Optional { action = function(ctx) ... end }. Runs when the observed per-face input changes. Receives a mutable block context.
Additional fields: initial (first observation), neighborId, previous and current (maps of all six physical face names to booleans). First observation uses false previous values. This observation is not saved tile state.
redstone = {
onInputChanged = { action = function(ctx)
if ctx.current.north and not ctx.previous.north then
ctx:schedule(20)
end
end }
}Tile neighbor callback. Requires tileEntity and { action = function(ctx) ... end }; receives a tile context. For ordinary block neighbor notification, use the top-level onNeighborChanged.
Examples: Ticks, redstone switch, pulse timer.
- 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