Skip to content

变量引擎

所属:服主指南 · 相关:品质与显示 · 碎片与模板

变量是物品级的动态值:随机数值、品质词、星级、动态文本等。类似 MMOItems 的占位符 / RNG 属性。


1. 变量能干什么

  • 武器每件随机滚一个伤害值。
  • 品质前缀 / 后缀文本随物品变化。
  • Lore 里插入动态数字、品质名、描述。
  • 配合星级、强化等级显示。

2. 声明变量

在物品(或碎片)的 variables: 段声明,键是变量名,值是范围静态字符串

yaml
random_blade:
  material: iron_sword
  display_name: "<gold>{tier_name} 之刃</gold>"
  lore:
    - "基础伤害:{min_damage} - {max_damage}"
    - "暴击几率:{crit_pct}%"
  variables:
    min_damage: "10 - 15"      # 范围 → 每件随机滚
    max_damage: "25 - 35"      # 范围
    crit_pct: "5 - 15"         # 范围
    tier_name: "传说"          # 静态字符串

范围语法

最小值 - 最大值空格-连字符-空格,正则 ^-?\d+(\.\d+)?\s*-\s*-?\d+(\.\d+)?$):

写法行为
15 - 25在 [15,25) 滚一个值,整数则输出 20
1.5 - 2.5在 [1.5,2.5) 滚,输出带 .0 的浮点
-10 - 10允许负数

min >= max,直接返回 min(不滚)。


3. 占位符语法

{变量名} 在文本里引用变量。合法字符:字母数字、下划线、连字符([a-zA-Z0-9_\-]不含空格)。

yaml
display_name: "<gold>{name}</gold>"
lore:
  - "伤害:<red>{damage}</red>"
  - "类型:{type}"
  - "{description}"
  • 找不到的变量原样保留{missing}{missing}),不报错。
  • 可用于:loredisplay_name、动作的 loreaction_lore 值。

4. 滚 → 解析 → 渲染 → 冲突 管线

变量经过四个阶段:

阶段干什么
Roll(滚)VariableRoller物品创建时,把范围滚成具体值,存进实例数据 values
Resolve(解析)VariableResolver + ConflictResolver多源合并出最终值
Render(渲染)VariableRenderer{变量} 替换进文本
Trace(溯源)VariableTrace记录每个变量的来源历史,调试用

解析的四个来源与优先级

来源优先级内容
TEMPLATE10definition.variables(模板声明)
INSTANCE20实例 values(创建时滚出的值)
LAYER30层补丁里的变量
RUNTIME_OVERRIDE40实例 overrides(API 运行时设置)

优先级高的胜出(RUNTIME > LAYER > INSTANCE > TEMPLATE)。不同 owner 冲突时会记录一条 VariableConflict


5. 变量的合并(碎片 / 覆盖)

变量按以下顺序叠加(后者覆盖前者):

  1. 碎片(按 fragments: 列表顺序)
  2. override.variables
  3. 根级 variables 段(最高优先级)
  4. 自动注入:若设了 tier,则 variables["tier"] = <小写tier>
yaml
dragon_plate:
  fragments:
    - armor_base                 # 碎片里 armor_type=Light
  override:
    variables:
      armor_type: "Heavy"        # 覆盖碎片
  variables:
    base_defense: "15"           # 最高优先级
  lore:
    - "类型:{armor_type}"        # → Heavy
    - "防御:{base_defense}"      # → 15

6. 保留 / 自动变量

变量来源
tier自动从 tier: 字段注入(小写)
star星级,渲染名尾 [+N](部分类型)
soulbound.owner灵魂绑定时设置,见 灵魂绑定
soulbound.level绑定等级

7. 开发者 API

通过门面 QinhItemsAPI.variables()(详见 API 参考):

kotlin
val api = QinhItemsAPI.variables()

api.get(item): Map<String,String>                    // 取解析后的变量
api.explain(item): Map<String, VariableTrace.Entry>  // 溯源(调试)
api.set(item, key, value, owner): Pair<ItemStack?, InstanceWriteResult>
api.setAll(item, values, owner): Pair<ItemStack?, InstanceWriteResult>
api.lock(item, key, owner): Boolean                  // 锁定变量,防他人改
api.unlock(item, key, owner): Boolean
api.refresh(item): ItemStack?                        // 重渲染显示

写入结果 InstanceWriteResultOK / NOT_QINH_ITEM / LOCKED_BY_OTHER / DOMAIN_VIOLATION

溯源示例

kotlin
val trace = QinhItemsAPI.variables().explain(item)
trace["damage"]?.let {
    it.value           // 最终值
    it.source          // TEMPLATE / INSTANCE / LAYER / RUNTIME_OVERRIDE
    it.owner           // 谁写的
    it.formatHistory() // "template=5 → instance=10 → runtime=15"
}

锁定

kotlin
QinhItemsAPI.variables().lock(item, "damage", owner = "my_plugin")
// 之后别的 owner 调 set 会得到 InstanceWriteResult.LOCKED_BY_OTHER

8. 存储格式

变量实例数据以 YAML 串存在物品 NBT(键 qinhitems:instance):

yaml
values:
  damage: "20"
  tier_name: "传说"
overrides:
  damage: "30"
override_owners:
  damage: "my_plugin"
locks:
  damage: "my_plugin"
seed: 12345678

种子(seed)保证可复现:相同 seed 滚出相同随机值。


下一步