Module · Building
building
Blocks, creations and the building editor. Needs the "building" permission; changing things needs more (see each function).
building.addTool(options?: table, onClick: function): BuildTool
Adds a button to the building toolbar. Returns a BuildTool; clicking it calls onClick.
options(optional): { name = string?, tooltip = string? }
local tool = building.addTool({ name = "⚙ Thrusters", tooltip = "Tune engines past their limits" }, function()
toggleWindow()
end)building.block(id: string): Block?
Finds a block by its id, or nil.
building.blockTypes(): any
Every block type there is, as { id, name, category, mod }.
building.blocks(type: string, limit?: integer): Block[]
Every block of a type in the world. Pass "sphere" for your own block, "author.mod:sphere" for another mod's, or a built-in name like "Thruster".
for _, sphere in ipairs(building.blocks("sphere")) do log.info(sphere.position) endbuilding.limit(mechanism: string, setting: string): number?
The raised ceiling for a mechanism's setting, or nil when it has its normal limit.
building.moveInto(player: Player, blocks: Block[], offset: vec3): boolean
Moves blocks by an offset in their creation's own directions, allowing them to overlap other blocks. Server scripts only; the player must own the creation.
net.on("push-in", function(player, data)
local blocks = {}
for _, id in ipairs(data.blocks) do blocks[#blocks + 1] = building.block(id) end
building.moveInto(player, blocks, data.offset)
end)building.onPlaced(type: string, fn: function): Subscription
Calls fn(block) whenever a block of a type appears — placed, loaded, or arriving from the server.
building.onPlaced("sphere", function(block) effects.burst("magic", block.position) end)building.onRemoved(type: string, fn: function): Subscription
Calls fn(block) just before a block of a type is removed.
building.onSelectionChanged(fn: function): Subscription
Calls fn(blocks) every time the building-editor selection changes, with the selected blocks (an empty list when nothing is selected). Replaces polling building.selection() on a timer.
building.onSelectionChanged(function(blocks)
label:setText(#blocks == 0 and "Nothing selected" or (#blocks .. " selected"))
end)building.placement(type: string, fn: function): Subscription
Guides players placing a block type: fn(query) runs every frame of the drag and may return where the block should go and how to show it. query has position, rotation (where the editor would snap), hit { position, normal, block }, ray, scale and — for blocks the game already guides, like gears — suggested. Return { position, rotation, state = "valid" | "neutral" | "invalid", label, settings = { … }, circles, lines, dots }, nil to keep the game's suggestion, or false for none.
building.placement("crank", function(q)
if not q.hit or not q.hit.block then return nil end
return { position = q.position, rotation = q.rotation, state = "valid", label = "On " .. q.hit.block.name }
end)building.raiseLimit(mechanism: string, setting: string, ceiling: number)
Raises the highest value a setting may take for one kind of mechanism, for everyone on this server. Server scripts only.
building.raiseLimit("Thruster", "Force", 5000000)
building.raiseLimit("JetEngine", "Force", 8000000)building.resetLimit(mechanism: string, setting: string)
Puts a limit this mod raised back to normal. Server scripts only.
building.selection(): Block[]
The blocks you have selected in the building editor.
building.tryMoveInto(player: Player, blocks: Block[], offset: vec3): boolean, boolean|string
Like building.moveInto, but a refusal returns false and the reason instead of raising an error. Wrong arguments, side and permission errors still raise.
Returns true and the result on success; false and the reason on a refusal.
net.on("push-in", function(player, data)
local blocks = {}
for _, id in ipairs(data.blocks) do blocks[#blocks + 1] = building.block(id) end
building.moveInto(player, blocks, data.offset)
end)