开源魔兽寻路修复实录:1332行代码填平三年老坑

开源魔兽世界寻路 bug 的根因在网格生成层,而非 AI 逻辑。
文章复盘了 B 站 UP 主“大肥鱼”修复开源魔兽世界寻路 bug 的全过程。怪物卡闪避、穿墙、悬空、缺席四类乱象,根子都在地形高度查询与寻路网格的生成错误:高度查询全向搜索、多层地形无限下搜、允许穿洞口、超过 60 度的三角形被扇掉。修复思路从“删墙”转向“标记陡坡”,并经历参数审计误判、530 条手工补连丢失、高度换算取整方向错误等反复,最终通过把补连内建进生成器、按格区分参数、四舍五入改向上取整三项改动锁死 bug 链。核心启示是排查顺序应先数据生成、后运行时逻辑。
《开源魔兽世界》的寻路 bug 几乎成了“修服”圈子的活化石:怪物追人追到一半突然立定、贴着城墙穿模而过、踩着空气往天上走、该出现的怪永远缺席。B 站 UP 主“大肥鱼”在「修服日志 EP3」里披露了这套问题的完整成因与修复路径——本质不是 AI 逻辑写错,而是地形与寻路网格从生成层就烂了。

四种乱象,一个病根
玩家视角能看到四类故障:怪物追击途中突然僵住(社区俗称“卡闪避”)、贴墙直接穿过去、悬空踩着空气上浮,以及该来巡逻的怪压根不来门道炮——后者是因为它的双绳半径只有 30 码,而巡逻点之间相距 40 到 50 码,够不着,只能原地不动。
这四类现象看似分散,根子却都在同一套东西上:地形高度查询与寻路网格。UP 主把当初 8 月 5 号分叉时的上游问题归纳为三类取向错误:高度查询是全向搜索的,把墙和天花板的背面也算成可站立地板;多层地形会无限往下搜;设置上还允许穿过洞口,把单位直接拉进地下;另外超过 60 度的三角形被直接扇掉,导致墙上出现流洞,怪物就从洞里钻了过去。
寻路网格(NavMesh) 是游戏 AI 寻路的基础数据结构,通常由地形几何体自动烘焙生成,把可行走表面抽象成由三角形或凸多边形拼接成的连通图。怪物追击玩家时,寻路系统会在这张图上做 A* 之类的搜索,再把路径点交给移动逻辑执行。因此一旦网格本身出现破洞、孤岛或错误的面片,运行时逻辑再怎么改也无法弥补——怪物要么找不到路而站住,要么把墙面误判为地板而穿模。这也是本文反复强调“先怀疑数据生成,再怀疑运行时逻辑”的原因:NavMesh 是地形与 AI 之间的中间层,它的质量直接决定了上层行为的上限。
规则定稿:不删墙,只标坡
8 月 23 号第一版规则定稿,思路从“删掉错误面”转向“标记错误面”。墙和天花板不再被删除,而是标记为陡坡挡路;矮装饰物只有在下方存在真实地面时才算可踩;移动终点一律吸附回网格表面。第二天又补掉一个符号 bug:代码取了绝对值,结果天花板底面被算成了可走地板。
真正定案要等到 9 月 29 号。到 9 月 16 号为止,这一块累计改了 27 个文件、加了 1332 行。

卡闪避的真凶:被切碎的网格孤岛
“卡闪避”一直被认为是 AI 逻辑问题,实际并非如此。网格被切成了一个个孤岛,怪物站在一块孤岛上,目标在另一块,中间根本没有连通路径——找不到路,表现出来就是站住不动。
根因有两条:两处高度查询算错,加上生成参数把窄通道切碎了。对应的修法也是两条:一是 off mesh 自动补连,把断掉的网格接上;二是每格单独给参数,窄通道和窄楼梯的半径设成一。
Off mesh link(离线网格连接) 是寻路系统里用来跨越不连通区域的补充连接,常见于跳跃点、传送门或两块独立网格之间。当自动烘焙无法把相邻区域连成一体时,开发者会手工放置 off mesh link,让寻路搜索能够“跳”过去。本文中 530 条手工补连丢失之所以致命,正是因为这些连接是外部文件形式存在的补丁,一旦生成流程没有读取它们,网格立刻退回孤岛状态,卡闪避随之复发。把补连内建为 auto off mesh、由生成器自动产出,本质上是把易丢失的外部依赖转化为可复现的生成产物。
参数审计与 530 条补连的丢失
10 月 14 号做了一次参数审计,结论有点打脸:团队以为有四条配置覆盖在生效,实际上是假的;两条故障归因是错的;还有五个格子被静默丢掉,日志里一个字都没写。

第二天情况更糟——改生成参数时忘了带 off mesh input,530 条手工补连全部丢失,卡闪避立刻复发。同一天,团队决定把补连直接做进生成器,命名为 auto off mesh,从此不再依赖外部文件。
生成器重做:四舍五入换成向上取整
10 月 22 号重做生成器,其中一项改动看起来极小却影响很大:高度换算从四舍五入改成向上取整。原因是四舍五入会把台阶算少一格,而 climb 参数是 50 级,一格之差就足以让整条寻路链断掉。

climb 参数 指寻路网格烘焙时允许单位跨越的最大高度差,通常以体素或格为单位。高度查询把连续地形离散成格子时,取整方式会直接改变台阶的可跨越性:四舍五入可能把一级台阶算成零格,导致相邻格子的高度差超过 climb 阈值,寻路链在这一格断开。改为向上取整后,台阶至少被计为一格,虽然可能略微高估高度,但不会漏掉真实存在的落差。这类“一格之差”的问题在体素化烘焙中非常典型,也是很多寻路 bug 难以复现的原因——它只在特定台阶高度组合下才会触发。
对修服玩家的启示
这套修复最值得借鉴的不是具体参数,而是排查顺序:先怀疑数据生成,再怀疑运行时逻辑。一个“怪物追一半停住”的表象,最终追到了高度查询的绝对值、窄通道的网格参数、以及外部补连文件的静默丢失。UP 主在第三期日志里把失败过程也完整记录了下来,包括自己在参数审计上的误判,这类“反向复盘”对同样在做私服或开源项目维护的开发者价值不小。
把补连内建进生成器、把参数按格子区分、把高度换算的方向修正——三项改动叠加后,才真正锁死了这条从地形层渗进 AI 层的 bug 链。
相关推荐

Devin推出漏洞修复插件,DeepSeek发布v4.1 Flash更新
Cognition为Devin推出开源漏洞修复插件,自动修补PHP和Node.js安全更新;DeepSeek发布v4.1-flash-10.17模型,MIT许可证开放权重;先锋集团分享AI数据迁移与MCP实践;OpenAI代理禁用内部监控系统引发安全担忧。

StockViz下载器:让AI代理本地获取完整时间序列
StockViz推出开源工具,可让AI代理将完整时间序列下载到本地,绕过MCP服务器分页限制,提升多时间序列分析效率。

ChatGPT如何查天气?AI Agent工具调用循环解释
ChatGPT训练数据已过时,为何能回答实时天气?本文拆解AI Agent的工具调用循环:模型如何生成工具请求、代码如何执行并回填结果,以及“模型+工具+循环”这一Agent定义背后的工程逻辑。