简体中文
流程说明
一次强化从头到尾的流程, 以及各环节出问题时该查哪里
一次强化围绕"目标装备 + 强化配方 + 消耗材料 + 成功/失败结果"运行. 排查问题时顺着流程往下找: 先看配方是否匹配, 再看材料和费用是否够, 最后看 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"动作行里能用哪些占位符, 见占位符参考