English
GUI Template
The window template plugins/EmakiAccessory/gui/accessory_gui.yml covers what each cell type does, what happens when you click it, and which checks run when the window closes. The accessory panel is described by that file
Slots Must Declare type Explicitly
Accessory cells must declare type: "accessory_slot" explicitly; a cell without type is nothing but decoration
Available Types
type | Purpose |
|---|---|
accessory_slot | An accessory cell. The key name must equal a slot instance id |
orphan_slot | An orphan cell showing accessories from slots the page no longer declares, for retrieval |
page_enable | An enable cell. Clicking makes the current page the active one; only the active page's accessories take effect |
page_switch | A switch cell. The key name must equal the target page's page_id; clicking opens that page |
One layout can be shared by several pages: gui_template in pages/*.yml points at a layout id. When sharing, note that a placed slot instance must be declared in that page's parts, otherwise the cell is unusable for the page
accessory_slot
The key name must equal a slot instance id in the form <partId>_<index>, with the index starting at 1 and matching that part's count in parts.yml
For example, a ring part configured with count: 2 needs both ring_1 and ring_2 cells:
yaml
slots:
ring_1:
slots: [12]
type: "accessory_slot"
item:
source: "LIGHT_GRAY_STAINED_GLASS_PANE"
components:
custom_name: "<gray>Ring</gray>"
lore:
- "<dark_gray>Insert an accessory to activate</dark_gray>"
ring_2:
slots: [13]
type: "accessory_slot"Each accessory_slot may occupy only one cell. If you write several, only the first takes effect and the rest are logged as warnings
Slots declared in parts.yml but not placed here are likewise logged as warnings, and the player cannot use them
A slot's item section defines the placeholder shown while the slot is empty; it is replaced by the real item once an accessory is inserted
orphan_slot
Accessories in slots the page no longer declares appear here for the player to retrieve, and cannot be put back once retrieved. If you shrink count in parts.yml, delete a part, or remove a part from a page's parts, you create orphans
yaml
slots:
orphan:
slots: "37-43"
type: "orphan_slot"
item:
source: "GRAY_STAINED_GLASS_PANE"
components:
custom_name: "<gray>"
tooltip_display:
hide_tooltip: trueAn orphan area may occupy several cells. The check is based on whether the owning page declares the slot, so accessories on other pages are never treated as orphans
You can skip the orphan area and lose nothing: the data stays in the file, but players then have no in-GUI retrieval entry point and depend on /eacc retrieve <page> or on the configuration being restored
page_enable
Clicking it makes the currently open page the active one. Only the active page's accessories provide attributes, skills, and set piece counts; other pages keep their data without contributing
yaml
slots:
page_enable:
slots: [8]
type: "page_enable"
item:
source: "lime_dye"page_switch
The key name must equal the target page's page_id; clicking switches to that page. Switching only changes the view, not the active page — to activate the new page you still click page_enable
yaml
slots:
main:
slots: [0]
type: "page_switch"
item:
source: "gold_ingot"
secondary:
slots: [1]
type: "page_switch"
item:
source: "iron_ingot"When the target page declares a permission the player lacks, the switch is refused
Decorative Cells
Cells without type are pure decoration, such as a frame:
yaml
slots:
frame:
slots: "0-8,45-53"
item:
source: "BLACK_STAINED_GLASS_PANE"
components:
custom_name: "<gray>"
tooltip_display:
hide_tooltip: trueClick Behaviour
A click on any cell is always cancelled (never handed to vanilla) and then dispatched by type:
| Action | Result |
|---|---|
| Inserting an accessory | The accessory slot declaration is checked first: without an accessory_slots declaration (and with no optional source matching) it reports gui.not_declared; a declared but non-matching cell reports gui.slot_mismatch. Then unique is checked against the same page and a duplicate reports gui.unique_conflict. On rejection the stack stays on the cursor and never enters the cell |
| Taking an accessory out | A left click with an empty cursor takes the stored accessory |
| Double click, number key, off-hand swap, drop, control-drop | Unsupported, reporting gui.click_unsupported |
| Quick transfers from the player inventory | Unsupported, reporting gui.transfer_unsupported; move items one cell at a time |
| Any mutation inside a read-only window | Refused with gui.read_only |
| Inserting into an orphan cell | Refused with gui.orphan_read_only |
Clicking page_enable on the already-enabled page | Reports gui.page_already_enabled and changes nothing |
Clicking the page_switch cell of the current page | Does nothing; an unknown target reports gui.page_unknown and a missing permission reports gui.page_no_permission |
| Session data reloaded meanwhile | The edit is refused with gui.session_stale; close and reopen the accessory window |
Switching a page closes the current window and opens the target on the next tick; the close path is suppressed during a switch, so the data session stays continuous (no flush and no lease release in between)
Orphan cells fill slot by slot in ascending slot id order; when there are more orphans than cells, the surplus can only be recovered with /eacc retrieve <page>
Validation on Close and Status Markers
Closing the window (any close path other than a page switch) runs a declaration check over every page of that player: an item sitting in a slot the page still declares, but no longer inside that slot's declaration, is taken out and returned to the player's inventory (dropped at their feet when the inventory is full) with one gui.invalid_returned message per item. Items in orphan cells are not part of this pass and keep their own take-out-only flow
An item that sits in the right cell but has its effects gated gets one extra status line in the window (rendering only, never written back to the item):
| State | Line | Cause |
|---|---|---|
| Conditions unmet | gui.condition_unmet | The EmakiItem definition's condition failed, so attributes, skills and set piece count stop applying |
| Durability exhausted | gui.durability_broken | Durability is used up, so attributes, skills and set piece count stop applying; the item stays in its cell and can be taken out for repair |
When these two lines are evaluated is described in integration
Top-Level Keys
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
id | string | Yes | — | — | Template id, referenced by gui_template in pages/*.yml; when blank the template is not loaded and a page referencing it cannot open (accessory.gui_template_missing) |
gui_type | string | No | CHEST | a Bukkit InventoryType name (case-insensitive); an invalid value falls back to CHEST | Window type |
title | string | No | "GUI" | — | Window title; MiniMessage is supported, and a text-config section (CoreLib text format) is accepted too |
rows | integer | No | 3 | 1–6, values outside the range are clamped | Row count; only applies to types that support custom row counts (such as CHEST) |
slots | map<string, object> | No | {} | — | Slot definitions, keyed by cell identifier |
Slot Keys
What slots.<key>'s key name means depends on the type (see "Available Types" above). Nested fields:
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
slots.<key>.slots | integer / list / string | Yes | — | a single cell number, a list of numbers, or a range string such as "1-3,5"; an entry that parses to nothing is ignored | Container cells this entry occupies, numbered from 0 |
slots.<key>.type | string | No | empty | accessory_slot / orphan_slot / page_enable / page_switch | Cell behaviour; empty means pure decoration. accessory_slot and page_switch also depend on the key name, as described above |
slots.<key>.item | object / string | No | empty | — | Item definition rendered in this cell; a plain item-source string is accepted as shorthand |
slots.<key>.item.source | string | No | empty | — | Item source (a vanilla material name, an EmakiItem definition, or another CoreLib item-source form); when blank it falls back to the part's icon, and when both are blank a barrier item is shown |
slots.<key>.item.amount | integer | No | 1 | ≥ 1, values below 1 are treated as 1 | Item amount |
slots.<key>.item.components | map | No | {} | — | Item component patches keyed by component id; the value is passed through to that component |
slots.<key>.item.components.custom_name | string | No | — | — | Item name with MiniMessage support (component custom_name) |
slots.<key>.item.components.lore | list<string> | No | — | — | Item lore lines with MiniMessage support (component lore) |
slots.<key>.item.components.tooltip_display.hide_tooltip | boolean | No | — | true / false | Hides the item tooltip (a nested field of component tooltip_display) |
slots.<key>.sounds | map<string, object> | No | {} | keys are click, left_click, right_click, shift_left_click, shift_right_click, middle_click, double_click, number_key, swap_offhand, drop, control_drop | Click sounds; an unrecognised key is reported as an issue and ignored |
item.components is CoreLib's generic item-component patch, so it accepts any Minecraft component id in addition to the three listed above. Actual accessory interactions are decided by type; sounds and custom components only affect appearance. See plugins/EmakiAccessory/gui/accessory_gui.yml for the complete shipped sample
Example: one accessory cell on a page, plus an enable cell and a switch cell
yaml
id: "compact_gui"
gui_type: CHEST
title: "<dark_gray>Accessories</dark_gray>"
rows: 3
slots:
ring_1:
slots: [11]
type: "accessory_slot"
item:
source: "LIGHT_GRAY_STAINED_GLASS_PANE"
page_enable:
slots: [15]
type: "page_enable"
item:
source: "lime_dye"
main:
slots: [16]
type: "page_switch"
item:
source: "gold_ingot"