Core Concepts & Architecture
Previous: Quick Start in 5 Minutes · Back to: Getting Started
Once you understand this page, every later chapter becomes simpler. Here we lay out QI's core terms and data flow. For a complete glossary, see the Glossary.
The Three-Layer Data Model of an Item
┌─────────────────────────────────────┐
YAML design │ Definition (template) │ shared by all items of the same ID
│ id / type / material / lore / │ lives in the in-memory registry
│ providers / variables / options … │
└─────────────────────────────────────┘
+
┌─────────────────────────────────────┐
state of this │ Instance (instance data) │ written in this ItemStack's NBT
one item │ values (rolled random values) / │ unique per item
│ overrides / locks / seed / │
│ soulboundOwner … │
└─────────────────────────────────────┘
+
┌─────────────────────────────────────┐
patches │ Layers │ socketing / inlaying / enhancing / affixes
after │ base → variables → section → affix → │ has an owner domain + priority
creation │ external (stacked by order) │
└─────────────────────────────────────┘
↓ Assembly Pipeline
final ItemStack (the one in the player's hand)- Definition (template): the immutable design blueprint compiled from YAML, managed by ID via
QinhItemRegistry. See Item Definition. - Instance (instance data): the mutable state written inside a single ItemStack's NBT. The key is
qinhitems:instance, and its content is a chunk of YAML. See Layers & Assembly. - Layers: patch packs (
QinhLayerPatchPack) appended after creation, stacked by the order ofQinhItemLayerType:base(10) → variables(20) → section(35) → affix(36) → external(100). Protected by the Write Domain Policy (WriteDomainPolicy) to prevent out-of-scope modifications.
Assembly Pipeline
The process of combining the three layers above into an ItemStack is called assembly, driven by QinhItemAssemblyService, which runs a series of Layer Contributors in order:
| Order | Contributor | What it does |
|---|---|---|
| 10 | BaseLayerContributor | Builds the base ItemStack from material and applies base meta |
| 20 | VariablesLayerContributor | Resolves all variables (template + instance + layer), renders them into Lore / name, handles locks |
| 35 | SectionLayerContributor | Injects Sections — prefix/suffix pools, affix pools |
| 36 | AffixLayerContributor | Injects Affixes |
| 100 | External (plugin-registered) | Third-party extensions |
Two entry points:
build(...)— fresh generation: allocates a new seed, rolls random values, runs all contributors.rebuild(item)— rebuild: keeps the existing seed / instance and re-renders (used to refresh after config changes).
For the developer API, see Layers & Assembly.
Provider
A Provider is an "external-system payload" attached to an item. It is an opaque key→value chunk of data, where the key is the external system's ID (e.g. ap, perm_effects, legendinlay, magicgem).
providers:
ap: # AttributePlus attribute payload
value: '{"attack_damage":18}'
legendinlay: # Legendinlay gem-socket payload
value: '{"set":"...","sockets":["normal"]}'QI itself does not interpret provider content; it only stores and passes it along. Interpretation is left to the corresponding Bridge. See Provider & Bridge.
ICVM and Attribute Mapping
ICVM is QI's internal "standard vocabulary" for core combat attributes (Internal Canonical Vocabulary). It maps internal keys (such as attack_damage) to the name you actually gave them in AttributePlus (such as 物理伤害). The mapping is configured in the attribute-mapping section of config.yml.
internal key attack_damage ──(attribute-mapping)──► AP display name "物理伤害"Why have this mapping layer? Because QI wants to keep configs portable, while every server may name its attributes differently in AP. See Attributes & Numbers.
Variable
A variable is an item-level dynamic value, used for random numbers, quality words, star levels, etc., and can be inserted into Lore / name via the {variableName} placeholder.
variables:
damage_roll: "15 - 25" # range → each item rolls a random value
tier_name: "传说" # static string
lore:
- "伤害:{damage_roll}" # replaced with the rolled value at render timeVariables go through a four-stage pipeline of "Roll → Resolve → Render → Conflict resolution". Multiple sources (template / instance / layer / runtime override) are merged by priority and remain traceable. See Variables.
Action = Trigger + Handler
An item's "skills / active effects" are implemented by the action system:
player does something (left click) → trigger atom left_click fires
→ check conditions (must all pass to continue)
→ check cooldown
→ check consume (must have enough to continue)
→ execute each handler in refs in order (passing payload)
→ any handler returns HANDLED → deduct consume, record cooldown- Trigger: 100+ built-in atoms (click, sneak, move, combat, container, entity interaction…) + sequence combos. See Triggers.
- Handler: 10 built-in (
qi:message/qi:sound/qi:title/qi:command/qi:give_item…) + ecosystem-registered (qinhskills:cast/combat:swing). See Handlers.
⚠️ You cannot write logic branches in YAML (if/else/switch) — this is a deliberate design boundary. For complex logic, please develop an action handler.
Type & Capability Matrix
Each item type (weapon / armor / ring / gem…) declares which capabilities (TypeCapability) it supports:
SKILL · ATTRIBUTE · GEM_SOCKET
SET · RENDER · CONSUMABLE · PROJECTILEFor example, weapon supports SKILL/ATTRIBUTE/GEM_SOCKET/RENDER, while currency supports only RENDER. The capability matrix determines whether a given type can have gem sockets or attributes. See Item Types.
Configuration File Overview
| File | Manages | Chapter |
|---|---|---|
config.yml | Main config (combat / soulbound / write-domains / attribute-mapping / gem…) | Configuration Files |
item_types.yml | Item types and capabilities | Item Types |
item_tiers.yml | Quality / Tier | Quality & Display |
enchant_limits.yml | Enchantment limits | Enchantment Limits |
items/*.yml | Item definitions | Item Definition |
fragments/*.yml | Fragments (reusable snippets) | Fragments & Templates |
sections/*.yml | Sections / affixes / pools | Sections / Affixes |
sets/*.yml | Sets | Sets |
integrations/*.yml | Gem-socket types, bridges, model catalog | Gem Sockets / Integrations |
Data Flow Overview Diagram
🖼️ [Image placeholder] End-to-end data flow diagram: YAML → TemplateCompiler → Definition → AssemblyService (Layer Contributors) → ItemStack → equip → EquipmentScanner → AttributePlus · suggested
assets/dataflow-overview.png
Once you understand all this, you can pick your role and dive deeper:
- Server owner → Item Definition
- Developer → API Overview