Skip to content

Socket Openers ​

Socket openers unlock reserved gem sockets on equipment. They separate "sockets defined by the equipment template" from "sockets currently usable by the player", which is useful for long-term progression, event materials, paid materials, or dungeon drops

Workflow ​

  1. Equipment defines available and reserved sockets in items/*.yml
  2. The player opens the socket opening GUI
  3. The player inserts the target equipment and an opener item
  4. The module checks whether the equipment matches a socket item definition
  5. The module finds a locked socket whose type is allowed by the opener
  6. On success, the opener may be consumed and the opened socket is written to the gem layer
  7. EmakiGem rebuilds the equipment presentation

Global configuration ​

Socket openers are configured under socket_openers in config.yml:

yaml
socket_openers:
  attack_drill:
    enabled: true
    item_sources:
      - "minecraft-blaze_rod"
    opens_gem_types:
      - "attack"
    consume_on_success: true
    actions:
      success:
        - 'send_message text="<green>Opened an attack gem socket!</green>"'
        - "play_sound sound=block.anvil.use volume=1.0 pitch=1.1"
      failure:
        - 'send_message text="<red>This equipment has no reserved attack socket.</red>"'
        - "play_sound sound=entity.villager.no volume=1.0 pitch=0.8"

Fields ​

FieldTypeRequiredDefaultRangeDescription
socket_openers.<id>objectNoempty (no openers)the key is the opener id (lowercased)One opener entry; the entry is skipped when the key is blank
enabledbooleanNotruetrue / falseWhether this opener is enabled. A disabled opener's item is not treated as opener material
custom_model_dataintegerNounsetany integerRestricts the opener item to a specific CustomModelData; not checked when omitted
display_namestringNoopener idMiniMessage textOpener display name
lorelistNoempty listMiniMessage textOpener lore
opens_gem_typeslistNoempty (no type restriction)socket types; containing any also means unrestrictedSocket types this opener can unlock
consume_on_successbooleanNotruetrue / falseWhether the opener is consumed after success
item_sourceslistNoempty (unrestricted)item source shorthandAllowed opener item sources. ANDed with the sibling matcher
matcherobjectNoemptysee Item MatcherNon-item-source conditions only (component, PDC, lore). The opener never matches when both item_sources and matcher are omitted
actions.successlistNoemptyCoreLib action linesActions executed after successful opening
actions.failurelistNoemptyCoreLib action linesActions executed when opening fails

Narrowing an opener with a matcher ​

How to write it: item_sources and matcher are sibling fields and both must hold. Put the item type in item_sources and only data conditions in matcher. For example, only a renamed blaze rod counts as the attack opener:

yaml
socket_openers:
  attack_drill:
    enabled: true
    item_sources:
      - minecraft-blaze_rod
    matcher:
      type: component
      component: custom_name
      operator: contains
      value: Attack Drill
    opens_gem_types:
      - "attack"

Full syntax (type list, operators, path) is in Item Matcher

Default openers ​

OpenerDefault enabledDefault itemTypesUse case
attack_drilltrueminecraft-blaze_rodattackWeapon or damage equipment progression
defense_drilltrueminecraft-prismarine_sharddefenseArmor or defensive accessory progression
universal_drilltrueminecraft-echo_shardanyRare universal opener
legendary_drillfalseminecraft-blaze_rod + matcher (name contains "legendary")attack, defenseDemonstrates "item source + component condition together"; disabled by default, enable it after confirming the match scope

Relationship with socket item definitions ​

Openers do not create arbitrary sockets. Declare the reserved sockets in the socket item definition first:

yaml
slots:
  - index: 0
    type: "attack"
    display_name: "<red>Attack Socket</red>"
  - index: 1
    type: "attack"
    display_name: "<red>Attack Socket II</red>"
  - index: 2
    type: "universal"
    display_name: "<white>Universal Socket</white>"
default_open_slots:
  - 0

Take this example:

  • attack_drill can open socket 1
  • universal_drill can open socket 1 or 2
  • If all matching sockets are already open, opening fails and actions.failure runs

Troubleshooting ​

  • Opener is not recognized: confirm that at least one of item_sources and matcher is declared, and that both conditions hold for the held item
  • No socket can be opened: check that slots has entries not listed in default_open_slots, and that the type matches
  • Opener is not consumed: check that consume_on_success is true, then check permission bypass settings
  • Display does not update: check whether the gem layer rebuilds the item and reopen the GUI if needed