English
Socket Item Definitions and GUI Templates
Socket item definition files are stored in items/*.yml. They define which equipment can have gem sockets, what socket types are available, which sockets are initially open, and which GUI templates should be used
Socket item fields
Shipped default file: items/example_socket_item.yml
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
id | string | Yes | — | — | Unique socket item definition id. The file is skipped when it is blank |
item_sources | list | No | empty (unrestricted) | item source shorthand such as minecraft-diamond_sword | Allowed item sources for the equipment. Combined with slot_groups and matcher using AND |
matcher | object | No | empty | see Item Matcher | Non-item-source conditions only (component, PDC, lore); item source conditions are rejected here |
slot_groups | list | No | empty (unrestricted) | weapon/sword/armor/helmet/chestplate/leggings/boots/offhand/shield/tool, or any substring | Group list matched against the item material name; values are lowercased on load and blank entries dropped. See Group names |
match | object | — | — | — | Deprecated and no longer read. See Migrating from match |
slots | list | No | empty list | each entry has index / type / display_name | Socket slot list; when empty the equipment has no usable sockets |
default_open_slots | list<integer> | No | empty | must exist in slots | Slot indexes that are open by default; indexes not present in slots are ignored |
allowed_gem_types | list | No | empty (unrestricted) | gem types; containing any also means unrestricted | Gem type whitelist for this equipment |
max_same_type | integer | No | unset = unlimited | 0 or unset = unlimited; a positive value = limit | Maximum gems of the same type |
max_same_id | integer | No | 1 | ≥ 1 | Maximum gems with the same gem id |
gui.gem_template | string | No | "" | GUI template id such as gem/default | Inlay / view / upgrade / reroll GUI template |
gui.open_template | string | No | "" | GUI template id such as open/default | Socket opening GUI template |
obtain.name_actions | list | No | empty | CoreLib name operations | Name operations applied when the gem layer is first written |
obtain.lore_actions | list | No | empty | CoreLib lore operations | Lore operations applied when the gem layer is first written |
obtain.actions | list<string> | No | empty | CoreLib action lines | Action lines run when the gem layer is first written |
Matching rules
Equipment matching is decided by three top-level fields, combined with AND (all must hold). Their types, defaults, and ranges are in the Socket item fields table above:
slot_groups: matched against the item material name; matching any one group passes, and an empty list means unrestricteditem_sources: allowed item sources; matching any one entry passes, and an empty list means unrestrictedmatcher: non-item-source conditions only (component, PDC, lore, variable); syntax is in Item Matcher
Recognition can only succeed when at least one of item_sources and matcher is declared
Group names
slot_groups tests the item's material name (such as diamond_sword), not the equipment slot the player wears it in. The available group names are:
| Group name | Matches when |
|---|---|
weapon, sword | Material name ends with _sword or _axe |
armor, helmet, chestplate, leggings, boots | Material name ends with one of _helmet, _chestplate, _leggings, _boots |
offhand, shield | Material name ends with shield, or contains totem |
tool | Material name ends with one of _pickaxe, _axe, _shovel, _hoe |
| Any other value | Falls back to a substring test: matches when the material name contains the value |
WARNING
helmet, chestplate, leggings, and boots are exactly equivalent to armor: each matches all four armour pieces and does not narrow the match to that one piece. To restrict to a specific piece, list it in the top-level item_sources, or rely on the substring fallback (for example write just _helmet)
Likewise _axe belongs to both weapon and tool, so axes match either group
DANGER
Recognition assumes at least one of item_sources and matcher is declared: when the file has neither, this socket definition never matches any item (declaring only slot_groups is not enough). If a match migration drops those conditions, the equipment shows up as "does not support gems"
Migrating from match
The old match block (with item_sources, slot_groups, and lore_contains) is no longer read. Where each field goes:
| Old field | Current form |
|---|---|
match.item_sources | Promoted to a top-level item_sources |
match.slot_groups | Promoted to a top-level slot_groups |
match.lore_contains | A type: component child inside matcher with component: lore and operator: contains, one per text fragment |
/emakigem convert-legacy can do the conversion for you:
| Command | Behaviour |
|---|---|
/emakigem convert-legacy | Dry run; prints the diff it would produce without touching files |
/emakigem convert-legacy confirm | Rewrites items/*.yml and leaves a .bak backup per file |
--apply is equivalent to confirm. The command requires emakigem.admin
WARNING
If a file contains both match and an existing matcher (or top-level slot_groups), the conversion reports a conflict and skips that file. Merge them manually first
Run the dry run first anyway to review the diff. match.item_sources is promoted straight to the top-level item_sources field and never written inside matcher, so converted files need no manual fix-up
Slot fields (slots)
| Field | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
index | integer | Yes | — | ≥ 0 (negative entries are dropped) | Socket index, starting at 0 and unique |
type | string | No | "universal" | any type name | Socket type, deciding which gems can be inlaid |
display_name | string | No | type | MiniMessage text | Socket display name in the GUI |
Weapon socket item example
yaml
id: "weapon_socket_item"
slot_groups:
- "weapon"
item_sources:
- "minecraft-diamond_sword"
slots:
- index: 0
type: "attack"
display_name: "<red>Attack Socket</red>"
- index: 1
type: "universal"
display_name: "<white>Universal Socket</white>"
- index: 2
type: "defense"
display_name: "<blue>Defense Socket</blue>"
default_open_slots:
- 0
allowed_gem_types:
- "attack"
- "defense"
- "utility"
- "universal"
max_same_type: 0
max_same_id: 1
gui:
gem_template: "gem/default"
open_template: "open/default"
obtain:
name_actions:
- action: "prepend_prefix"
value: "<gold>✦</gold> "
lore_actions:
- action: "append"
content:
- "<gray>Sockets: <dark_gray>(%opened_slots%/%total_slots%)</dark_gray></gray>"
actions:
- 'send_message text="<gray>Socketable item detected: <yellow>%item_definition_id%</yellow></gray>"'obtain applies the first time the item is recognized and the gem layer is written. Its lore_actions can use template variables such as %opened_slots%, %total_slots%, and %item_definition_id%
GUI directories
| Directory | Purpose |
|---|---|
gui/gem/ | Inlay, extraction, upgrade, and reroll GUI templates |
gui/open/ | Socket opening GUI templates |
GUI blocks and placeholders
In gui/gem/*.yml and gui/open/*.yml, each block under slots declares which renderer owns it through type. Blocks with a type are filled in dynamically, and the custom_name and lore written in the block are only templates resolved through placeholders at render time. Blocks without a type (frames and fillers, for example) are purely static decoration and take no placeholder substitution
Type constants
type | View | Purpose |
|---|---|---|
target_item | Inlay / Open | Target equipment display slot |
socket_info | Inlay / Open | Socket overview information |
socket_slot | Inlay / Open | A single socket cell; when several slots are declared they map to socket indexes in order |
preview_display | Inlay / Open | Preview of the pending operation |
confirm | Inlay / Open | Confirm button |
socket_summary | Inlay | Aggregated socket statistics |
opener_item | Open | Socket opener input slot |
mode_inlay | Inlay | Switch to inlay mode |
mode_extract | Inlay | Switch to extract mode |
mode_upgrade | Inlay | Switch to upgrade mode |
mode_reroll_full | Inlay | Switch to full reroll mode |
mode_reroll_value | Inlay | Switch to value reroll mode |
A type value not listed here is owned by no renderer, so the block degrades to a static item
Placeholder groups
Each type supplies one pair of placeholders: the title placeholder goes into custom_name and the line collection placeholder into lore
type | Title placeholder | Lines placeholder |
|---|---|---|
target_item | %target_title% | %target_lines% |
socket_info | %info_title% | %info_lines% |
socket_summary | %summary_title% | %summary_lines% |
socket_slot | %slot_title% | %slot_lines% |
preview_display | %preview_title% | %preview_lines% |
confirm | %confirm_title% | %confirm_lines% |
opener_item | %opener_title% | %opener_lines% |
All mode_* | %mode_title% | %mode_lines% |
Every mode_* block shares the same placeholder pair; the renderer picks the wording from that block's type, so all five mode blocks can use an identical template
How line placeholders expand
Line placeholders (%*_lines%) expand differently from plain placeholders when written inside lore:
| Form | Result |
|---|---|
A line containing only %x_lines% | Expands into one line per collection element |
| Empty collection | Expands to zero lines; the line disappears |
Mixed inline form (such as Stats: %x_lines%) | Does not expand; stays a single line and keeps the prefix |
| Placeholder not supplied | Kept literally, showing %key% to the player |
custom_name only performs scalar substitution and never expands into multiple lines
Besides the title and line placeholders, some blocks supply extra scalar placeholders (such as %slot% for socket cells, and %item%, %opened%, %total%, %locked% for socket info) that can be referenced directly in line text
WARNING
After a plugin upgrade, GUI files that already exist under plugins/EmakiGem/gui/ are left untouched, and their existing keys are not overwritten by the bundled version either: default GUI resources are static files, released only when the target path is missing; only config.yml and lang/*.yml use the versioned merge that brings bundled content in for new keys while leaving existing keys as they are. Existing configuration therefore does not pick up newly added type values, new blocks, or the placeholder-supplied form
Bundled GUIs rely on placeholder supply: for a dynamic block with a type, the renderer replaces the title and lines at render time, so slots.<block>.item.components.custom_name should be %<block>_title% and slots.<block>.item.components.lore should be %<block>_lines% (line placeholders, see How line placeholders expand). If that same key on your server holds fixed text, it is kept as-is and never becomes a placeholder or picks up new bundled wording. To adopt new content, rewrite those keys as placeholders (and add any missing type and blocks), or back up and delete the GUI file so the plugin releases the default version again
Use different socket definitions for weapons, armor, and accessories so gems cannot be inserted into unintended equipment