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
- Install AttributePlus, drop it into
plugins/, and start once to let it generateplugins/AttributePlus/attribute.yml. - Define attributes in AP (
attribute.yml), and note the display name you gave each attribute (by default there may only be "物理伤害"). - Configure the mapping in QI's
config.yml, mapping QI's internal keys to your AP display names:yamlattribute-mapping: attack_damage: "物理伤害" # On the right, fill in the real name from your AP health: "生命" defense: "防御" - Confirm combat is enabled:yaml
combat: enabled: true attribute-backend: auto # Auto-detect AP /qi reload, and check the startup / reload log:属性后端: attributeplus (已接入)= success.- Configure attributes on the item:yaml
my_sword: providers: ap: value: '{"attack_damage":18}' - Equip the item → check whether the corresponding attribute was added to the player's AP panel.
Troubleshooting
| Symptom | Cause / Fix |
|---|---|
Log shows noop | AP not installed, or combat.enabled: false |
| Attribute numbers display but don't apply | Pure item-library mode; or the mapping name doesn't match AP (the console will warn) |
| Console warns the mapping name doesn't exist | The 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:
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
- Install QinhSkills (and its dependencies). QI and QS can start in either order—QI uses
QinhSkillsEnableListenerto support late-load linking. - After startup, check whether QI's startup log
Action Handlerlist containsqinhskills:cast(linked). - Call a skill from an item:yaml
actions: triggers: left_click: trigger: { atom: left_click } refs: - handler: qinhskills:cast payload: '{"skill":"fireball","level":1}' - Call from a set bonus (note the handler uses map form):yaml
abilities: - trigger: right_click cooldown: 5s actions: - {handler: "qinhskills:cast", payload: "套装爆发技能名"} - Left-click / trigger condition → QS receives the skill-cast request.
Troubleshooting
| Symptom | Cause |
|---|---|
HANDLER_UNAVAILABLE | QinhSkills not loaded / not enabled |
| Invalid skill name | The payload's skill doesn't exist in QS; QI passes it through verbatim without validation |
| Set-bonus skill doesn't trigger | The 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
- Install Legendinlay (and LegendCore).
- Confirm the QI config is enabled:yaml
legendinlay: enabled: true socket-catalog: integrations/legendinlay_sockets.yml auto-deploy-lc-script: true - Define socket types (
integrations/gem_socket_types.yml), mapping to LI's socket:yamltypes: qi_weapon: display: "武器孔" legendinlay: qi_weapon # Corresponds to LI's socket id - Configure the LI socket catalog (
integrations/legendinlay_sockets.yml); theloremust be byte-for-byte identical to LI's side:yamlsockets: qi_weapon: label: "武器孔" lore: "武器专属孔位" - Open sockets on the equipment (YAML or GUI):yaml
my_sword: gem-sockets: - qi_weapon /qi reload. Check the startup log for宝石: LI(LC✔·N孔).- 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
| Symptom | Cause |
|---|---|
| The inlay interface doesn't recognize the socket | The LI socket catalog lore doesn't match LI's side (must be byte-for-byte identical) |
The qi- prefix can't fetch the item | The 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
- Install MagicGem.
- QI config:yaml
magicgem: enabled: true socket-catalog: integrations/magicgem_sockets.yml - Socket type mapping (
gem_socket_types.yml):yamltypes: armor: display: "护甲孔" magicgem: armor_slot - MG socket catalog (
integrations/magicgem_sockets.yml):yamlsockets: armor_slot: lore: "§7◇ §8镶嵌孔" - Open sockets,
/qi reload, and check the log forMG(N孔).
Shares the LegendinlayProviderParser parsing format. For details see Integration → MagicGem.
5. PlaceholderAPI
- Install PlaceholderAPI.
- QI automatically registers the
qinhitemsexpansion. - 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:
// 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):
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
- Integration (Architecture): bridges / registry internals
- API Recipes: complete code for market / mail / lottery, etc.
- Provider & Bridge