Interactable Configuration

Register placeable static objects with an inventory and Lua behavior, such as chests, furnaces, and crafting benches.

Interactables are placeable static objects with an inventory and Lua behavior — chests, furnaces, crafting benches, doors, and similar. This is the catalog file that registers them.


File Location

Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):

interactable-config: interactable-config.yaml

Then create the file it points to, relative to your mod’s folder:

mods/<YourMod>/interactable-config.yaml

The file is a single list of interactable entries:

interactables:
  - name: my_chest
    hitbox:
      width: 2.0
      height: 1.5
    requires-supporting-blocks: true
    time-to-break-ms: 1000
    power-required: 1
    tool-break-types: axe

Names are automatically prefixed with your mod name unless you write one already containing a colon.


Minimal Example

interactables:
  - name: my_sign
    hitbox:
      width: 1.0
      height: 1.0

Fields

FieldDefaultDescription
name(required)The interactable’s identifier.
hitbox(required){ width, height } in blocks.
requires-supporting-blocksfalseWhether this object needs solid ground beneath it to be placed.
time-to-break-ms1000How long it takes to break with a valid tool.
power-required1Minimum tool power level needed to break it.
tool-break-types(none)Which tool categories can break it — a single string or a list. Leaving this unset means any tool or a bare hand can break it (see Breaking below).
breakabletrueWhether it can be broken at all. false makes it permanently unbreakable — immune both to being mined directly and to having the block beneath it broken — regardless of tool-break-types. Use it for signs, monuments, or permanent structure pieces.
collidabletrueWhether entities/players collide with it physically.
interact-cooldown-ms0Minimum time between interactions (cooldown).
default-state"default"Initial state name. Must match a states: entry in this object’s texture config, or the object resolves no state — see State names are matched exactly.
interact-range10.0How many blocks away this object can be interacted with from.
crafting-station(none)Marks this interactable as a crafting station — { power, type }. See Crafting Stations.
light(none)Makes the object emit light — same shape as Shared Blocks → light.
drop-table(none)Items dropped when broken — see Drop Table.
drops-selffalseShorthand for “drops exactly one of itself” — see Drops Self.
draw-priority0Client-only. Draw order for this placed object.
shader(none)Client-only. Overrides the render shader for this object.
itemtrueWhether registering this interactable also registers its type: interactable item, making it obtainable and placeable. Set false for one that must never exist in an inventory — same rule as a block’s item.
particles(none)Client-only. Ambient particle emission — a list of emitter groups, each with its own emit-random. See the particles: block.

Unknown keys at the top level of an entry are rejected: a misspelled field is a load-time error naming the bad key, not a silently-ignored one. Its nested blocks are validated the same way — an unrecognized key inside the light block, the scripts block, or a drop-table entry is also a load-time error naming the bad key. See Unknown Fields.


Breaking

tool-break-types and power-required gate which tools can break an interactable:

  • If tool-break-types is set, the tool must have at least one matching entry (via the tool’s own tool-types); if it’s left empty, any tool — or a bare hand — qualifies, and
  • The tool’s power-level must be >= power-required.

Leaving tool-break-types empty means “no tool requirement” — any tool or a bare hand can break it (subject to power-required). Set one or more categories to restrict which tools work.

To make an interactable permanent, set breakable: false. This overrides everything above: it can’t be mined directly, and breaking the block beneath it won’t destroy it either (it survives losing its support). Use it for signs, monuments, or fixed structure pieces.

tool-break-types: axe          # single tool category
tool-break-types: [axe, pickaxe]  # multiple categories, any one qualifies

Crafting Stations

Add a crafting-station block to turn an interactable into a crafting station. While a player stands within the station’s interact-range, the server lets them craft recipes of that type whose own crafting-station.power (see crafting-config.md) is at most this station’s power.

crafting-station:
  power: 2
  type: crafting   # Crafting, Smelting, or any custom tag your recipes use

Notes:

  • Both power and type are required whenever the block is present — a half-configured station is a load-time error rather than a silently non-functional station.
  • type is an open, case-insensitive tag matched against a recipe’s crafting-station.type. A recipe declares the station it requires with the same block name and keys an interactable uses to declare the station it provides, so the two sides read identically. Beyond the base game’s Crafting/Smelting you can invent your own categories (Anvil, Loom, …) — the station and its recipes just have to use the same tag. See crafting-config.md.
  • Your station’s client-on-interact hook still has to open the crafting menu client-side (via display_crafting_menu(power, type)) — that’s what the player sees. The crafting-station config is the server’s independent authority: crafting is validated server-side against nearby stations, so a modified client can’t craft station-gated recipes out of range.
  • Hand-crafting baseline: every player can always craft Crafting recipes of power 1 with no station nearby (this matches the crafting menu the inventory opens by default). Anything above power 1, or any recipe of another type (including Smelting), requires a station in range.

Drops Self

Most interactables just drop one copy of themselves when broken. That’s what drops-self is for:

drops-self: true

It’s exactly equivalent to a drop-table with a single group holding this interactable’s own item at chance: 1.0 and min/max of 1, and requires an item registered under the interactable’s own name. If both drops-self and drop-table are given, drop-table wins and a warning is logged.

This shorthand exists for interactables and blocks only — mobs, trees, and mounts share the drop-table block below but have no drops-self field. For anything more involved than one guaranteed self-drop, use a drop-table.


Drop Table

What the interactable leaves behind when it’s broken — independent drops: rolls, weighted pick-one groups:, or a named loot-table: to defer to:

drop-table:
  drops:
    - item: MyMod:my_item
      chance: 1.0
  groups:
    - entries:
        - item: MyMod:common_drop
          weight: 0.9
        - item: MyMod:rare_drop
          weight: 0.1

This is the shared drop-table block, identical here to the one on blocks, mobs, mounts and trees — see Shared Blocks → drop-table for every field, the chance-vs-weight distinction, the amount shorthand, and deferring to a named loot table.

For how this differs from a standalone loot table, see Drop Table vs Loot Table.


Lua Hooks

Interactables support several Lua callback hooks, declared under a single scripts: map keyed by event name, each value the bare path to a .lua file that returns its handler function (the same shape as items’ server-on-primary-use):

scripts: keySideCalled
server-on-createServerWhen placed
server-on-interactServerWhen a player interacts with it
server-on-inventory-closeServerWhen a player closes its inventory UI
server-updateServerEvery tick
client-on-createClientWhen received/loaded
client-on-interactClientWhen a player interacts with it
client-updateClientEvery frame

The server-on-interact handler receives (interactable, player_entity_id, player), where player is the interacting player’s entity wrapper — it can reply privately with player:send_message(text) or set the player’s respawn point with player:set_custom_spawn(x, y) / player:clear_custom_spawn().


Complete Example

interactables:
  - name: crafting_bench
    hitbox:
      width: 3.0
      height: 1.5
    requires-supporting-blocks: true
    time-to-break-ms: 500
    power-required: 1
    tool-break-types: axe
    crafting-station:
      power: 2
      type: crafting
    scripts:
      client-on-interact: /interactables/crafting-bench/scripts/client_interact.lua
    drops-self: true

  - name: door
    hitbox:
      width: 1.0
      height: 3.0
    requires-supporting-blocks: true
    time-to-break-ms: 1000
    power-required: 1
    tool-break-types: axe
    scripts:
      server-on-interact: /interactables/door/scripts/server_interact.lua
    interact-cooldown-ms: 400
    default-state: door_closed
    drops-self: true