Rules

Learn how to write Unbreakable rules.

Unbreakables uses Shogi for rule syntax. Rules are configured in config/unbreakables-common.toml:

rules = [
  "is_block('minecraft:spawner') -> refuse('You cannot break this block.')"
]

Rules are applied in order. If a rule refuses or fails, the block cannot be broken. If a rule adds a cost, such as xp or an item, the cost is only consumed when the block break succeeds.

Protecting blocks

To make a block unbreakable, refuse the break when that block is being mined:

rules = [
  "is_block('minecraft:spawner') -> refuse('You cannot break this block.')"
]

Tags can be used instead of single blocks:

rules = [
  "is_block('#minecraft:ores') -> refuse('You cannot break ores.')"
]

Creative players and players with creative-style instant build permissions bypass Unbreakables rules.

Break costs

Rules can require xp or items before a block can be broken:

rules = [
  "is_block('minecraft:spawner') -> xp_level_cost(10)",
  "is_block('minecraft:trial_spawner') -> item_cost('minecraft:nether_star', 1)"
]

Cooldowns can also be used to limit repeated breaks:

rules = [
  "is_block('minecraft:spawner') -> cooldown_cost('spawner_break', '1h')"
]

When a rule blocks the break or requires something from the player, Unbreakables can show in-game feedback such as a message, remaining cooldown time, xp cost, item cost, or a combination of those.

Packaged rules

Mods and datapacks can provide named rules. Enable those rules with use('namespace:path').

For example, Waystones provides a rule for generated waystones:

rules = [
  "use('waystones:generated_waystones')"
]

Player-placed blocks

Unbreakables adds an is_placed condition for rules that need to tell player-placed blocks apart from generated blocks. This is mainly useful for generated structure protection, where player-placed replacement blocks should stay breakable.

By default, placedBlockTracking is set to in_structure. In this mode, Unbreakables tracks eligible block placements inside generated structure pieces.

Blocks tagged as unbreakables:do_not_track and fluid states are not tracked. Changing this setting only affects placements observed after the setting is active; it does not retroactively classify blocks that already exist.

For the full list of generic Shogi conditions and effects, see the Shogi documentation.