Item Definition (full item YAML fields)
Belongs to: Server Owner Guide · Related: Item Types · Attributes & Numbers · Action System
This is QI's most central chapter: how to describe an item with YAML. After reading it you'll be able to understand and write items of any complexity.
📦 Want a ready-made recipe to copy? See Item Example Library (~140 built-in examples). 🩺 Got an error? See Validation Error Quick Reference.
1. File Layout: Grouped by Type
Item definitions live under plugins/QinhItems/items/, and the file name is the type: items in weapon.yml default to type: weapon, items in ring.yml default to type: ring.
Within each file, every top-level key is an item ID, and its definition lives under that key:
# items/weapon.yml
demo_iron_blade: # ← item ID
material: iron_sword
display_name: "<white>Iron War Blade</white>"
# …
demo_thunder_edge: # ← another item
material: golden_sword
# …This is called the grouped layout, and it's the recommended style. QI also stays compatible with the old one-file-per-item layout (where the item carries an explicit
id:field); on reload it automatically migrates to the grouped layout and deletes the old file. The logic responsible for this isTypeGroupedItemFiles.
Item ID Conventions
- Lowercase, alphanumeric + underscores / hyphens.
- When referencing, use the bare ID, without prefix (
demo_iron_blade, notqi:demo_iron_blade). - Internally it passes through
QinhItemIds.normalize(): it automatically stripsqinhitems-/qinhitems:/qi-/qi:prefixes, lowercases, and converts non-alphanumeric characters to underscores. So lookups are case-insensitive.
2. Top-Level Field Reference Table
The table below lists all fields of QinhItemDefinition and their YAML keys. Bold = commonly used fields.
| YAML key | Type | Default | Meaning |
|---|---|---|---|
| (top-level key) | String | — | Item ID (unique) |
type | String | inferred from file name / misc | Item type, see Item Types |
material | String | required | Base material or external item-source reference |
display_name | String? | null | Item name, MiniMessage or legacy & color codes |
item_name | String? | null | Fallback name (used for search / item-source indexing) |
lore | List<String> | empty | Description lines (one entry per line) |
tier | String? | null | Quality (uppercase, e.g. EPIC), see Quality |
providers | Map | empty | Data providers (attributes ap, binding effects, etc.), see §4 below |
variables | Map<String,String> | empty | Variables, see Variables |
base_values | Map<String,Double> | empty | Base values (compiled into ap), see Attributes |
enchantments | Map<String,Int> | empty | Enchantments: key=level |
enchant_max_total_level | Int? | null | Total enchantment level cap for this item, see Enchantment Cap |
gem-sockets | List<String> | empty | List of gem socket type IDs, see Gem Sockets |
gem-state | Map | empty | Current inlay state of each socket |
gem-lore-override | List<String> | empty | Custom gem socket lore (overrides default) |
sections | List<String> | empty | Referenced Section IDs |
affixes | List<String> | empty | Referenced affix IDs |
fragments | List<String> | empty | Referenced Fragment IDs |
resource_pack | section | null | Resource pack / custom model |
options | section | — | Item options (see §3 below) |
actions | section | — | Actions / triggers (see Action System) |
update.version | Int | 1 | Config schema version (for migration) |
There are also two fields maintained by the system that you generally don't write by hand:
contentHash(content hash, for change detection) andsourceFile(source file name).
3. The options Section
options controls the item's meta flags, visuals, food component, custom NBT, and so on. All optional.
my_item:
material: diamond_sword
options:
# —— Durability / stacking ——
unbreakable: true # infinite durability
max_stack_size: 1 # max stack size (1–99)
max_durability: 1000 # custom max durability
# —— Display flags ——
hide_attributes: true # hide attribute tooltip (default true)
hide_enchants: false # hide enchantment tooltip
glow: true # fake enchant glow (auto-applies HIDE_ENCHANTS)
item_flags: # extra ItemFlag
- "HIDE_UNBREAKABLE"
- "HIDE_ARMOR_TRIM"
# —— Visuals ——
custom_model_data: 10001 # custom model data (if resource_pack.custom_model_data is set, that one takes precedence)
color: "#FF00FF" # leather / potion dye (hex or "R,G,B")
skull_owner: "username" # skull skin owner (username or UUID)
armor_trim: # armor trim (1.20+)
material: "minecraft:copper"
pattern: "minecraft:coast"
model_data: # 1.20.5+ advanced model component
floats: [1.5, 2.0]
flags: [true, false]
strings: ["custom_string"]
colors: ["#FF0000", "0,255,0"]
# —— Potion effects (for persistent effects while worn see providers.perm_effects; here are the item's own built-in potions) ——
potion_effects:
- "STRENGTH:200:1:false:true:true" # type:duration(ticks):level:ambient:particles:icon
- "SPEED:200:0" # the last three can be omitted
# —— Food component ——
food:
nutrition: 8 # nutrition (0–20)
saturation: 4.5 # saturation
can-always-eat: false # edible even when full
eat-seconds: 1.6 # eating duration (seconds)
# —— Constraints / binding ——
restrictions: # usage restrictions
- "level:20" # requires level 20
- "permission:vip.use" # requires permission
bind_on_acquire: true # soulbind on pickup, see Soulbinding
# —— Custom NBT ——
nbt:
"custom:key1": "value1"
"custom:number": 42
"custom:bool": truerestrictions Syntax
Written in the options.restrictions list; validated when equipping / using. If unmet, the item's lore is marked red and use is blocked (via canUse / QinhItemUseCheckEvent):
| Syntax | Meaning | Who decides |
|---|---|---|
level:20 | Requires player level ≥ 20 | QI native |
permission:xxx | Requires permission | QI native |
world:world_name | Requires being in the specified world | QI native |
class:战士,法师 | Requires class | Delegated to QinhItemUseCheckEvent (third-party implementation) |
Custom xxx:yyy | Custom | Delegated to the event |
See API Reference → canUse for details.
4. The providers Section
A Provider is an "external-system payload" attached to the item. The key is the system ID, and the value is the payload (usually keyed under value, but raw / data / payload are also supported).
my_item:
providers:
ap: # ① AttributePlus attributes
value: '{"attack_damage":18,"crit_rate":0.12}'
perm_effects: # ② persistent potion effects while worn
value: '{"strength":1,"speed":0}'
legendinlay: # ③ Legendinlay gem socket metadata
value: '{"set":"qi_blade_trio","slot":"weapon","sockets":["normal"]}'
magicgem: # ④ MagicGem gem socket metadata
value: '{...}'ap— combat attributes. See Attributes & Numbers for details.perm_effects— persistent potion effects while worn:{"effect_name":amplifier}, 0 = level I.legendinlay/magicgem— gem socket payloads, usually auto-synced and generated by the GUI /gem-sockets, see Gem Sockets for details.
A Provider can also be written in a multi-carrier-key sub-section form; for developer details see Providers & Bridges. Allowed carrier keys:
value/raw/data/payload.
5. The material Field
material determines the item's underlying ItemStack. Two ways to write it:
- Without
:or-→ parsed as a vanillaMaterialname (e.g.diamond_sword,golden_apple). - With
:or-→ treated as an external item-source reference, taking a finished item from plugins like CraftEngine / ItemsAdder / Nexo / MMOItems wholesale as the base model (along with its own model / CMD / components).
5.1 External Item-Source Reference (CraftEngine / ItemsAdder / Nexo, etc.)
Parsing is delegated to QinhCoreLib's unified item-source system (ItemSourceManager → ItemManagerAPI). Supported prefixes (aliases):
| Item source | Available prefixes |
|---|---|
| Vanilla | vanilla / minecraft / mc / v / material / type |
| CraftEngine | craftengine / ce / craft-engine |
| ItemsAdder | itemsadder / ia |
| Nexo | nexo / nx |
| MMOItems | mmoitems / mi |
| NeigeItems | neigeitems / ni |
| MythicMobs | mythicmobs / mm / mythic |
| MagicGem | magicgem / mg / magic-gem |
| CustomFishing | customfishing / cf |
| QinhItems (itself) | qinhitems / qi |
Syntax (ItemReferenceParser):
material: ce:my_custom_sword # colon form
material: ce-my_custom_sword # hyphen form (the prefix must come before the first -)
material: nexo:ruby_blade
material: ia:iron_katana
material: mi-SWORD-Legendary # MMOItems special case: mi-<type>-<ID>
material: ni-blade::{"品质":"传说"} # trailing ::{json} passes params to the backendKey points:
- The colon
:and the hyphen-are equivalent:ce:x≡ce-x. In the hyphen form, everything before the first-is the prefix, and everything after is the item ID. - When referencing an external source, you usually don't need to also configure
resource_pack.custom_model_data—the external item already comes with its own model. For the CMD / resource-pack route, see Resource Packs & Custom Models. - If the backend plugin isn't installed / the item ID doesn't exist → parsing fails → the item becomes
unhealthy. Use/qi diagnoseto see the specific reason (SOURCE_NOT_FOUND= the prefix isn't registered, i.e. the plugin isn't installed;ITEM_NOT_FOUND= that plugin doesn't have this item). - The editor also supports these references when you change the material; the input hint reads
e.g.: iron_sword / craftengine:xxx.
These prefixes are provided uniformly by QinhCoreLib and are shared across the whole ecosystem (QI / QinhSkills, etc.). For the full explanation, see Cross-Module Integration → QI ↔ CoreLib.
A failed material resolution causes the item to become unhealthy, which is reported in /qi status / /qi diagnose.
6. Full Annotated Example
A real, complex item that combines all of the above (a weapon, in the Thunder Edge style):
demo_thunder_edge:
type: weapon
material: golden_sword
display_name: "<yellow>Thunder Edge</yellow>"
item_name: "Thunder Edge"
tier: EPIC
lore:
- ""
- "<gray>Left-click to swing and summon thunder</gray>"
- "<dark_gray>Cooldown 3 seconds</dark_gray>"
providers:
ap:
value: '{"attack_damage":22,"crit_rate":0.12}'
variables:
star: "3"
enchantments:
sharpness: 3
knockback: 1
gem-sockets:
- 绿色
- qi_weapon
sections:
- quality_prefix_pool
affixes:
- legendary_weapon_affix
options:
unbreakable: true
glow: true
bind_on_acquire: false
restrictions:
- "level:20"
resource_pack:
custom_model_data: 12345
actions:
triggers:
left_click:
trigger:
atom: left_click
cooldown: 3s
consume:
- "item:minecraft-redstone:1"
refs:
- handler: qi:title
payload: "<yellow>⚡ Thunder ⚡</yellow>||<gray>The roar echoes</gray>||3||30||10"
- handler: qi:sound
payload: "minecraft:entity.lightning_bolt.thunder;1;1.2"
update:
version: 1🖼️ [Image placeholder] A screenshot of the Thunder Edge above in its in-game tooltip (hover), annotating which lore segment corresponds to which field · suggested
assets/item-anatomy.png
7. Item Health Check
On every /qi reload, QI runs healthIssues() validation on each item. Common errors:
| Error cause | How to fix |
|---|---|
id / type / material / sourceFile is empty | Fill in the required fields |
display_name and lore both missing | Provide at least one |
max_stack_size <= 0 | Change to 1–99 |
| Unknown type | type must exist in item_types.yml |
| Unknown material | material must use a valid vanilla material name or an external-source reference |
Unhealthy items are still loaded, but they're listed in /qi status / /qi diagnose / /qi problems.
8. Reload & Save
- After editing YAML →
/qi reloadrecompiles and hot-refreshes online players' items. - Saving from the GUI editor →
EditorSaveGuardfirst runsPolicyEnginevalidation, then writes back tosourceFile, and hot-reloads the action table.
For the validation rules (errors you may hit when saving), see Resource Packs and the developer-oriented constraint-system explanation.
Next Steps
- See which types are available and what each can add → Item Types
- Add attributes to an item → Attributes & Numbers
- Give an item active skills → Action System