是_拔刀剑

是_拔刀剑

恢复Yes Steve Model在1.21.1上丢失的拔刀剑腰部挂刀、剑技动画和女仆渲染。

Bug修复

YES-SB —— 让 YSM 的拔刀剑回到 1.20.1 的样子

纯客户端模组 | Minecraft 1.21.1 | NeoForge | MIT 开源

把 Yes Steve Model(YSM) 在 1.21.1 上丢掉的 拔刀剑:重锋 表现,还回 1.20.1 的样子。


你遇到过这些吗?

在 1.21.1 上同时装了 YSM 和拔刀剑:重锋,可能会发现:

  • 第三人称里 腰上根本没有刀,只剩刀光特效;
  • 连招时 只有普通挥砍,拔刀剑的剑技动画不出现;
  • 手里的刀 待机和走路姿势与普通剑一模一样;
  • 车万女仆 手里的刀不显示,背槽里的刀变成一张 平面贴图。

同一个 YSM 版本号(2.6.5),在 1.20.1 上这些 全都是正常的。 所以问题出在 1.21.1 的构建,而不是“拔刀剑 2.x 改了什么”。

本模组把这几件事补回来。


修复内容

① 第三人称的腰挂刀与连招出鞘

拔刀剑的“刀 + 鞘”在第三人称下不是手持物,而是挂在实体渲染器上的一个渲染层(LayerMainBlade), 按 MMD 的刀挂点绘制:平时刀插在腰间的鞘里,连招时按动作把刀拔出来挥砍。

YSM 在 EntityRenderDispatcher 里接管了实体的渲染,原版渲染器不再执行, 挂在它上面的渲染层就一起停摆了 —— 腰上的刀因此消失。

本模组在“原版渲染器被跳过”的确切时机补回渲染层所需的变换环境,让拔刀剑自己那一层重新跑起来。

② 拔刀剑剑技动画

YSM 的持握/挥动解析器会按连招状态取一个动画名再播放,它的 1.21.1 构建里这套 API 的调用方是完好的, 但拔刀剑兼容模块是空实现(isSlashBlade 恒为 false),整段逻辑是死代码。

本模组补回 两个缺失的返回值:isSlashBlade(stack) 与 getAnimationName(ctx)。 动画名规则完全对齐 1.20.1 的实现(含 combo_a4_ex → combo_a4ex 的改名、居合斩的空中变体)。

如果算出的动画名不在模型包里,本模组会返回空串 —— 因为 YSM 拿到“非空但模型没有”的名字时会跳过后续 普通挥动逻辑,模型会卡在上一帧姿态出不来。这是一个踩过的坑。

③ 持刀时的专属待机 / 行走动作

手持拔刀剑时,待机 / 走 / 跑 / 跳 / 潜行 / 飞行这些主动画会先问 slashblade:idle 之类; 模型包里有就播专属动作,没有就 退回原名。这是 1.20.1 那份兼容模块的另一半,同样被掏空了。

④ 车万女仆的拔刀剑

车万女仆自己实现了女仆的拔刀剑渲染,在 1.20 与 1.21 分支源码里都还在, 但 1.21.1 的发布版 jar 里 compat/slashblade 整个包都不存在(源码在、发布 jar 里没有,可确证)。

后果是女仆手里的刀掉进普通物品渲染路径(而拔刀剑的 BEWLR 对第三方称上下文什么都不画 ⇒ 手里空着), 背槽里的刀掉进 FIXED 上下文被画成平面图标。

本模组按 TLM 源码 原样补回 那两处渲染分支,变换数值一个没改。


前置与依赖

以下均为 可选:没装的模组对应功能自动失效,不会崩溃。

模组 版本 为什么需要
Yes Steve Model 2.6.x 补偿渲染只在它存在时才有意义
拔刀剑:重锋 2.x 渲染还原依赖它公开的 LayerMainBlade
车万女仆 1.5.x 补回它的女仆拔刀剑渲染分支

必需前置:Minecraft 1.21.1 + NeoForge(21.1.x)。


安装

  1. 给 Minecraft 1.21.1 装好 NeoForge;
  2. 把 YES_SB-1.0.1.jar 放进 .minecraft/mods/(版本隔离时是 versions/<版本名>/mods/);
  3. 启动即可。

只需要装在客户端。 服务器不需要,也不会因为服务器没装而出问题。

启动后日志里搜索 [YES-SB] 可以确认状态,例如:

[YES-SB] 已就绪:YSM 2.6.5-neoforge+mc1.21.1,拔刀剑 已安装,车万女仆 已安装。第三人称腰刀补偿=开,剑技动画=开,主动画变体=开,女仆拔刀剑=开,靶向注入版本白名单=命中
[YES-SB] 注入女仆渲染层:com.github.tartaricacid.touhoulittlemaid.client.renderer.entity.geckolayer.GeckoLayerMaidHeld

没装 YSM 时会输出 [YES-SB] 未检测到 YSM:原版渲染本就正常,无需补偿。 并保持惰性。


配置

首次启动生成 config/yes_sb.properties。 所有键都支持热重载 —— 改完存盘约 2 秒生效,不需要重启游戏。

总开关:

键 默认 作用
enabled true 总开关;false 时完全惰性(等价于卸掉本模组)
debugLog false 详细日志(排查用,会明显增大日志体积)

按功能分组的常用键:

键 默认 作用
restoreThirdPerson true ① 还原第三人称腰挂刀与连招出鞘
thirdPersonScale 0.7 补偿缩放,对齐 YSM 模型的整体缩小比例
waistOffsetX / Y / Z 0 腰挂刀的额外位移(方块,正数 = 向上 / 向前)
slashbladeComboAnimations true ② 剑技动画触发
slashbladeMainStateAnimations true ③ 主动画的拔刀剑变体
maidSlashBlade true ④ 车万女仆的拔刀剑渲染
firstPersonMode auto 第一人称:auto 交回拔刀剑原生(= 1.20.1 的样子)/ model 画 3D 刀身 / icon 画平面图标 / off 永远不干预

完整键表(共 50 项)见 README。

上面这条链接不要带 #锚点 —— CurseForge 的描述编辑器会把带中文锚点的 URL 清成空 (实测贴上去会变成 href="",点了只跳回本页)。


已知限制 —— 请先读这一节

本模组把 1.21.1 上 丢失的渲染与动画触发 补了回来,但下面几条 尚未 达到 1.20.1 的效果, 列出来以免误导:

  • 玩家的刀跟不上 YSM 的动画(未解决)。 玩家这条路走的是拔刀剑自己的渲染层,它的刀挂点是从 原版玩家模型 的各部位算出来的; 而屏幕上显示的角色是 YSM 的模型在播 YSM 的动画。两套动画,刀自然对不上。 目前的表现是:手持非攻击姿态时刀在手上,整套攻击流程中刀与模型动作不同步。

  • 女仆的攻击逻辑未恢复(未解决)。 剑技动画的 触发钩子 是好的,缺的是“进入连招状态”那一步,所以女仆攻击时仍用普通动画。

  • 第一人称默认不接管(已定案)。 第一人称不经过 YSM 接管的 EntityRenderDispatcher,YSM 从来没掐过它 —— 1.20.1 的第一人称就是拔刀剑自己那套 BladeFirstPersonRender(一整把刀斜跨画面), 1.21.1 上本来也是好的。所以默认 auto:原版画得出来就放手,画不出来才兜底。 想改用本模组画的 3D 手持刀身就设 firstPersonMode=model, 并按日志里的“刀原点(相机空间)”用 firstPersonOffsetX/Y/Z 收敛。

  • 靶向注入对第三方版本敏感。 本模组依赖 YSM / 车万女仆的内部结构。上游模组更新后这些靶点可能失效, 届时对应功能会自动跳过 —— 表现为 功能不生效,不会崩溃。

  • 空中连招第二段收招后,模型会停在滞空姿势,落地也不切回地面动画(非本模组造成)。 需要按一次鼠标左/右键才能恢复;移动、疾跑、跳跃都无法解除。 排查结论:本模组的两条动画注入全部关闭时不复现(但那样也没有任何拔刀剑专属动画), 只开任意一条都复现 —— 触发条件是“让 YSM 去播模型包的 slashblade:* 动画”这件事本身, 与动画名怎么算无关。1.20.1 上同一套模型包表现正常, 故判断为 YSM 1.21.1 构建在“空中动画切回地面动画”这一步的问题。 详见 README §6.6。


与本模组无关的常见问题

  • 剑技动画要求模型包支持。 模型包需要在 ysm.json 里声明 slashblade 动画文件; 官方文档写明:不声明就沿用普通剑动画。这不是本模组能替你解决的。
  • 本模组不是 YSM 或拔刀剑的官方组件。 请不要把本模组的问题反馈给它们的作者。

设计原则与边界

本模组只做「补回」,不做替换。

  • 不自己画刀。 玩家身上的刀仍然是拔刀剑自己的渲染层(LayerMainBlade)画的 —— 本模组只是把 YSM 掐掉的那一次调用补回去。因此刀的挂点来自原版玩家模型, 整套攻击流程中玩家的刀与 YSM 模型的动画不同步(见上面「已知限制」第一条)。 要让刀真正绑在 YSM 模型的骨骼上,需要另外写一套渲染器 —— 本模组刻意没有这么做: YSM 的内部类经过混淆,绑骨骼等于绑混淆名,上游一升级就断, 而且出错是崩溃,不是“没效果”。
  • 不修改 YSM / 拔刀剑 / 车万女仆的任何文件,不包含、不再分发任何第三方的代码或资源。
  • 不依赖反射去读写别人的私有结构 —— 只调用拔刀剑与车万女仆的公开类与公开方法。
  • 所有依赖都是可选的,所有靶向注入都是失败即静默的: 靶点不存在或版本不匹配时只是对应功能不生效,不会崩溃,也不会因为版本对不上而装不上。
  • 含车万女仆:按 TLM 源码原样补回 1.21.1 发布版丢掉的两处拔刀剑渲染分支(手部 / 背槽); 上游修复后这部分即可退役。
  • 请不要与其它同类修复模组同时安装 —— 它们会抢同一条渲染路径, 可能表现为两把刀,或者互相覆盖。

与上游的关系

本模组的定位是 临时补丁,不是替代品 —— 上游修复后即退役。 本模组作者已就两侧的问题主动联系上游作者,说明来意并致歉(第一次做修复补丁,缺乏经验)。

  • 车万女仆:§④ 那两处是 发布版的移植遗漏(源码在、发布 jar 里没有,可确证)。 本模组只是把它补回去,上游修复后本模组的女仆部分即可退役。
  • Yes Steve Model:空桩 不是“有意停用”,而是当时还没做适配 —— YSM 2.6.5 开发时 1.21.1 上还没有拔刀剑,那份联动没有可适配的对象。 作者已答复:「我后面会做的,因为之前做的时候没有 1.21 的拔刀剑」, 并同意本模组 保留到官方正式修复为止。所以本模组的 ②③ 两部分在上游补上适配后即可退役。

关于运行时注入的授权:本模组对 YSM 的注入是“只补返回值、不搬运实现”, 已获其作者同意;作者亦已知悉“为定位根因做过局部的字节码层面分析”一事。 成品 jar 不含任何第三方代码或资源。

退役承诺(对上游与用户都成立):

触发条件 本模组要做的事
YSM 正式实现拔刀剑联动 声明 ②③ 失效、移除或标注对应开关
车万女仆正式补回 compat/slashblade(渲染 + 逻辑) 声明 ④ 失效、移除女仆相关混入
两侧都修完 本模组整体失去存在意义 ⇒ 从 CurseForge 撤下(按社区惯例归档而非删除,避免破坏锁定 file ID + 哈希的整合包)

四处靶向注入全部带 版本白名单 + 失败即静默:上游一改靶点,对应功能自动跳过 (表现为不生效,不会崩溃)⇒ 退役不存在紧急时间窗。 反过来也要注意:上游修好、本模组却还没退役时,用户可能分不清“是谁修好的” —— 所以这里把话说清楚。


许可与致谢

本项目以 MIT 协议开源,第三方归属的完整声明见 NOTICE。

项目 协议 本项目的关系
拔刀剑:重锋 代码 MIT / 美术 ARR 不含、不复刻其代码;仅运行时调用其公开类
车万女仆 MIT(仅 code part) 移植了其 SlashBladeRender 的变换逻辑,按 MIT 保留版权声明
Yes Steve Model All Rights Reserved 不复制、不内嵌、不再分发其任何代码或资源

本模组不包含、不再分发上述任何项目的代码或美术资源。

致谢 拔刀剑:重锋、车万女仆、YSM 三位作者 —— 没有它们干净的可读实现, “把丢失的那一层还回去”不可能做到。

代码由 DeepSeek 监修。 The code is supervised by DeepSeek. 修复:切换物品时第一人称会冒出一把横向的、跟着装备动画下落的刀。

  • 根因:firstPersonMode=auto 的兜底分支里,前置条件的最后一句是「主手是不是拔刀剑」。 切换物品时手上已经是新物品,于是被误判成「原版画不出来 ⇒ 本模组兜底」, 把正在离场的那把刀按手持物画了出来。
  • 现在只有玩家此刻确实握着拔刀剑时才接管第一人称。 判据用 mc.player 的双手,而不是传进来的那个 stack —— 装备动画里那个 stack 正是离场的刀,拿它判断等于没判断。

新增:molang 变量 slashblade_animation。

  • YSM 1.20.1 的真实现会把这个变量绑定为当前拔刀剑连招名;1.21.1 的空桩把它绑成恒定空串, 而本模组此前从未补过(旧判断「只影响调试变量」是错的 —— 模型包的 animation controller 可以读它来决定状态切换)。
  • 现已补上,语义与 1.20.1 对齐:不做「模型包有没有这条动画」的检查。

诊断(debugLog=true 时输出,供反馈问题时使用):

  • 「剑技动画为空 ⇒ 原因与实测数值」—— 这一支原先完全静默, 日志里一条都没有时分不清是「没被调用」「超时」还是「异常被吞」。
  • 「剑技动画:最近 2 秒 YSM 询问了 N 次」—— 区分「YSM 没走到这条分支」与「走到了但算出来是空」。
  • 「补偿调用:实体 / 主手 / 副手」—— 上面几条都是 2–5 秒节流,抓不到瞬时的渲染异常。
  • 异常分支原先完全不留痕,现在会报告异常类型与消息。

已知问题(未解决,且已确认不是本模组造成的):

  • 空中连招(右键连按)第二段收招后,模型停在滞空姿势,落地也不切回地面动画, 需要按一次鼠标左/右键才能恢复。移动、疾跑、跳跃都无法解除。

    排除过程:本模组的两条动画注入全部关闭时不复现(但那样也没有任何拔刀剑专属动画); 只开任意一条都复现;enabled=false 时不复现(同样是没有动画可播)。

    ⇒ 触发条件是「让 YSM 去播模型包的 slashblade:* 动画」这件事本身, 与连招名怎么算、主动画变体怎么替换都无关。 1.20.1 上同一套模型包表现正常,故判断为 YSM 1.21.1 构建在 「空中动画切回地面动画」这一步的问题 —— 该构建发布时 1.21.1 尚无拔刀剑可适配。

    试过但无效的修法(记录以免重走):关闭/开启原版姿态重算;补回 molang slashblade_animation(1.0.4 已实现)。


Fixed: a horizontal blade appearing and sliding down with the equip animation when switching away from the blade in first person.

  • Cause: the auto fallback path's precondition ended with "is the main hand a SlashBlade". When you switch items, the hand already holds the new item, so it was misread as "the vanilla renderer can't draw ⇒ fall back to us", and the blade that was leaving got drawn as a held item.
  • Now the first-person takeover only happens when the player actually holds a SlashBlade right now. The check uses mc.player's hands, not the stack passed in — during the equip animation that stack is the outgoing blade.

Added: molang variable slashblade_animation.

  • YSM's 1.20.1 implementation binds this variable to the current SlashBlade combo animation name; the 1.21.1 stub binds it to a constant empty string, and this mod never restored it (the old assumption "it's only a debug variable" was wrong — a model pack's animation controller may read it to drive state transitions).
  • Now restored, with the same semantics as 1.20.1: no "does the model pack have this animation" check.

Diagnostics (emitted when debugLog=true, for bug reports):

  • "剑技动画为空 ⇒ reason + measured values" — this branch used to be completely silent; with nothing in the log you could not tell "never called" from "timed out" from "exception swallowed".
  • "剑技动画:YSM asked N times in the last 2 s" — separates "YSM never reached this branch" from "it did, but the name came out empty".
  • "补偿调用: entity / main hand / off hand" — the others are throttled to 2–5 s and miss short-lived rendering anomalies.
  • The exception branch used to leave no trace at all; it now reports the type and message.

Known issue (unresolved, and confirmed not caused by this mod):

  • After the second segment of the aerial combo (rapid right-click) ends, the model stays in the airborne pose and does not return to the ground animation after landing. A left/right mouse click clears it; moving, sprinting and jumping do not.

    Ruled out by testing: with both of this mod's animation injections disabled the issue does not reproduce (but then there are no SlashBlade animations at all); enabling either one alone reproduces it; enabled=false does not reproduce it (again, no animations to play).

    So the trigger is "letting YSM play the model pack's slashblade:* animations" itself — independent of how the combo name is computed or how main animations are substituted. The same model pack behaves correctly on 1.20.1, so this is judged to be a YSM 1.21.1 build issue in the airborne → ground animation transition — that build shipped before a 1.21.1 SlashBlade existed to adapt to.

    Approaches tried without effect (recorded to save others the trip): toggling the vanilla pose refresh; restoring molang slashblade_animation (implemented in 1.0.4).