捉虫(Bug)小记

本文简述了自己查找定位 Bug 过程中的一点思考

某日发现游戏(UE5)项目中出现了一个 Bug,表现大概是这样的:

怪物可以正常在地面上移动,但是在死亡时却会'诡异'的从地面上掉下去 ...

自己对于游戏项目的逻辑不是特别熟悉,大概跟踪了一下相关代码,发现怪物死亡时大体会走下面的逻辑流程:

  • 首先开启怪物模型(Mesh)的物理碰撞
    • SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics)
  • 接着调整怪物模型(Mesh)的碰撞响应
    • SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block)
  • 最后开启怪物模型(Mesh)的物理模拟
    • SetSimulatePhysics(true)

逻辑看上去还是挺完备的,似乎没有什么问题,但是几轮验证下来,确认只要关闭了上述逻辑,怪物的坠落问题就不存在了,所以一定是物理模拟引起了问题,但是问题究竟出在哪里呢 ? 一度让人费解 ...

好在这个 Bug 是可重现的(以我的经验,一般可重现的 Bug 都是能最终追溯到原因的,只是花费的时间长短不同),初步判断原因应该还是出在物理碰撞上,只是 UE 的碰撞处理相对复杂,跟踪物理碰撞的问题确实要花不少精力.

总之经历了多轮的 猜测验证, AI辅助, 断点调试 等操作,最终还是发现了问题点:

  • SetShapeCollisionEnabled

你可能会有些疑惑,上述的逻辑流程中并没有什么 'SetShapeCollisionEnabled' 的调用,问题怎么会出在这个接口上呢 ?

原来在怪物初始化时,项目逻辑会对碰撞 Shape 调用 'SetShapeCollisionEnabled' 来与 怪物模型(Mesh) 本身的 CollisionEnabled 做同步,而怪物模型(Mesh)本身的 CollisionEnabled 是 ECollisionEnabled::QueryOnly,这就导致碰撞 Shape 的 CollisionEnabled 也变为了 ECollisionEnabled::QueryOnly.

接着当怪物死亡处理物理碰撞时,逻辑虽然会设置 怪物模型(Mesh) 的 CollisionEnabled 为 ECollisionEnabled::QueryAndPhysics,但是碰撞 Shape 的 CollisionEnabled 依然还是初始化时设置的 ECollisionEnabled::QueryOnly,而 UE 在处理碰撞 Shape(碰撞 Shape 参与实际的物理碰撞检测)最终的 CollisionEnabled 时做了"最小化"处理(即取 怪物模型(Mesh) 本身的 CollisionEnabled 和 碰撞 Shape 的 CollisionEnabled 的最小值),继而会取 碰撞 Shape 的 CollisionEnabled 为 ECollisionEnabled::QueryOnly,即碰撞 Shape 不参与物理模拟,于是就出现了前面所说的怪物坠落问题 ...

上述流程可能说的有些繁复,但是流程本身并不是重点,不太理解的朋友不必过多关注,我们进一步要问的是,出现这个 Bug 的根本原因在哪里 ? 有没有可能避免 ?

个人认为出现这个 Bug 的根本原因还是在于细节不明 ,一般而言,在 UE 的碰撞处理上,游戏逻辑其实是不太需要去主动调用 SetShapeCollisionEnabled 的,保持默认设置即可,但是项目在怪物初始化阶段,因为细节不明 ,主动调用了 SetShapeCollisionEnabled,导致了问题隐患;同时项目在怪物死亡时,因为细节不明,又仅仅设置了 怪物模型(Mesh) 的 CollisionEnabled,而没有去处理碰撞 Shape 的 CollisionEnabled,于是触发了问题.

至于能否避免这类 Bug,个人觉得还是比较困难,除了要求个人对所编写代码尽量了解清晰明确之外(很难保证也很难执行 ...),似乎没有什么好的方法,尤其现在 AI 编码盛行,相关问题可能还会被进一步放大 ...

至此我不禁想起了多年前另一个让我印象深刻的 Bug,这个 Bug 的表现是玩家会在某个多人副本游玩过程中出现'卡死'情况,这里说的'卡死'并不是指玩家死机了,而是指玩家的游戏界面状态会和实际游戏状态不一致,继而导致玩家无法继续游戏,并且这个'卡死'是概率性的,本地测试时极难重现,线上环境也是偶尔重现.

玩家的游戏界面状态不正确,首先想到的自然是客户端是不是处理同步信息不当,但实际上客户端相关代码并不是特别复杂,看上去也没有什么问题;然后考虑是不是服务器没有正确下发同步信息,但实际看下来相关代码也比较正常,再加上 Bug 的偶现性,这个问题就被搁置下来了 ...

问题一搁就搁了好久,直到后来反馈这个问题的玩家越来越多,我们才不得不尝试在相关代码中埋点,外加测试同学不断帮忙复现,最后终于是定位到了问题:

原来在游戏逻辑层面,客户端和服务器的代码其实都没有问题,问题出在服务器给客户端同步数据的接口上,这个接口的内部实现中做了最大同步数量的优化(即一次只能给一定数量的客户端同步),超过最大数量的同步请求会被直接丢弃(并且没有任何日志 ...),于是当游戏中一次同步包含大量玩家的时候,部分玩家就不会收到同步信息,于是便出现了问题(而一般的游戏流程中,基本不会触发上述的接口问题,而出问题的多人副本玩法本身比较特殊,所以容易触发这个问题).

细细想,这个 Bug 其实也可算是 细节不明 造成的 ...


有没有解决之道呢 ? 想想还是如之前所言,没有什么好的方法.可能还是应了那句老话吧 : 软件行业没有银弹,即便在这个 AI 洪流的年代,对于有些问题,我们还是 不可不慎, 不可不察 啊 ~

相关推荐
旋生万物1 分钟前
素数螺旋映射 $z_n=n^{1+i}$ 的角分布统计检验与零模型对比
大数据·前端·人工智能·算法·云原生·螺旋生成论·螺旋相位
智能RPA5 分钟前
农业与矿业行业智能体自动化平台对比评测(计量与巡检场景)
运维·人工智能·python·自动化·agent·rpa
easyeye1235 分钟前
用开源的Toonflow和MiniMax H3一步步复刻万妖
人工智能
byte轻骑兵8 分钟前
VCP核心缩写概览
人工智能·音视频·le audio·低功耗蓝牙音频
茶杯6758 分钟前
AI重构电商视觉生产 极睿科技AGI Ecpro助力行业数字化升级
人工智能·ai重构电商·极睿科技·agi ecpro·极睿科技—agi ecpro
liferecords10 分钟前
笔记本硬跑 744B 大模型:GitHub 上的『蜂鸟』把 SSD 当显存用
人工智能·开源·大模型·推理优化
sg_knight10 分钟前
ZCode Bug 定位实战:把报错丢给 ZCode,它是怎么修的
llm·bug·agent·ai编程·glm·智谱·zcode
工业设备方案笔记10 分钟前
I3568开发板 vs X3576开发板:RK3568与RK3576到底怎么选?
人工智能
ting945200011 分钟前
深度拆解|Dif.Sh 开源特性开关(Feature Flags)技术架构与工程落地全解析
人工智能·架构·开源
2601_9623807616 分钟前
历史解说与民俗科普视频的AI自动配素材实现教程
人工智能·音视频