物品配置
Baikiruto 的物品配置围绕 ItemDefinitionLoader 展开,支持模型继承、显示模板、运行时数据、脚本、内置 Meta 快捷配置,以及 1.20.5+ 的 components。
和现有很多物品系统不同,Baikiruto 会把配置拆成“模板层”和“运行时数据层”两部分:
- 模板层:
models、displays、物品基础ItemStack - 运行时数据层:
data、data-mapper、effects、meta、components、i18n
配置文件结构
每个 items/*.yml 都支持多种真实加载方式。
方式 1:完整结构(推荐)
__group__:
models:
displays:
items:
这是默认 items/example.yml 使用的结构,也是最推荐的写法。
__group__ 的实际作用
__group__:
id: "example"
path: "example"
priority: 100
icon: "example:all_features"
这个节点主要影响 /baikiruto menu 的分组展示:
id是菜单分组 IDpath是菜单里显示给你的路径名priority越高,分组越靠前icon可以直接写 Baikiruto 物品 ID,也可以写原版材质名
如果你完全不写 __group__,Baikiruto 会按当前文件在 items/ 下的相对路径自动生成:
- 例如
items/weapons/swords.yml默认会生成分组 IDweapons/swords - 它的父分组会自动视为
weapons
方式 2:单物品模式
material: "DIAMOND_SWORD"
name: "Example Sword"
lore:
- "A simple sword"
当文件本身不包含 items、models、displays 等保留节点时,loader 会把整个文件当成一个物品定义,物品 ID 默认取文件名。
方式 3:顶层键模式
my_custom_item:
material: "STONE"
name: "Custom Item"
保留顶层键以外的 section,也会被当成独立物品条目读取。
方式 4:兼容简写
源码还支持部分兼容语法,适合做小型文件或过渡迁移。
顶层 display: 单显示定义:
display:
name: "&7<item_name>"
lore:
- "&9<item_type>"
- "&f<item_description...>"
这种写法会把当前文件里的 display 当成一个显示模板定义,模板 ID 默认就是 display。
顶层 foo$: 模型简写:
"example/base$":
material: "NETHERITE_SWORD"
effects:
glow: true
这种写法会把键名末尾的 $ 去掉,真正注册出来的模型 ID 是 example/base。
但日常文档和生产配置仍建议优先使用完整结构,兼容简写更适合快速验证或迁移旧配置。
核心配置节点
1. 基础属性节点
items:
example:
id: "example:item"
material: "NETHERITE_SWORD"
icon: "DIAMOND"
version-hash: "m12111-example"
model: "example/base"
from:
- "example/base"
display: "example/default"
字段说明:
id:物品 ID;未填写时默认取当前条目的键名material/icon/type:材质字段,三者等价version-hash:显式版本哈希;未填写时源码会根据配置自动计算 SHA-1model/from:继承模型,可写字符串或列表display:关联显示模板 ID
注意:
material不是严格必填;若当前条目和继承链都没给材质,最终会回退到STONEmodel和from都能参与模型继承,常用上可以把model理解成单引用快捷写法
2. 显示节点
name(物品名称)
# 字符串写法
name: "&6传说之剑"
# Map 写法
name:
item_name: "&6传说之剑"
# 锁定显示名
name!!:
item_name: "&6Locked Name"
lore(物品描述)
# List 写法
lore:
- "&7Line 1"
- "&7Line 2"
# Map 写法
lore:
item_type: "&7类型: 武器"
item_stats:
- "&7攻击: {damage}"
item_description:
- "&7一把传说中的神剑"
# 锁定描述
lore!!:
item_description:
- "&7Locked lore"
显示节点的真实特性:
name支持字符串或 maplore支持字符串列表或 maplore为 map 时,键会按排序顺序拼装到最终 lore 中- 显示文本在 RELEASE 显示阶段才会做运行时变量替换
- 如果你在
config.yml里开启了settings.mini-message.enabled,<red>、<gradient:...>这类标签也可以直接写进名称和 Lore
3. 数据节点 (data)
data:
durability: 240
charge: 3
player:
level: 1
durability!!: 240
player.level!!: 1
data 会直接进入运行时数据。
锁定规则:
- 使用
!!后缀表示锁定路径 - 被锁定的数据路径会写入
__locked_data_paths__ - 后续脚本或重建时,锁定路径不能被随意覆盖
4. 数据映射器节点 (data-mapper)
data-mapper:
durability_line:
type: fluxon
script: |
def current = &data["durability_current"] ?: &data["durability"] ?: 0
def max = &data["durability"] ?: 0
return current.toString() + "/" + max.toString()
data-mapper 会把脚本编译成运行时映射,在 toItemStack() 早期执行。
当前规则:
- 可以继续直接写成字符串或字符串列表
- 也可以像上面这样显式写
type+script engine可作为type的别名,source/content也能代替script- loader 最终会把 mapper 统一整理成带
type和source的内部结构
注意时机:
data-mapper在ItemReleaseEvent之前运行durability_bar、cooldown_remaining这类显示期变量尚未注入- 因此推荐在 mapper 中使用原始运行时数据,不要依赖显示阶段才生成的派生变量
5. 效果节点 (effects)
effects:
glow: true
item-flags:
- HIDE_ENCHANTS
- HIDE_ATTRIBUTES
effects 是兼容层效果映射,适合常见视觉和基础属性键。
详见 视觉效果。
6. 组件节点 (components)
components:
custom_name: "&6Example Item"
enchantments:
levels:
sharpness: 5
attribute_modifiers:
modifiers:
- type: "attack_damage"
amount: 6.0
operation: "add_value"
slot: "mainhand"
components 是现代原版 Data Components 的主入口。
详见 原版组件。
7. 国际化节点 (i18n)
i18n:
en_us:
name:
item_name: "English Name"
lore:
item_description:
- "English description"
zh_cn:
name:
item_name: "中文名称"
lore:
item_description:
- "中文描述"
i18n 会作为运行时数据的一部分保留,并在显示和脚本阶段按当前 locale 选择对应内容。
注意:
- 它不是简单的“整份配置最高优先级覆写”
- 当前最关键的是本地化
name/lore/scripts/event i18n.<locale>.scripts和i18n.<locale>.event也沿用同一套脚本源写法,既兼容旧的纯字符串,也支持type: fluxon
8. 脚本节点 (scripts)
scripts:
build:
type: fluxon
script: |
return item
release:
type: fluxon
script: |
&ops.setData("last_release", "release")
return item
release_display: |
&ops.setData("last_release_display", "release_display")
return item
drop: |
return item
常见生命周期脚本:
buildreleaserelease_displaydrop
注意:
- loader 会同时合并
scripts和event下的脚本条目 - 旧的纯字符串写法仍然可用;如果你要跟新默认示例保持一致,推荐写成
type: fluxon+script: | type默认会回落到fluxon,engine也能当作别名使用script、source、content都能放脚本文本;字符串列表会自动按换行拼接- 如果配置里声明了未注册的脚本类型,这条脚本会被跳过,并输出
log-script-type-missing !!后缀在动作触发器里用于取消底层Cancellable事件;对build/release这类生命周期脚本不要理解成“取消 BUILD/RELEASE 阶段”
9. 事件节点 (event)
event:
on_use:
type: fluxon
script: |
&ops.setData("last_trigger", "use")
return item
on_right_click:
type: fluxon
script: |
&ops.setCooldown(80)
&ops.setData("last_trigger", "right_click")
return item
on_attack: |
&ops.setData("last_trigger", "attack")
return item
data:
source: "example"
默认示例里展示过的常见触发器包括:
on_useon_interacton_left_clickon_right_clickon_right_click_entityon_attackon_damageon_block_breakon_item_breakon_consumeon_pickupon_swap_to_mainhandon_swap_to_offhandon_selecton_async_tick
如果你要控制 on_async_tick 的开关、触发间隔,或“只在某些玩家状态、世界、权限、游戏模式 / 特定槽位触发”,不要把这些条件写在 event 里,而是写到 meta.async-tick;脚本文本本身仍然写在 event.on_async_tick。
默认 items/example.yml 里其实还示范了 on_death、on_kill、on_hurt、on_shoot、on_projectile_hit、on_sneak、on_sprint、on_jump、on_respawn、on_equip、on_unequip 等更偏战斗 / 装备联动的触发器;完整 31 种写法建议直接对照 脚本系统。
事件脚本和生命周期脚本共用同一套解析规则:
- 可以直接写
on_use: | - 也可以像上面的示例一样,在触发器下面再包一层
type/script type会先做规范化(转小写、-转_)
event.data 也是真实支持的,但它会被合并进脚本上下文,而不是保留成一个独立的 &event.data 对象树。
10. Meta 节点 (meta / metas)
metas:
trace:
scripts:
build:
type: fluxon
script: |
return item
meta:
durability:
synchronous: true
remains: "example:remainder"
cooldown:
ticks: 80
by-player: true
unique:
enabled: true
bind-player: true
async-tick:
interval: 20
conditions:
worlds:
- world
permissions: "baikiruto.async.fire"
slots:
- mainhand
需要明确区分:
metas/meta-scripts:真正的 Meta 扩展入口meta:内置效果快捷配置
详见 Meta 扩展。
继承机制
Model 继承
models:
"example/base":
material: "NETHERITE_SWORD"
effects:
glow: true
"example/advanced":
from:
- "example/base"
effects:
item-model: "baikiruto:items/all_features_12111"
真实规则:
from支持字符串和列表- 支持多继承
- 子模型覆盖父模型同名字段
- loader 会处理依赖顺序并检测循环引用
运行时合并顺序
在默认物品运行时数据里,源码会按以下顺序合并:
model defaults
-> display runtime
-> item display runtime
-> display lock metadata
-> item components
-> item data
-> item data-mapper
-> item effects
-> item meta effects
-> item i18n
这也是为什么 components、effects、meta 之间会出现覆盖关系。
锁定机制
数据路径锁定
data:
durability!!: 240
player.level!!: 10
源码会把这些路径记录到:
__locked_data_paths__
显示字段锁定
name!!: "&6Locked Name"
lore!!:
- "Locked line"
material!!: "DIAMOND"
显示锁定相关的真实运行时键包括:
__locked_display_fields____locked_display_values____locked_display_signature__
这套签名不仅用于重建时恢复锁定显示,也会参与更新检测。
ItemStream 数据流
物品在 toItemStack() 时的大致顺序如下:
ItemUniqueFeature.prepare
-> ItemDataMapperFeature.apply
-> ItemReleaseEvent
-> scripts.release
-> apply selected display
-> apply i18n display
-> ItemReleaseDisplayEvent
-> scripts.release_display
-> ItemDurabilityFeature.prepare
-> ItemCooldownFeature.injectDisplayData
-> runtime display render
-> PlaceholderAPI render
-> ItemStreamTransport.sync
-> VersionAdapterService.applyVersionEffects
-> ItemNativeFeature.apply
-> ItemReleaseFinalEvent
这也是为什么:
unique.*会先生成data-mapper早于显示变量注入native是最后一轮 NBT 覆写
更新检测与 version-hash
version-hash: "m12111-example"
真实行为:
- 写了
version-hash时,直接用显式值 - 不写时,源码会根据 item、model、display、template、runtimeData 等内容自动生成 SHA-1
- 更新检查不仅比较版本哈希,还会比较锁定显示签名
因此即使 version-hash 不变,只要锁定显示签名变化,物品仍可能被判定为需要更新。
NBT 存储结构
baikiruto:
id: "example:all_features"
version: "m12111-example"
meta_history:
- trace
data:
durability: 240
unique.uuid: "..."
__locked_data_paths__:
- durability
__locked_display_fields__:
- name
__locked_display_values__:
name:
item_name: "Locked Name"
__locked_display_signature__: "..."
注意:
meta_history记录的是真正应用过的metas- 运行时数据整体存放在
baikiruto.data
完整示例
默认资源骨架
__group__:
id: "example"
path: "example"
priority: 100
icon: "example:all_features"
models:
"example/base":
material: "NETHERITE_SWORD"
display: "example/default"
displays:
"example/default":
name:
item_name: "&6Baikiruto Example Item"
lore:
item_type: "&7Target: Minecraft 26.1.1"
items:
"example:all_features":
icon: "NETHERITE_SWORD"
version-hash: "m12111-example"
model: "example/1_21_11"
display: "example/default"
默认资源里的真实组合
data:
category: "example"
tier: "legendary"
durability: 240
data-mapper:
durability_line:
type: fluxon
script: |
def current = &data["durability_current"] ?: &data["durability"] ?: 0
def max = &data["durability"] ?: 0
return current.toString() + "/" + max.toString()
effects:
glow: true
item-flags:
- HIDE_ENCHANTS
- HIDE_ATTRIBUTES
meta:
durability:
synchronous: true
remains: "example:remainder"
cooldown:
ticks: 80
by-player: true
unique:
enabled: true
bind-player: true
components:
custom_name: "&6Example All Features"
item_model: "baikiruto:items/all_features_12111"
custom_model_data: 1211101
display/def.yml 的默认显示模板
default_display_1:
name: "&7<item_name>"
lore:
- "&9<item_type>"
- "&f<item_description...>"
default_display_2:
name: "&7<item_name>"
lore:
- "&9<item_type>"
- "&f<item_description...>"
- ""
- "&a+<damage> Damage"
default_display_2 适合做“基础描述 + 额外属性尾行”这种展示风格;你也可以直接复制它改成自己的武器模板。