Skip to content

流程说明 ​

一次强化从头到尾的流程, 以及各环节出问题时该查哪里

一次强化围绕"目标装备 + 强化配方 + 消耗材料 + 成功/失败结果"运行. 排查问题时顺着流程往下找: 先看配方是否匹配, 再看材料和费用是否够, 最后看 PDC 写入与展示刷新

标准流程 ​

text
┌─────────────────────────────────────────────────────────────┐
│ 1. 玩家打开强化 GUI                                          │
│ 2. 放入目标装备 → 读取当前星级与锻印等级                       │
│ 3. 按配方匹配规则匹配可用强化配方                             │
│ 4. 校验材料, 费用, 条件和星级上限                             │
│ 5. 计算成功率 (目标星级基础率 + 锻印加成, 钳制到上限)          │
│ 6. 触发 StrengthenPreAttemptEvent (可取消, 可改写成功率)      │
│ 7. 执行随机判定 → 成功 / 失败                                 │
│ 8. 按结果重建物品并写入 strengthen layer                      │
│ 9. 扣除经济费用                                              │
│ 10. 触发 StrengthenAttemptEvent                               │
│ 11. 执行该星级的 actions.success / actions.failure            │
│ 12. 首次达到广播星级时发送本地或全服广播                       │
│ 13. 在玩家 owner 线程安全结算 escrow, 刷新 GUI 与背包          │
└─────────────────────────────────────────────────────────────┘

排查入口 ​

现象先检查
GUI 显示无法强化配方顶层 matcher / slot_groups, 当前星级, limits.max_star 和 stars 节点
点击后提示材料不足materials, 物品来源, 数量和玩家实际背包
金币不足或扣费异常economy.currencies, 经济提供器和 cost_formula
星级没有变化strengthen layer 是否写入, 是否被失败降星或保护材料影响
Lore 没刷新CoreLib 装配是否执行, 必要时使用 /estrengthen refresh

详细阶段说明 ​

阶段 1-2: 打开 GUI 与装备识别 ​

你打开强化 GUI, 把目标装备放进指定槽位. 模块会:

  • 读取装备当前的 strengthen layer (星级, 锻印等级, 里程碑标记, 成功/失败计数, 分支路径)
  • 装备没有 strengthen layer 时, 按 +0 算

阶段 3: 配方匹配 ​

配方按文件顶层的这几个字段匹配目标装备, 几个条件要同时满足:

字段说明
matcher通用物品匹配器, 只按组件, PDC, Lore, 变量等非物品源条件判定; 顶层物品源条件使用同级 source_patterns. 见 物品匹配器
slot_groups按装备大类分的槽位组 (weapon/armor/offhand/generic), 不是具体装备槽位
stats_any拥有指定属性之一
source_patterns按物品来源模式匹配

旧版 match 块已不再被读取, 迁移方式见强化配方

另外还要求: 当前星级未达到 limits.max_star, 且目标星级在 stars 中有对应配置

阶段 4: 校验 ​

校验项失败行为
必需材料数量提示材料不足, 阻止操作
经济余额扣费失败时返回未提交结果
条件检查条件不满足时返回 strengthen.error.condition_not_met
星级上限已达 limits.max_star 时阻止操作

这一阶段会识别保护材料和锻印材料, 但不强制要求放入

阶段 5: 成功率计算 ​

text
成功率 = 目标星级基础成功率 + 有效锻印等级 × temper_chance_bonus_per_level
最终成功率 = clamp (成功率, 0, success_chance_cap)
  • 目标星级基础成功率优先取配方 success_rates 里对应目标星级的值; 配方没配时回退到 config.yml 的全局 success_rates
  • 有效锻印等级 = clamp(当前锻印 + 材料提供的 temper_boost, 0, max_temper)

阶段 6-7: 事件与随机判定 ​

StrengthenPreAttemptEvent 在主线程触发, 你可以在监听器里取消它, 也可以用 setSuccessRate 改写成功率. 随后生成 [0, 100) 区间随机数, 小于成功率即判定成功

阶段 8: 写入强化层 ​

结果星级锻印
成功提升到目标星级重置为 0
失败 (目标星级 < 6)保持不变累加锻印增量
失败 (目标星级 ≥ 6, 无保护材料)降 1 星, 最低 0累加锻印增量
失败 (有保护材料)保持不变累加锻印增量

锻印增量: 目标星级 ≤ 8 时 +1, 目标星级 > 8 时 +2; 累加后不会超过 limits.max_temper

不管成功还是失败, 装备上的成功次数, 失败次数和最后尝试时间都会更新; 成功时还会记下首次达到的星级里程碑

阶段 9-13: 扣费, 动作与安全结算 ​

  • 先重建物品, 成功了才扣经济费用; 扣费失败时本次尝试不提交
  • StrengthenAttemptEvent 在结算阶段触发
  • 对应星级的 actions.success / actions.failure 拿到的是可变 item_target, 要等动作链全部跑完才读取最终物品
  • 首次达到 broadcast.local_stars 或 broadcast.global_stars 中的星级时发送广播, 详见广播系统
  • 最终物品, 未消耗材料和其他 escrow (托管) 内容只在玩家 owner 线程结算, 然后刷新 GUI 与玩家背包
  • 材料扣除或目标物品重建/提交失败时, 源码会恢复材料数量并尝试补偿已扣的经济; 失败结果不会作为半成品继续提交

待结算与恢复 ​

结果动作跑完了, 但玩家离线或实体调度被拒绝时, 本次尝试会挂为待结算状态: 不提前发放, 也不丢弃 escrow

  • 玩家重新上线时, 模块会在该玩家的 owner 线程重试
  • 玩家再次打开强化 GUI 时也会尝试恢复待结算项
  • GUI 关闭或配置重载不会清掉已提交结果的待结算状态
  • 结算按阶段记录进度; 如果结果物品已经发放, 后续材料返现出异常时, 重试只接着跑剩下的阶段, 不会重复发放结果物品
  • 待结算项只有在全部阶段都成功后才移除, 保证重试时重复执行的结果一致

NOTE

待结算队列是当前服务器进程内的运行时恢复机制; 它不保证跨完整服务端重启后的持久化

锻印 (Temper) ​

锻印是失败时累积的等级, 用来补偿连续失败:

  • 每次失败按目标星级加 1 或 2 级锻印, 上限为 limits.max_temper
  • 每级锻印按 limits.temper_chance_bonus_per_level 提升下一次的成功率
  • 强化成功后锻印归零
  • 材料可以配 temper_boost, 在本次尝试中额外给锻印加成
  • 管理员用 /estrengthen clearcrack 清除主手装备的锻印值

锻印状态存在 strengthen layer 的 PDC 里

里程碑星级 ​

stars.<星级>.name 可以给该星级命名, 用在 GUI 展示. 装备状态会记下首次达到过的星级集合, 避免重复广播

装备达到里程碑星级时, 会触发该星级的 effects 和 actions:

  • 额外属性加成 (ea_attribute) 与技能附加 (es_skill)
  • 名称前缀或 Lore 标记 (name_action / lore_action)
  • 成功动作 (如全服广播, 音效, 标题)

动作节点 ​

星级阶段的 actions 节点支持两个键:

节点触发时机
actions.success该星级强化成功后
actions.failure该星级强化失败后

动作示例 ​

yaml
stars:
  8:
    name: "<gold>伤害提升</gold>"
    actions:
      success:
        - 'send_title title="<gold><bold>+8 物理伤害提升</bold></gold>" subtitle="<yellow>额外增伤已解锁</yellow>"'
        - "play_sound sound=minecraft:entity.player.levelup volume=1.1 pitch=1.2"
      failure:
        - 'send_message text="<red>强化失败,当前等级 +%star%。</red>"'
        - "play_sound sound=minecraft:block.anvil.destroy volume=1 pitch=0.8"

动作行里能用哪些占位符, 见占位符参考