Coming soon toSteam
Modding docsAPI 1

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

client onlyneeds building

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) end

building.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

client onlyneeds building

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

client onlyneeds building

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[]

client onlyneeds building

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)