Guide 1 Docs 2 Reference 3
27

BlockSpec type

What a definition says a block *is*. Every hook takes base as its **last** argument: call it and you extended what is under you, leave it out and you replaced it. base is a decision rather than a reentrant call — its effects land when your hook returns, and calling it twice happens once.

Functions 11

blockSpec.on_use((block: BlockAt, player: Player?, held: string?, base: (...any) -> any) -> Used?) → ?

The hooks. Writing one is what asks for it — there is no flag beside on_random_tick saying the random pass may land here.

blockSpec.on_break((block: BlockAt, player: Player?, by: Breaker, base: (...any) -> any) -> Drops?) → ?

Something broke it. Answers "none", "table" or a drops list; fails closed to the definition's drops.

blockSpec.on_step((block: BlockAt, body: Body, base: (...any) -> any) -> ()) → ?

A body is standing on it; body is { id, kind }.

blockSpec.on_tick((block: BlockAt, base: (...any) -> any) -> ()) → ?

A scheduled tick this block asked for came due.

blockSpec.on_random_tick((block: BlockAt, base: (...any) -> any) -> ()) → ?

The random pass landed on it. Not the same thing as on_tick, which is why it has the longer name.

blockSpec.on_place((block: BlockAt, player: Player?, base: (...any) -> any) -> ()) → ?

A player put it down; block.data is empty then, ready to be filled.

blockSpec.on_neighbour((block: BlockAt, from: Vec3, announced: string, base: (...any) -> any) -> ()) → ?

A neighbour changed; from is its position and announced the block name the notifier announced itself as.

blockSpec.on_trigger((block: BlockAt, cause: Trigger, base: (...any) -> any) -> ()) → ?

It was lit, blasted or burnt; cause is "ignite", "explosion" or "fire".

blockSpec.on_power((block: BlockAt, powered: boolean, base: (...any) -> any) -> ()) → ?

A redstone signal started (powered is true) or stopped reaching it. Called once for each, not for every change beside it.

blockSpec.on_added((block: BlockAt, base: (...any) -> any) -> ()) → ?

It has just been stored, whatever stored it.

blockSpec.on_removed((block: BlockAt, base: (...any) -> any) -> ()) → ?

It has just gone from the world.

Fields 16

blockSpec.name: string

Without a namespace. The pack's own is put in front of it, and a colon here is refused: a pack cannot write another pack's name.

blockSpec.looks: (string | { string })?

A block state the client already draws, because a client has never heard of this pack. One name, or one per state in state order. | takes the first this version has: "crimson_planks|nether_brick".

blockSpec.hardness: number?

Seconds-scale, as vanilla's hardness is; below zero is unbreakable.

blockSpec.resistance: number?

What an explosion has to chew through.

blockSpec.material: { solid: boolean?, covers: boolean?, firm: boolean?, liquid: boolean?, burns: boolean?, }?

The jar's Material as five questions: solid, covers (grass under it dies), firm (snow and ice need it), liquid, burns.

blockSpec.opacity: number?

What a step through it takes off the light; 15 is an opaque cube.

blockSpec.light: number?

What it gives off, 0 to 15.

blockSpec.tick_every: number?

Seconds between block:schedule() and on_tick; 0.5 unless you say.

blockSpec.drops: (Drops | false)?

What a break leaves — and, because on_break fails closed, what it leaves when this pack is too slow to answer. Never the looks block's. false is nothing, as "none" is.

blockSpec.item: (ItemTable | false)?

The block in a hand. Its id is set to the block's name, so placing it puts this block down, and a break leaves it unless drops says. false is no item, also for a block with a texture.

blockSpec.texture: (Faces | { Faces })?

Its own picture on 1.21.4+: one for every state, or one per state.

blockSpec.model: (Model | { Model })?

Its own shape on 1.21.4+, in place of texture: a model that stays inside the block, one for every state or one per state. The block collides as its looks block does: "rail" is walked through.

blockSpec.facing: boolean?

Turns its front to whoever places it; block.facing reads and turns it.

blockSpec.power: (number | { [string]: number } | { number | { [string]: number } })?

What it gives a redstone circuit, 0 or 15: one number for every face, a table keyed by face (the names texture takes), or a list of either with one entry per state. It is the power a block of redstone gives.

blockSpec.label: Text?

The name of the item a textured block comes with.

blockSpec.extends: (BlockRef | { [string]: any } | { any })?

A handle, a game block's name, a plain table of fields and hooks, or a list of those **innermost first**. There is no class and no metatable: fields merge and hooks wrap.