Skip to content

Integration Hands-on Manual (Per-plugin)

Belongs to: Developer · Related: Integration (Architecture) · Attributes & Values · Gem Sockets

Integration covers the architecture; this page covers the complete steps from installation to integration testing—for server admins and developers to wire up each external plugin step by step.


1. AttributePlus (Attribute Backend)

QI's value backend. Without it, you enter pure item-library mode (items can be built, actions can trigger, but attributes won't apply to players).

Steps

  1. Install AttributePlus, drop it into plugins/, and start once to let it generate plugins/AttributePlus/attribute.yml.
  2. Define attributes in AP (attribute.yml), and note the display name you gave each attribute (by default there may only be "物理伤害").
  3. Configure the mapping in QI's config.yml, mapping QI's internal keys to your AP display names:
    yaml
    attribute-mapping:
      attack_damage: "物理伤害"     # On the right, fill in the real name from your AP
      health: "生命"
      defense: "防御"
  4. Confirm combat is enabled:
    yaml
    combat:
      enabled: true
      attribute-backend: auto       # Auto-detect AP
  5. /qi reload, and check the startup / reload log: 属性后端: attributeplus (已接入) = success.
  6. Configure attributes on the item:
    yaml
    my_sword:
      providers:
        ap:
          value: '{"attack_damage":18}'
  7. Equip the item → check whether the corresponding attribute was added to the player's AP panel.

Troubleshooting

SymptomCause / Fix
Log shows noopAP not installed, or combat.enabled: false
Attribute numbers display but don't applyPure item-library mode; or the mapping name doesn't match AP (the console will warn)
Console warns the mapping name doesn't existThe name on the right of attribute-mapping doesn't exist in AP; change it to match

For full details see Attributes & Values.

Developer: Wire up a custom attribute system

Not using AP but another attribute plugin? Implement AttributeBackend and register it:

kotlin
class MyBackend : AttributeBackend {
    override val id = "mybackend"
    override fun isAvailable() = true
    override fun apply(player, source, attributeLines): Boolean { /* apply */ return true }
    override fun remove(player, source): Boolean { /* remove */ return true }
}
QinhCombatAPI.registerAttributeBackend(MyBackend())

2. QinhSkills (Skill Engine)

In item actions / set-bonus skills, qinhskills:cast hands off skill casting to QS.

Steps

  1. Install QinhSkills (and its dependencies). QI and QS can start in either order—QI uses QinhSkillsEnableListener to support late-load linking.
  2. After startup, check whether QI's startup log Action Handler list contains qinhskills:cast (linked).
  3. Call a skill from an item:
    yaml
    actions:
      triggers:
        left_click:
          trigger: { atom: left_click }
          refs:
            - handler: qinhskills:cast
              payload: '{"skill":"fireball","level":1}'
  4. Call from a set bonus (note the handler uses map form):
    yaml
    abilities:
      - trigger: right_click
        cooldown: 5s
        actions:
          - {handler: "qinhskills:cast", payload: "套装爆发技能名"}
  5. Left-click / trigger condition → QS receives the skill-cast request.

Troubleshooting

SymptomCause
HANDLER_UNAVAILABLEQinhSkills not loaded / not enabled
Invalid skill nameThe payload's skill doesn't exist in QS; QI passes it through verbatim without validation
Set-bonus skill doesn't triggerThe handler used the string shorthand and got split incorrectly at the first colon; switch to map form

For the linking mechanism see Integration → QinhSkills.


3. Legendinlay (Gem Socket Backend A)

Steps

  1. Install Legendinlay (and LegendCore).
  2. Confirm the QI config is enabled:
    yaml
    legendinlay:
      enabled: true
      socket-catalog: integrations/legendinlay_sockets.yml
      auto-deploy-lc-script: true
  3. Define socket types (integrations/gem_socket_types.yml), mapping to LI's socket:
    yaml
    types:
      qi_weapon:
        display: "武器孔"
        legendinlay: qi_weapon       # Corresponds to LI's socket id
  4. Configure the LI socket catalog (integrations/legendinlay_sockets.yml); the lore must be byte-for-byte identical to LI's side:
    yaml
    sockets:
      qi_weapon:
        label: "武器孔"
        lore: "武器专属孔位"
  5. Open sockets on the equipment (YAML or GUI):
    yaml
    my_sword:
      gem-sockets:
        - qi_weapon
  6. /qi reload. Check the startup log for 宝石: LI(LC✔·N孔).
  7. Players use LI's inlay interface to socket gems into that equipment.

LegendCore Fallback

When auto-deploy-lc-script: true, QI automatically deploys QinhItemsModule.groovy to LegendCore/groovy/ and runs lce reload, as a backup for when the Kotlin reflection bridge fails. Check the log for 检查 LegendCore/groovy/QinhItemsModule.groovy.

Troubleshooting

SymptomCause
The inlay interface doesn't recognize the socketThe LI socket catalog lore doesn't match LI's side (must be byte-for-byte identical)
The qi- prefix can't fetch the itemThe LegendCore bridge isn't registered; check the groovy script deployment

For details see Gem Sockets and Integration → Legendinlay.


4. MagicGem (Gem Socket Backend B)

Coexists with Legendinlay, or pick one of the two.

Steps

  1. Install MagicGem.
  2. QI config:
    yaml
    magicgem:
      enabled: true
      socket-catalog: integrations/magicgem_sockets.yml
  3. Socket type mapping (gem_socket_types.yml):
    yaml
    types:
      armor:
        display: "护甲孔"
        magicgem: armor_slot
  4. MG socket catalog (integrations/magicgem_sockets.yml):
    yaml
    sockets:
      armor_slot:
        lore: "§7◇ §8镶嵌孔"
  5. Open sockets, /qi reload, and check the log for MG(N孔).

Shares the LegendinlayProviderParser parsing format. For details see Integration → MagicGem.


5. PlaceholderAPI

  1. Install PlaceholderAPI.
  2. QI automatically registers the qinhitems expansion.
  3. Use placeholders in scoreboards / Tab / holograms etc. (evaluated against the main-hand item):
    %qinhitems_socket_count%   %qinhitems_li_set%

For the full placeholder list see Placeholders.


6. CoreLib Item Source (let other plugins fetch QI items)

QI registers itself as a CoreLib item source (id qinhitems, alias qi). Other plugins:

java
// Resolve via the CoreLib prefix (note: prefix resolution is in CoreLib)
ItemStack s = ItemManagerAPI.getHookItem("qi:demo_thunder_edge");

Or use the QI API directly (only QI can reverse-look up which item a stack belongs to):

java
String id = QinhItemsAPI.INSTANCE.getItemId(stack);
ItemStack s = QinhItemsAPI.INSTANCE.assembly().build("demo_thunder_edge", 1);

For a comparison of integration routes see API Overview.


Next Steps