Skip to content

Gem Definitions ​

Gem definition files are stored in gems/*.yml. A gem definition describes how the gem item is recognized, which socket types it supports, what effects it provides, and how inlay, extraction, and upgrade costs are handled. The gem id comes from the id field inside the file and is unrelated to the file name. Shipped default file: gems/example_gem.yml

Top-level fields ​

FieldTypeRequiredDefaultRangeDescription
idstringYes——Unique gem id. Lowercased on load; the file is skipped when blank
display_namestringNoidMiniMessage textDisplay name
lorelistNoempty listMiniMessage textLore of the gem item itself
gem_typestringNo"universal"any type name (commonly attack, defense, utility, universal)Gem type used for socket compatibility matching
levelintegerNo1≥ 1Base gem level; increases on upgrade
base_item_sourcestringYes—item source shorthand "provider-itemId"Construction base material: which item is built when the gem is granted. A single item source shorthand, not a list, and not a matching position. The gem is skipped when it cannot be parsed. The legacy top-level item_sources key is still read as a fallback for this value (only when it has exactly one entry)
item_sourceslistNoempty (unrestricted)item source shorthandRecognition: allowed item sources for the gem item. ANDed with the sibling matcher
matcherobjectNoemptysee Item MatcherRecognition: non-item-source conditions only (component, PDC, lore)
custom_model_dataintegerNounsetany integerOptional custom model data
effectslistNoempty listsee Effect typesEffects applied when the gem is inlaid
socket_compatibilitylistNoempty (any socket type)socket types; containing universal also means anySocket types that can accept this gem
required_gemslistNoemptygem idsGem ids this gem depends on; lowercased and deduplicated on load
conflicting_gemslistNoemptygem idsGem ids that conflict with this gem; checked in both directions
inlay_costobjectNono costsee Cost configurationCost paid when inlaying
extract_costobjectNono costsee Cost configurationCost paid when extracting
extract_returnobjectNooriginal / 1 / 0.0see Return modesHow the gem is returned after extraction
stagesobjectNodisabledsee Upgrade stagesUpgrade stage settings. The parser reads stages first
upgradeobjectNo—same as stagesFallback alias for stages. Read only when the file has no stages key
rerollobjectNodisabledsee RerollReroll settings
actions.inlay_successlistNoemptyCoreLib action linesAction lines run after a successful inlay
actions.extract_successlistNoemptyCoreLib action linesAction lines run after a successful extraction

NOTE

Listing universal in socket_compatibility lets the gem go into any socket type

Minimal example ​

yaml
id: "ruby_basic"
display_name: "<red>Ruby</red>"
gem_type: "attack"
level: 1
base_item_source: "minecraft-redstone"
item_sources:
  - "minecraft-redstone"
socket_compatibility:
  - "attack"
  - "universal"
effects:
  - type: "variables"
    variables:
      physical_attack: 5
  - type: "ea_attribute"
    ea_attributes:
      physical_attack: 5.0

Effect types ​

TypePayload keyDescription
variablesvariablesRuntime variables used by lore templates and formulas
ea_attributeea_attributesEmakiAttribute PDC attributes written to equipment
es_skilles_skillsEmakiSkills skill attachments
name_actionname_actionsName operations applied to equipment
lore_actionlore_actionsLore operations applied to equipment

Values under variables and ea_attributes may be numbers or expressions and can reference %level%; keys resolved earlier in the same block are available as variables to later expressions

Top-level form ​

Besides the effects list, the parser also accepts variables, ea_attributes, name_actions, and lore_actions written directly on the gem root:

yaml
variables:
  physical_attack: 8
ea_attributes:
  physical_attack: 8.0

variables and ea_attributes merge both forms, with keys from effects overriding top-level keys. For name_actions and lore_actions, a top-level value takes precedence and the matching effects entry is ignored. Skills can only be declared through es_skill inside effects

Cost configuration ​

inlay_cost, extract_cost (and reroll.full_cost / reroll.value_cost) share the same structure, a cost object:

FieldTypeRequiredDefaultRangeDescription
currencieslistNoempty listeach entry is a currency entryCurrency cost list
materialslistNoempty listeach entry is a material entryMaterial cost list

Currency entry (currencies[]):

FieldTypeRequiredDefaultRangeDescription
providerstringNo"auto"economy provider idCurrency source; lowercased on load
currency_idstringNo""—Currency id (a sub-currency under the same provider)
amountdoubleNounset (formula used)a value > 0 is used as a fixed amountFixed amount; when omitted or ≤ 0 the cost is computed from cost_formula / base_cost
base_costdoubleNo0≥ 0Value of %base_cost% inside cost_formula
cost_formulastringNo""expression using %base_cost%, %level%, and so onAmount formula; blank with no amount falls back to base_cost
display_namestringNo""MiniMessage textDisplay name of the cost

Every currency entry must supply at least one of amount (> 0), base_cost (> 0), or cost_formula, or it is dropped; an entry whose resolved amount is ≤ 0 does not take effect either

Material entry (materials[]):

FieldTypeRequiredDefaultRangeDescription
item_sourceslistYes—item source shorthandMaterial item source (syntax in Item Source); the entry is dropped when it cannot be parsed
amountintegerNo1≥ 1Amount consumed

Cost example ​

yaml
inlay_cost:
  currencies:
    - provider: "vault"
      currency_id: ""
      base_cost: 1000
      cost_formula: "%base_cost% * %level%"
      display_name: "<gold>Coins</gold>"
  materials:
    - item_sources:
        - "minecraft-gold_nugget"
      amount: 1

Upgrade stages ​

Gems support level-based upgrade stages. You can override the display name and the effects at each stage to unlock stronger stats or skills

There are two possible top-level keys: the parser takes stages first and only falls back to upgrade when that key is absent. Both have exactly the same structure and meaning; upgrade is only a legacy alias

WARNING

When a file declares both stages and upgrade, upgrade is ignored entirely (the two are not merged). Use stages in new configuration

Stage block fields ​

FieldTypeRequiredDefaultRangeDescription
enabledbooleanNotrue when at least one level parsed, otherwise falsetrue / falseWhether upgrading is enabled
max_levelintegerNothe highest configured level, or 1 when none parsed≥ 1Maximum level; also the level upper bound used by item-layer previews
gui_templatestringNo""GUI template idParsed and retained, but currently has no consumer, so setting it has no effect. The upgrade view reuses gui.gem_template from the socket item definition
levelsobjectNoemptykeys are integer levels greater than 1Per-level configuration. When this key is omitted, the numeric keys of the stage block itself are read as the level table

Level keys must parse as integers greater than 1; 1 and below, and non-numeric keys, are skipped

Level fields ​

FieldTypeRequiredDefaultRangeDescription
display_namestringNo""MiniMessage textDisplay name for that level
variablesobjectNoemptykey/value pairs; values may be numbers or expressionsExpression variables for that level; keys are lowercased and an earlier-resolved key is available to later expressions
ea_attributesobjectNoemptykey/value pairs; values may be numbers or expressionsPDC attributes for that level
effectslistNoempty listsee Effect typesEffect list for that level, same format as the base effects
name_actionsobject/listNoemptyCoreLib name operationsName operations for that level; takes precedence over the base name_actions when present
lore_actionsobject/listNoemptyCoreLib lore operationsLore operations for that level; takes precedence over the base lore_actions when present
matricesobjectNoemptystring key/value pairsString key/value table for that level; keys are lowercased

DANGER

Neither the stage block nor a level block reads materials, economy, success_rate, success_rates, or failure_penalty. Writing those keys into a gem definition raises no error but has no effect at all. Upgrade materials, costs, and the success roll are decided by the matching EmakiStrengthen enhancement recipe; without a usable recipe, or when EmakiStrengthen is unavailable, the upgrade entry reports that upgrading is unavailable

Stage example ​

yaml
stages:
  enabled: true
  max_level: 4
  gui_template: "upgrade/default"
  levels:
    2:
      display_name: "<red>Ruby II</red>"
      effects:
        - type: "variables"
          variables:
            physical_attack: 12
        - type: "ea_attribute"
          ea_attributes:
            physical_attack: 12.0

Omitting levels and writing levels directly under the stage block is equivalent:

yaml
stages:
  2:
    display_name: "<red>Ruby II</red>"
  3:
    display_name: "<red>Ruby III</red>"

Reroll ​

Reroll re-rolls a gem's affixes. Configure it in the reroll block of a gem definition; skip that block and reroll stays disabled for the gem

Reroll block fields ​

FieldTypeRequiredDefaultRangeDescription
enabledbooleanNotrue when a reroll block is present; reroll is disabled when the block is absenttrue / falseWhether reroll is enabled
groupstringNo"default"affix pool group nameWhen pools has no such group, the pool named default is used instead; with no default either the pool counts as empty and reroll fails
max_affixesintegerNo1≥ 1Upper bound on affixes generated by a full reroll
poolsobjectNoemptykeys are group names, values are affix entry listsAffix pools. Fallback alias affixes (read only when pools is absent)
full_costobjectNono costsame structure as inlay_cost, see Cost configurationCost of a full reroll
value_costobjectNono costsame structure as inlay_cost, see Cost configurationCost of a value reroll

Affix entry fields ​

FieldTypeRequiredDefaultRangeDescription
idstringNothe entry key in map form—Affix id; the entry is skipped in list form when no id can be found
weightdoubleNo1≥ 0; non-positive values are recorded as a diagnosticRoll weight
min / maxdoubleNomin = 0, max = mina value range; min and max are swapped when max < minValue range. Aliases min_value / max_value
min_stage / max_stageintegerNo1 / unbounded≥ 1 and max_stage ≥ min_stageUsable stage range; entries outside the range are filtered out by the gem's current stage before rolling
display_namestringNoidMiniMessage textAffix display name
attribute_idstringNoidattribute idMatching attribute id

Reroll modes ​

ModeBehaviourCost key
Full rerollRe-rolls the affixes themselves by weight. The count is the smaller of max_affixes and the existing affix count, or max_affixes when the gem has no affixes yetfull_cost
Value rerollKeeps the existing affix ids and stages and only re-rolls values inside each affix's min/max rangevalue_cost

Settlement rules ​

Reroll runs in two steps: generate a candidate first, then confirm it:

  1. Opening reads the gem in the main hand, generates a candidate, charges immediately, and opens a candidate session with a time-to-live
  2. Confirming validates the config fingerprint and the item instance; the candidate is written to the main-hand gem only when both match

WARNING

If the gem definition changed before confirmation (fingerprint mismatch), or the main-hand item changed, the session fails and is discarded. Every termination path other than a successful confirm refunds the charge; when the player is offline at that moment the refund becomes pending and runs once the player can be scheduled again

yaml
reroll:
  enabled: true
  group: "default"
  max_affixes: 2
  pools:
    default:
      - id: "physical_attack"
        weight: 10
        min: 5
        max: 12
        min_stage: 1
      - id: "physical_crit_rate"
        weight: 5
        min: 1
        max: 4
  full_cost:
    currencies:
      - provider: "vault"
        currency_id: ""
        base_cost: 3000
        display_name: "<gold>Coins</gold>"
  value_cost:
    currencies:
      - provider: "vault"
        currency_id: ""
        base_cost: 800
        display_name: "<gold>Coins</gold>"

Reroll command entries and the session query API are documented in Commands and Permissions and API

Design notes ​

  • Use stable item_sources for recognition instead of display names or lore matching, and keep base_item_source pointing at the item you actually hand out
  • Keep gem_type and socket_compatibility simple and easy to understand
  • Write real stats through ea_attribute; use lore actions only for presentation
  • Use extract_return carefully on high-value gems