下载 App

《刀光剑影》开发者日志

10/17综合

从"画符"到肉鸽,和一次被用户点破的三连修

这一期跨了两天(10/14、10/17)。前半程把《画刃》从"画一笔出刀光"改造成三阶段肉鸽,后半程是用户上手后一口气点出的三个表现问题。日志按事情本身写,不按天数。

本期进展

1. 玩法转向:从"画符"到肉鸽
原先的核心是"在屏幕上画一笔,这一笔变成刀光"。玩家反馈方向变了——不要画符,要战斗爽。于是做了一次大转向:
  • 删掉剧情、任务、NPC、采集、宝箱、营火、交互物件
  • 保留原角色模型、程序化骨骼动画、兼容蒙皮、第三人称相机
  • 加三幕肉鸽:局内 Run 是唯一权威状态(menu / playing / upgrade / stageclear / down / result),23 项强化含 3 个突破
这里有一条反复踩的坑:"画符"和"肉鸽"是两套节奏。画符讲究"我画的形状决定结果",肉鸽讲究"数值成长决定结果"。两者硬凑会让玩家不知道自己在玩什么。最后的取舍是保留"手动出刀"的手感(单击出刀),但伤害/冷却/宽度全部由肉鸽构筑决定,形状固定为月牙。
2. 剑意越收集越少:一个数值语义错误
用户原话:“收集剑意应该是越来越多呀”。
定位到根因:升级时从同一个变量里扣掉了门槛值。
lua复制
lua
-- 旧:xp 既是"当前进度"又是"本局累计" xp = xp - xpNeeded -- 升级后数字变小
玩家看到的是"我捡了 100,升级后变 30",直觉上就是"越收集越少"。
改法是把两个语义拆开:
变量含义升级时
xp距离下一级的进度余额扣门槛
totalXP本局真正收集到的总量不扣
totalXP 只在合法接收时加一次(实际靠近吸收、或首领清场收取),掉落不计。界面上同时显示"累计剑意"和"升级进度 x / y"。
教训:一个变量承担两个语义,早晚会在 UI 上暴露成"数字不对"。 拆开比打补丁便宜。
3. 后期掉落不涨 / 首领奖励漏计
顺着剑意这条线又查出两个问题:
  • 普通怪奖励是按阶段固定的(6/8/10),后期打起来没有成长感。改成 base × 时间成长 × 职责倍率:第一幕 6、第二幕 12、第三幕 24,随时间线性涨到 2 倍,精英 ×4、首领 ×15。
  • 最终首领死亡时先切 result 再收集剑意,而 AddXP 在 result 态拒收,导致地上剑意全部漏掉。改成先 CollectAll 再 FinishStage。
4. 切幕卡顿:把"小圈选址 + 强制传送"整套删掉
用户反馈"切幕太卡了",同时点破一件更根本的事:
“我给你这么大地图你就给我放这么小个位置,那其他东西都给你占资源了是吧”
一查,确实是这样。原来每次换幕要做:
  1. 同步筛选几十个候选小战场(每个候选还要做 81 格安全/连通采样)
  2. 把角色传送过去
  3. 当帧补建脚下地形和碰撞
  4. 首次开局还会为选这个小圈顺带生成全图刷怪点数据(43×43 格、最多 4 万多次选点)
而地图是 1024×1024 米,实际只用了中间 32 米。
改法是从根上删掉这套机制,而不是给大场地打更多分:
  • 三幕在玩家当前所在位置推进强度,不传送
  • 全图可行走陆地都能打,敌潮随玩家近场刷新/回收(普通怪 72m 外归池,不算击杀)
  • 首领跑远了重新显形追上来,保留真实剩余 HP,不回满
实测切幕耗时:
按钮/主帧 CPU导演耗时
第 1→2 幕16.45ms0.32ms
第 2→3 幕17.11ms0.36ms
5. 界面重做:把"挡视野的中央大板"拆掉
用户吐槽"收集建议挡视野了"“界面不够帅,按钮也不帅弹窗也不帅”。
先做的事是看同类肉鸽的实机截图(Vampire Survivors、Death Must Die 的公开商店图),确认了一条通用规律:战斗信息贴边,复杂内容留给暂停界面。
然后重做:
  • 删掉战斗中央的大统计板
  • 生命左上、剑意/等级右上、经验条贴顶、首领血条缩成顶部细条
  • 菜单/升级三选一/结算统一成墨黑底 + 金色切角线 + 剑纹章
  • 横屏三列,窄屏纵排可滚动
6. 持续战斗卡顿:剑气几何每帧重建
切幕修完后用户仍反馈卡,加了分段计时定位到真凶:
[RogueProfile] frame=54 director=10.32 terrain=3.69 waves=184.85 post=195.09ms
剑气每帧 34ms、两道 68ms,还有 184ms 尖峰——问题在 BladeWave 每帧用 BeginGeometry 重建 1968 个顶点,每个顶点都新建 Color/Vector4(Lua userdata,GC 压力大),UV/法线/切线每帧重复写。
改法:固定拓扑 + 缓存 GetVertex 引用原位更新,UV/法线/切线只初始化一次,颜色仅在透明度变化时打包。
优化前优化后
单波 CPU约 34ms约 5ms
双波 CPU约 68ms约 10ms
600 帧 >100ms 尖峰29 次0 次
同时把敌人导航也纳入分帧预算(原来直线检测绕过了预算,0.15s 到期就同步扫整条长线)。
7. 用户点破的三个表现问题(本次会话)
用户上手后说:
“怪物攻击的时候攻击球和剑意是一样的。而且剑气挥出去和回来的时候方向还是一致的这很奇怪。怪物永远都是侧面面对着玩家的,这也很奇怪。”
三件事都确认属实,逐个修:
① 怪物永远侧面对着玩家
先做了一个朝向探针:把四种怪模型放在固定朝向下,从局部 +Z 和 +X 两个方向各拍一张。结果很清楚——四款模型的脸都朝模型局部 +X(墨灵的大眼和触须、沙魇的脸和双臂都在 +X 侧),而代码按 +Z 定义正面来转向。
[图片:暂不支持黏贴,请手动导入]
上图:修复后四只怪都正面朝镜头(能看到正脸、双眼、双臂)。
修法是给模型挂一个固定 -90° 偏航把脸转到节点前方。这里有个容易漏的点:包围盒居中偏移和贴地最低点计算也必须用同一个旋转,否则模型会偏心或穿地。
② 回旋剑气去回程朝向一样
node.rotation 只在发射时设一次,回程时月牙仍朝原方向飞,看着像"倒着飞"。加了 faceCos/faceSin,在折返点附近平滑绕竖轴掉头 180°,让凸面始终朝实际飞行方向。几何(Conform)和粒子(ToWorld)共用同一朝向,避免特效脱节。
③ 攻击球和剑意看着一样
两者原本都用同一个 Sphere.mdl 发光球,只靠颜色区分。把攻击弹体换成带尖端的 Cone.mdl 锥体、改危险橙红,并让它指向飞行方向。
实测取样对比:
外观实测色值
剑意光点青绿圆球(164, 239, 225)
攻击弹体橙红锥体(231, 132, 99)
[图片:暂不支持黏贴,请手动导入]

[图片:暂不支持黏贴,请手动导入]
上图:攻击弹体(锥形,橙红)与剑意光点(球形,青绿),形状和颜色都不再雷同。

问题与风险

① 剩余帧尖峰没有清零。 600 帧持续战斗测试最大帧耗时约 94ms,流式加载测试最大约 45ms,超过 100ms 的尖峰从 29 次降到 0 次,但仍有约 40ms 的 waves 峰和 39~84ms 的 post 峰。不能宣称稳定 60 帧。
② 首次进入地图仍有加载耗时。 全图 256 块远景地形、高度表、水面是启动时同步建立的,这部分没有动。
③ 大幅瞬移到未加载区域时,脚下物理地面需要数帧生成。 相机用的物理射线在这几帧可能没有地面命中。主角采样贴地不受影响,但正常跑图靠邻块预取规避,瞬移场景未做额外处理。
④ 本次三处修复只验证了表现,没做真机性能复测。 朝向修复给每只怪每帧多了一次 Quaternion 乘法和包围盒 8 点变换,理论上可忽略,但没有实测。
⑤ 日志配图编号有点乱。 assets/image/devlog/ 里历史编号(09_、10_)和本次(p9_)不统一,是历史遗留,暂未整理。

下期计划

  • 真机复测:剩余帧尖峰、草地密度、4K 贴图内存
  • 把 assets/image/devlog/ 从构建打包范围排除(这条从第八期欠到现在)
  • 敌人 AI 与战斗节奏(继续欠着)
  • 统一整理 devlog 配图命名