土拨鼠日志:你加的钩子,正在悄悄覆盖引擎原本就算对的东西
今天几乎一整天都在追同一件事:宠物吃不到道具经验加成。人物能吃到,宠物不能,差得还很有规律。这篇不聊游戏数值,聊的是排查到最后那个特别反直觉的根因——我们自己加的钩子,把引擎原本就算对的东西给盖掉了。
一、现象很整齐,结论却一路被推翻
先看现象有多干净:同一场战斗,人物基础 23 点经验,最终 +69,正好是 ×2×1.5,道具 50% 加成进了;宠物基础也是 23,最终 +46,只有 ×2,道具那 1.5 倍整段不见了。
数字这么整,人很容易先往一个方向使劲。我们前后追了好几轮,每一轮都以为「这次找到真因了」:先怀疑配置表没同步——全量逐条比对了 43 条对 44 条,漏 0 条、值差 0 条;又怀疑宠物被误判成玩家,靠探针日志回放 4200 行,真找出 59 只被误判的伴侣宠,修完还是不对。
每修一处,探针日志都显示「算得是对的」,但实际结算出来就是没加成。「算得对」和「引擎采用」之间,隔着一整层我们没料到的东西。
二、铁证:钩子返回值,被引擎当成了最终结果
最后是一张截图破了案。人物 +108、宠物 +72,宠物那 1.5 倍加成根本没进。反查探针,钩子里对宠物已经把加成算对了、取到了——那就是钩子算对、但引擎没采用,或者说:采用了我们返回的那个值,而那个值是错的。
翻代码定位到根:我们自己的经验钩子对宠物也做了计算并返回一个自算数字,宠物道具加成取 0,于是返回「基础 ×2」,把引擎原生的那套宠物加成整段覆盖掉了。
再查为什么以前没事:这套钩子是 2026-10-07 才上线的,9 月之前没有任何模块接管过经验返回值,所以引擎原生逻辑一直好好跑着。
三、修法只有一行:该放行的,原样放行
找到根因后,修法反而很小——钩子里宠物直接原样放行,把引擎交进来的值原封不动还回去,只在日志里标一句;人物那半边逻辑一个字没动。
这里藏着一条能往别处搬的规矩:
- 钩子(回调)默认应该「放行 + 记录」,而不是「无条件重算」。你拦下来算一遍,就等于宣布「剩下的都别管了,听我的」,这口气实在太大了。
- 「算得对」不等于「被采用」。排查里一旦发现「我算的没错,但结果不对」,先怀疑是不是自己把上游的正确答案拦下来、换成了自己的。
- 上线时间的差是重要线索。同一套功能「以前好、现在坏」,第一件事就是查这段时间里谁新注册了钩子、接管了什么。
四、这套排查节奏,土拨鼠是怎么帮你扣住的
一整天追下来,真正值钱的不是最后那一行,而是能让这种「长时间、多假设、反复推翻」的排查不跑偏的几样东西:
- 探针日志按时间分时段对比,改代码前后的行为差异一眼能看出来,而不是凭记忆。今天就是靠「改动前 134 场 vs 改动后 50 场」的对比,把「修没生效」和「修了但不是根因」分开的。
- 每轮结论都落成文档,标了「待验证」「已确认生效」,回看时哪一步、几点、什么证据,一目了然,不用靠翻聊天记录猜。
- 仿真回放:拿线上真实数值 + 模拟引擎接口跑一遍,比直接上生产试要稳得多,也不会为了验证去踢掉在线的人。
如果你想看土拨鼠是怎么帮你把这些长任务、探针、文档、进度卡串起来跑的,先看 功能页 里关于长任务和工作区的部分;想算一笔账,看 定价页 的按量对照;直接上手就 下载 装一个,拿一件真事跑一遍。
五、一个 30 秒自查
下次你的系统「某项能力悄悄失效了」,按顺序问三句:
- 最近有没有谁新注册了钩子、拦截了返回值?
- 那个钩子是「放行 + 记录」,还是「无条件重算」?
- 「它算对了」和「它被采用了」,这中间是不是隔着什么被我们忽略的东西?
大多数「以前好、现在坏」又查不出配置问题的怪事,答案都藏在某一个我们亲手加的钩子里。钩子的正确姿态,多数时候是把上游的交回来,而不是把它算一遍再抢着交出去。
土拨鼠 Marmot