Skip to content

Cross-Module Integration (Qinhuai Ecosystem Data Flow)

Section: Developer · Related: Integration · Integration in Practice · Attributes & Numbers

QI is not an island. It works together with QinhCoreLib (QCL), QinhSkills (QS), and AttributePlus (AP). This chapter explains how data flows between them and how responsibilities are divided.


1. Module Responsibilities

QinhCoreLib (QCL)  ── base: unified item-source management, attribute-pipeline contract, action contract

       │ depends on
QinhItems (QI)     ── items: definition/assembly/actions/sets/binding/gems (no numbers, no casting)
       │ pass through skills   │ hand off attributes
       ▼                       ▼
QinhSkills (QS)    AttributePlus (AP)
  skill engine        numbers backend
ModuleResponsible forNot responsible for
QCLItem-source registry, ItemManagerAPI prefix resolution, action contract typesConcrete item content
QIItem templates / assembly / Lore / actions / sets / binding / gem socketsNumeric computation, skill casting
QSSkill definition and castingItems
APActually applying attribute numbers to the playerItems

Core principle: QI does not compute numbers and does not cast. Numbers go to AP, skills go to QS.


2. QI ↔ CoreLib

QI registers itself as an item source

On startup QI registers itself into CoreLib's item-source system (QinhItemsItemSource, id qinhitems, alias qi), and registers its item module into ItemManagerAPI (aliases qinhitems / qi / QinhItems).

Others fetch QI items through CoreLib

java
// Prefix resolution lives in CoreLib —— any plugin that hooks CoreLib can fetch QI items this way
ItemStack s = ItemManagerAPI.getHookItem("qi:demo_thunder_edge");

CoreLib unified item-source prefix table

ItemManagerAPI.getHookItem(ref) / ItemSourceManager.parseItemReference(ref) recognize the prefixes below (ItemSourceType). QI items' material field and other plugins fetching QI items both go through this same set:

Item sourceidAliases
Vanillavanillaminecraft / mc / v / material / type
CraftEnginecraftenginece / craft-engine
ItemsAdderitemsadderia
Nexonexonx
MMOItemsmmoitemsmi
NeigeItemsneigeitemsni
MythicMobsmythicmobsmm / mythic
MagicGemmagicgemmg / magic-gem
CustomFishingcustomfishingcf
QinhItemsqinhitemsqi

Reference grammar (ItemReferenceParser):

<prefix>:<itemID>            ce:dragon_blade   /   nexo:ruby
<prefix>-<itemID>            ce-dragon_blade (: and - are equivalent; prefix is taken before the first -)
<prefix>-<itemID>::{json}    ni-blade::{"品质":"传说"} (pass params to the backend at the end)
mi-<type>-<ID>              mi-SWORD-Legendary (MMOItems special case → SWORD:Legendary)
<no separator>              iron_sword (resolved as a vanilla Material)

Diagnostics: ItemManagerAPI.diagnose(ref) returns a DiagnosticResult, with codes including SOURCE_NOT_FOUND (prefix not registered = plugin not installed), ITEM_NOT_FOUND (no such ID in the source), and ITEM_REF_PARSE_FAILED (malformed format). On the server-owner side, see Item Definition §5.1.

Key boundary

CapabilityWhere
qi:id / qinhitems:id prefix resolutionCoreLib's ItemManagerAPI
Item reverse lookup (item → id), isQinhItemQI's QinhItemsAPI
Generating by IDBoth work (CoreLib forwards to QI, or QI directly via assembly().build)

So: qi: prefix resolution depends on CoreLib; reverse lookup / direct generation depend only on QI. For onboarding routes see API Overview.


3. QI ↔ AttributePlus

Data flow

Item providers.ap = {"attack_damage":18}
   │ ICVM key attack_damage ──(config.yml attribute-mapping)──► AP name "物理伤害"

Equipment change → EquipmentScanner reads → ApBlobParser formats → "物理伤害: 18"

AttributeBackend.apply(player, "qi:equip:mainhand", lines) → AttributePlus applies
  • Six independent per-slot sources qi:equip:<slot>, set source qi:set:<id>.
  • No AP → NoopAttributeBackend (pure item-library mode).

For the full explanation see Attributes & Numbers.

Custom attribute backend

Not using AP? Implement and register an AttributeBackend, and QI will hand attributes off to your system:

kotlin
QinhCombatAPI.registerAttributeBackend(MyBackend())

4. QI ↔ QinhSkills

Data flow

In an item action / set abilities:
   - handler: qinhskills:cast
     payload: {"skill":"fireball","level":1}


QI action dispatch → QISkillBridge handler → QinhSkills receives the cast request


QS actually casts (may further call MythicMobs)
  • QI only declares and passes through the payload; it does not parse skills and does not cast.
  • The link is done by QinhSkillsLinker, supporting late loading (QinhSkillsEnableListener).

For the linking mechanism see Integration → QinhSkills; for onboarding steps see Integration in Practice.


5. QI ↔ Legendinlay / MagicGem

Item gem-sockets: [qi_weapon]
   │ GemSocketService.syncProviders

providers.legendinlay = {"sockets":["qi_weapon"],...}

   ▼ bridge resolution (LegendinlayProviderBridge)
LI/MG backend identifies sockets by socket lore → player inlays
  • Socket type mapping is in gem_socket_types.yml; the socket catalog lore must match the backend verbatim.
  • The LegendCore bridge (with a groovy fallback) makes the qi- prefix usable in LegendCore.

See Gem Sockets and Integration → Legendinlay.


6. A complete call-chain example (player left-clicks to cast a skill and deal damage)

Player left-clicks the weapon
  → QI ActionTriggerListener captures left_click
  → validates conditions / cooldown / consume
  → dispatches refs:
        · combat:swing (heavy) → QinhCombatSwingEvent → player.attack()
              → damage is settled by AttributePlus per item providers.ap
        · qinhskills:cast {"skill":"...","level":1}
              → QISkillBridge → QinhSkills casts → (possibly) MythicMobs skill
  → deducts consume, records cooldown
  → QinhActionDispatchedEvent (for listener statistics)

Each link has a clear responsibility: QI dispatches, AP computes damage, QS casts the skill.


7. Load order and dependencies

RelationshipNotes
QCL → QIHard dependency; QCL must start first
QI ↔ QSSoft dependency; either order works (QI supports late-loading linking)
QI ↔ APSoft dependency, auto-detected
QI ↔ LI/MGSoft dependency

For startup-order details see Config Files → Startup Order.


Next steps