English
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"| Field | Type | Required | Default | Accepted range | Description |
|---|---|---|---|---|---|
id | string | Yes | — | — | Dismantle station id, matching the file name. A missing id refuses the file (station.dismantle_station_missing_id) |
display_name | string | No | the id | MiniMessage text | Display name used in the window title |
layout | string | No | "station_dismantle" | a gui/<name>.yml id | Window layout. A missing layout raises missing_layout in the startup precheck |
permission | string | No | "" | a permission node | Permission required to open this dismantle station. When empty, falls back to emakistation.dismantle.access.<id> |
output.default | string | No | "storage_first" | storage_first, backpack_first, storage_only, backpack_only | Output routing; the values match crafting stations, and an unrecognised value falls back to storage_first |
condition | section | No | empty | see Conditions | Condition 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| Field | Type | Required | Default | Accepted range | Description |
|---|---|---|---|---|---|
id | string | Yes | — | — | Recipe id. A missing id refuses the file (station.dismantle_recipe_missing_id) |
display_name | string | No | the id | MiniMessage text | Display name |
station_id | string | No | "" | a single dismantle station id | The bound dismantle station, singular. When empty the recipe is unscoped, so any dismantle station can use it |
tags | list<string> | No | [] | strings | The current implementation only parses and stores this field; nothing reads it, and station binding is decided by station_id alone |
item_sources | list<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_source | string | No (at least one of it and item_sources) | — | a single item source token | Legacy 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) |
matcher | section/object | No | — | general item matcher | Top-level matcher selecting the input by component, PDC, or lore. It is ANDed with item_sources. See Item Matcher |
rolls | integer | section | No | 1 | an integer ≥1, or min/max both ≥1 | How many times each dismantle rolls. Both forms are inclusive |
pool | list | Yes | — | non-empty list | Output probability pool. An empty pool refuses the recipe (station.dismantle_recipe_empty_pool) |
permission | string | No | "" | a permission node | Permission required to use this recipe; empty means unrestricted |
condition | section | No | empty | see Conditions | Condition 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.0matcher 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: 3yaml
# Range, both ends inclusive
rolls:
min: 2
max: 4The 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
| Field | Type | Required | Default | Accepted range | Description |
|---|---|---|---|---|---|
pool[].item_source | string | Yes | — | a single item source token | Output 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[].amount | integer | section | No | 1 | an integer ≥1, or min/max both ≥1 | Amount; a fixed value or a min / max range. Out-of-range values are treated as ≥1 |
pool[].weight | double | No | 1.0 | >0 | Relative weight. Invalid values (<= 0 or unparsable) fall back to 1.0 |
Differences from Crafting Recipes
| Aspect | Crafting recipe | Dismantle recipe |
|---|---|---|
| Station binding | station_ids (plural list) | station_id (singular; empty means unscoped) |
| Input | materials (several requirements, each an item_sources set) | item_sources (a source list, auto-matched from the inventory, no input slot) |
| Output | Fixed list in result.outputs | Random rolls from pool weighted by weight |
| Duration | duration_seconds, enters the queue | No duration, settles immediately |
| Currency cost | cost | None |
| Condition gates | condition (evaluated at submission) + display_condition (evaluated on catalog repaint) | condition only, and not evaluated today |
| Stage actions | actions.pre / success / failure (not executed today) | None |