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: stringWithout 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.