Skip to content

Dismantling ​

Dismantle stations are fully independent from crafting stations: their ids are unrelated, and each loads from its own directory. Dismantling is not a fourth page of a crafting station

text
/emakistation dismantle <station>

You need emakistation.dismantle plus that dismantle station's access permission (if the configuration leaves it empty, it falls back to emakistation.dismantle.access.<id>)

Dismantling has no input slot: opening the window scans your inventory for the first item that matches an available dismantle recipe and selects that recipe. With no matching item the window does not open, and station.dismantle_no_matching_item is returned. Confirming consumes exactly one input item and then rolls rolls times against the pool; confirming again (the button has by then become a claim button) delivers the outputs to the configured routing. The input icon shown in the window is only a read-only preview of that recipe's input -- no item is ever placed into the GUI

Dismantle Station Definition ​

Station files live under plugins/EmakiStation/stations_dismantle/, and the file name matches id

yaml
id: "example_dismantle"
display_name: "<aqua>Example Dismantling Bench</aqua>"

layout: "station_dismantle"

permission: ""

output:
  default: "storage_first"
FieldTypeRequiredDefaultAccepted rangeDescription
idstringYes——Dismantle station id, matching the file name. A missing id refuses the file (station.dismantle_station_missing_id)
display_namestringNothe idMiniMessage textDisplay name used in the window title
layoutstringNo"station_dismantle"a gui/<name>.yml idWindow layout. A missing layout raises missing_layout in the startup precheck
permissionstringNo""a permission nodePermission required to open this dismantle station. When empty, falls back to emakistation.dismantle.access.<id>
output.defaultstringNo"storage_first"storage_first, backpack_first, storage_only, backpack_onlyOutput routing; the values match crafting stations, and an unrecognised value falls back to storage_first
conditionsectionNoemptysee ConditionsCondition gate. It is parsed and stored, but no runtime path evaluates it, so it does not restrict opening

A dismantle station has no queue section, no channels section, no preview_layout / queue_layout, and no output.player_switchable. Dismantling settles immediately and never enters the queue

yaml
# Example: a dismantle station that delivers to the warehouse only
id: "scrap_yard"
display_name: "<gray>Scrap Yard</gray>"
layout: "station_dismantle"
output:
  default: "storage_only"

Current behaviour when output delivery fails

Dismantled outputs are delivered according to output.default; when every configured target is full, the current implementation discards the rolled outputs of that attempt instead of parking them for a claim, and persists nothing. Make sure players have spare inventory or warehouse room before opening this gameplay, or pick a more forgiving output.default

Dismantle Recipe Definition ​

Dismantle recipes live under plugins/EmakiStation/recipes_dismantle/, one recipe per file. The file name does not affect loading; the recipe id comes from the id field inside the file

yaml
id: "example_dismantle"
display_name: "<yellow>Iron Block Dismantling Example</yellow>"

station_id: ""
tags:
  - "blacksmith"

permission: ""

item_sources:
  - "minecraft-iron_block"

rolls:
  min: 2
  max: 3

pool:
  - item_source: "minecraft-iron_ingot"
    amount:
      min: 2
      max: 4
    weight: 6.0

  - item_source: "minecraft-iron_nugget"
    amount: 3
    weight: 3.0
FieldTypeRequiredDefaultAccepted rangeDescription
idstringYes——Recipe id. A missing id refuses the file (station.dismantle_recipe_missing_id)
display_namestringNothe idMiniMessage textDisplay name
station_idstringNo""a single dismantle station idThe bound dismantle station, singular. When empty the recipe is unscoped, so any dismantle station can use it
tagslist<string>No[]stringsThe current implementation only parses and stores this field; nothing reads it, and station binding is decided by station_id alone
item_sourceslist<string>No (at least one of it and input_source)[]item source tokens (hyphen form)Input item source list, the current form. An inventory item must match one of them (and also satisfy matcher, when one is written)
input_sourcestringNo (at least one of it and item_sources)—a single item source tokenLegacy form. It is still read for compatibility, but loading logs a dismantle_recipe_legacy_input_source warning; prefer item_sources. Written together with item_sources it is refused (station.recipe_source_field_conflict)
matchersection/objectNo—general item matcherTop-level matcher selecting the input by component, PDC, or lore. It is ANDed with item_sources. See Item Matcher
rollsinteger | sectionNo1an integer ≥1, or min/max both ≥1How many times each dismantle rolls. Both forms are inclusive
poollistYes—non-empty listOutput probability pool. An empty pool refuses the recipe (station.dismantle_recipe_empty_pool)
permissionstringNo""a permission nodePermission required to use this recipe; empty means unrestricted
conditionsectionNoemptysee ConditionsCondition gate. The dismantling flow does not evaluate it, so an unsatisfied condition does not block dismantling

If neither item_sources nor input_source is present (or both hold only blank values), the recipe is refused with station.dismantle_recipe_no_input

Matching the input with a matcher ​

A top-level matcher lets a dismantle recipe select inputs by item data -- for example, only already-damaged gear:

yaml
id: "damaged_gear_dismantle"
# item_sources is still required and is checked alongside the matcher
item_sources:
  - "minecraft-iron_chestplate"
matcher:
  type: component
  component: damage
  operator: '>'
  value: 0
rolls: 1
pool:
  - item_source: "minecraft-iron_nugget"
    amount: 2
    weight: 1.0

matcher is ANDed with item_sources

item_sources must match and the matcher (when present) must pass, so the example above only accepts an iron chestplate that is also damaged. An input source is always required (item_sources is the current form; the legacy input_source key is still read for compatibility but logs a warning)

To express "a given item and a component condition", put the item source in item_sources and the component condition in matcher

Item source conditions still cannot go inside matcher (type: item_source / item_sources / source / sources are rejected with a warning and the matcher never matches); item sources belong in the top-level item_sources

NOTE

Dismantling has no analogue of the crafting-side "a matcher material never uses the warehouse" rule: it always looks only at the real items in your inventory and never draws from the warehouse

rolls ​

rolls accepts two forms:

yaml
# Fixed count
rolls: 3
yaml
# Range, both ends inclusive
rolls:
  min: 2
  max: 4

The rolls are independent: each one picks an entry from pool by weight. A min below 1 is treated as 1, and a max below min is treated as min

pool — Output Probability Pool ​

FieldTypeRequiredDefaultAccepted rangeDescription
pool[].item_sourcestringYes—a single item source tokenOutput source, singular — one source per entry. A blank value skips the entry; an unparsable token logs station.dismantle_recipe_bad_source and skips the entry
pool[].amountinteger | sectionNo1an integer ≥1, or min/max both ≥1Amount; a fixed value or a min / max range. Out-of-range values are treated as ≥1
pool[].weightdoubleNo1.0>0Relative weight. Invalid values (<= 0 or unparsable) fall back to 1.0

Differences from Crafting Recipes ​

AspectCrafting recipeDismantle recipe
Station bindingstation_ids (plural list)station_id (singular; empty means unscoped)
Inputmaterials (several requirements, each an item_sources set)item_sources (a source list, auto-matched from the inventory, no input slot)
OutputFixed list in result.outputsRandom rolls from pool weighted by weight
Durationduration_seconds, enters the queueNo duration, settles immediately
Currency costcostNone
Condition gatescondition (evaluated at submission) + display_condition (evaluated on catalog repaint)condition only, and not evaluated today
Stage actionsactions.pre / success / failure (not executed today)None