Kzeroko KTM2

锻造运行时

锻造砧状态、配方匹配、强化结果、持久化与锻造成品事件。

更新于 2026/9/26 9 分钟阅读

锻造实现维护砧的库存、绑定图纸、批次进度与锻造者归属。本文描述 ForgeryAnvilBlockEntity 和 internal.itemlevel.SmithingStoneUpgrade 周围的内部约定,不将它们视作公共 API 门面。

它做什么

服务端刻更新完成配方步骤或装备强化,客户端渲染同步后的状态。操作见装备锻造,包括校验缺口在内的编写规则见配方数据。

运行时模型

ForgeryAnvilBlock.getTicker 安装 onCommonTick。客户端执行目前为空的客户端刻方法后返回。服务端先运行 tickSmithingStoneUpgrade;识别出强化组合,或清理已经失效的强化流程时,该刻不再处理普通配方。

状态转换
PENDING绑定配方匹配或强化组合有效时,进入 FORGING。
FORGING强度足够且材料精确匹配时消耗库存,再推进步骤或产生成品。配方不再匹配时返回 PENDING,但不清除普通锻造进度。
COMPLETE成品留在槽 0。取空该槽会重置本批,保留图纸。

方块保存配方 ID,而非配方对象。每次查找都会查询当前配方表。移除配方会停止匹配;缩短步骤列表或保存了无效索引时,可能在 matches 有机会拒绝前就抛出异常。

保存与同步字段

下表默认值指读取时缺失字段的结果;新批次默认值另行标注。库存与物品堆叠内部载荷由现有编码器处理,不属于额外的自定义锻造字段。

字段类型默认值作用
InventorycompoundCore 库存编码9 槽库存委托 IsekaiCore 的 ItemStackInventory,在该复合标签下写入 Minecraft 库存 NBT。
Statusstring读取时必需PENDING、FORGING、COMPLETE;构造时为 PENDING。缺失或无效文本经 valueOf 抛出异常。
ForgeryStepint0从零开始的步骤索引,加载时不限制范围。
ForgeryProgint0配方强度或强化敲击次数,加载时不限制范围。
ForgeryOriginalityint读取:0;新批次:10修改时限制为 0–10;isOriginal() 检查至少 5。
LockedRecipestring缺省:null使用 Identifier.tryParse,无效文本变为 null。
Blueprintcompound缺省:空保存的物品堆叠,含图纸研究状态。
ForgingPlayerUUID int array缺省:null记录首位锻造者;存在但格式错误的 UUID 不在本地修复。
ForgerySmithingUpgradebooleanfalse是否处于强化流程;刻更新时按库存重新检查。
RenderIngredientsboolean读取:false;新批次:true渲染提示。首步骤仍会渲染材料,不受此值影响。
DisplayItemcompound缺省:空加工中显示的堆叠,首步骤不显示;完成时改为显示槽 0。
ise_smithupgrade_successint0保存在装备堆叠而非方块实体上。读取下限 0,写入上限 1000000。
ise_smithupgrade_failureint0保存在装备上;读取下限 0,递增上限 11。9 次警示,超过 10 次损毁。

writeNbt 同时供区块初始数据与方块实体更新包使用。修改调用 updateListeners,客户端没有独立的锻造状态机。首步骤始终显示材料,后续步骤才遵循渲染标志。加工中显示物品仅在步骤 0 之后出现,完成后的成品始终取自槽 0。

显示层间距

中央步骤物品或成品在BASE_Y = 1.015处渲染一次。材料缩放保持0.25,生成物品的厚度为0.25 / 16格。首个槽位在基准之上抬高这一厚度。叠放副本间距为0.25 / 16 + 1 / 1024,后续每个槽位再增加该间距的九分之一。平面物品最多显示16份副本,立体模型显示一份。

这些值由ForgeryDisplayLayers管理。槽位错层可分开生成物品的表面平面;资源包的自定义几何体仍可能相交,需要在游戏内检查。

约定

交互、匹配与归属

主手交互优先级依次为:空手取成品;绑定图纸;潜行空手取图纸或查看已存计划;空手或持锤取材料;溶解重置;除 TimedInventoryItem 外的普通材料插入。

绑定时向存储复制恰好 1 张图纸,非创造模式还会扣除手中数量。取回要求库存为空、无进度、步骤为 0 且未完成。查看要求步骤已推进、库存为空且未完成。重置保留已存图纸与当前库存。

初步配方匹配按顺序比较非空堆叠,并要求精确数量。完成检查另行比较从索引 0 开始的连续槽位;自动化不可制造空洞。成功步骤清空整个库存,不会调用尚未使用的 consumeIngredients 辅助方法。

锻造状态下记录的首位敲击者拥有本批归属。其他 UUID 每次敲击使原创度减少 1,但不替换归属者。原创度初始为 10,修改范围为 0–10,至少 5 时视为原创。这些访问方法本身不负责抽取成品品质。

最终配方完成时,PlayerForgeryEvents.ON_FORGED_ITEM 接收砧、从该世界查找的可空玩家及可变输出堆叠。回调按注册顺序执行,早于成品写入槽位。随后任务制作触发器为解析到的服务端玩家计入 1 次配方完成。锻造石强化绕过此事件与配方触发器。

敲击数据包边界

正常的 Better Combat 客户端回调进行 1.5 格射线检测,要求顶面且相对命中高度至少为 0.9,然后发送 isekaiexpansion:hand_forgery。

数据包字段线类型含义
blockPosBlockPos处理器捕获的玩家世界中的砧位置。
attackSpeeddouble客户端报告的攻击速度,用于延迟执行。
hammerStrengthint客户端报告的强度;百炼千锤生效时乘以 1.5 后截断。

延迟为 int(int(1 / attackSpeed * 20) * 0.55) 刻。调度任务重新检查方块与访问接口,再调用 forge。该处理器不会独立验证距离、手持锤、攻击频率或速度是否有限且为正。这是现有校验缺口,不能视作服务端可信保证。修改砧的调用应位于其服务端世界任务路径上。

强化选择与结果

SmithingStoneUpgrade.find 接受恰好 1 组数量为 1 的合格装备及总经验为正的锻造石;其他非空物品会使组合无效。装备被复制到会话中,全部锻造石堆叠共同累计经验与单位数。装备类别及镶孔、属性回退条件位于 ItemLevelingBridge.canReceiveExperience。

每次强化敲击增加 1 点进度,不采用锤的强度。完成要求为 10 次;记录的在场锻造者拥有百炼千锤时为 5 次。找不到锻造者时,没有技艺或幸运加成。品质优先读取当前主手锤,再读取副手;均无锤时使用 IsekaiCore 的普通品质。状态中不保存最初敲击用的锤。

结果概率使用下式。hammerRarityLevel 由 IsekaiCore 的品质枚举提供。

u = sum(max(1, floor(stoneExperience / 150)) * stoneCount)
m = clamp(1 - exp(-max(0, u) / 32), 0, 1)
r = max(0, hammerRarityLevel)
l = clamp(playerLuck, -10, 20)
b = 1 when Hundredfold Hammering is active, otherwise 0

great = clamp(0.240 + 0.110*m + 0.045*r
              + 0.015*max(0,l) + 0.100*b, 0.001, 0.700)
luckReduction = l * (0.003 when l >= 0, otherwise 0.004)
failureFloor = 0.012 when m >= 0.85, otherwise 0.035
failure = clamp(0.135 - 0.105*m - 0.006*r
                - luckReduction - 0.015*b, failureFloor, 0.160)

一次随机数先落入大成功区间,再判断紧随其后的失败区间,其余为普通成功。因此,大成功和失败不是两次独立抽取。

成功通过 IsekaiCore 的物品等级器加入全部锻造石经验;百炼千锤乘以 1.15 后四舍五入,正经验奖励至少为 1。大成功额外计算 max(1, u)^0.62:向下取整且至少为 1,再按小数部分的概率进位,最终限制为 1–256。累计保存的大成功层数上限为 1000000。

失败增加永久失败次数,不提供经验;次数大于 10 时销毁装备,达到 9 时开始警示。成功不重置失败次数。每次完成的尝试都清空输入库存,消耗全部锻造石。装备存活时进入 COMPLETE,损毁则回到 PENDING。移除有效组合会清除强化进度及锻造者归属。装备属性加成由 ItemLevelAttributeApplier 另行应用。

扩展方式

普通内容通过配方与图纸定义添加。若需在内部修改最终产物,可在公共初始化期间注册:

PlayerForgeryEvents.ON_FORGED_ITEM.register((anvil, player, output) -> {
    if (player != null && anvil.isOriginal()) {
        output.getOrCreateNbt().putBoolean("example_original", true);
    }
});

此内部回调修改实际输出堆叠;不要从客户端渲染器修改世界。添加新制作模式时,应保留刻更新优先级、成品取回与图纸保留约定,并明确该模式是否触发配方事件。

验证

  • 在生存与创造模式下绑定并取回图纸;确认取成品优先,批次结束仍保留计划。
  • 测试顶面与侧面插入、堆叠合并、精确数量及颠倒材料顺序。通过开发工具制造空槽,检查两次匹配的差异。
  • 保存并重载各状态,核对全部字段;确认缺失或无效 Status 会被拒绝,而非静默重置。
  • 完成多步配方,再分别测试首位锻造者离场与其他玩家敲击,检查回调顺序及任务归属。
  • 用受控随机数覆盖强化成功、大成功、失败、9 次警示与第 11 次失败损毁;确认石料始终消耗,成功保留旧失败次数。
  • 强化途中更换锻造石组合或移除材料,确认进度重置。检查图纸在强化与重置后保留。
  • 加固数据包前,在受控开发服务器上测试无效位置、速度、强度与手持物品;当前处理器不提供权威校验。

相关页面

图纸运行时负责纸张内的研究状态。锻造配方数据负责 JSON 约定,等级与经验说明强化推动的装备成长。