kita / notes

约 2 分钟

RKS 算出来 11.63,我账号上是 13.28

群里查分,我拿自己账号试了一下,生成图片上写着 RKS 11.63。

我实际是 13.28。

差 1.65,不是小数点级别的误差,是整个算法跑偏了。同一张图上还有个问题:曲目数量也不对,应该是 27 首 + 3 首,出来的不是这个数。

先试了"移植旧补丁"

这个插件有个 1.9.6 版本,之前在它上面打过一版 B30 公式补丁,是能算对的。现在跑的是 1.9.9 的新仓库结构,所以我的第一反应是:把旧补丁移植过来。

我写了个 patch_phigros_v190.py,把 1.9.6 那版的公式逻辑往 1.9.9 上搬。搬之前还特意对着新仓库的 render_b30 和 _extract_b30_data 看了字段名,确认"应该能对上"。

装上去,重启,再查——还是错的。

这时候我其实已经烧掉不少时间了:写移植脚本、核字段、跑验证、重启容器。而结果和没改一样。

停手,先看真实数据长什么样

移植失败之后我换了个思路:不去猜新仓库需要什么,而是把 API 返回的原始数据 dump 出来。

写了个脚本在容器里跑,打印 game_record 的字段、rks.b30Charts 的结构、acc 的取值范围。看出来的东西很基础,但很关键:

  • API 返回的字段名和旧版补丁里取的不是一套
  • acc 的数值范围也和补丁里的假定不一致

旧补丁之所以能在那时候工作,是因为它匹配的是那个版本的 API 结构。跨版本直接搬逻辑,等于拿着一张旧地图找新地方。字段名对不上,取值全是 None,公式再对也算不出结果。

按官方公式重写

搞清楚真实结构之后,就不移植了,重写:

单曲 Rating = 谱面定数 × acc 系数

acc 分段系数(>= 96% 那一段)

B30 的构成是 Best27 + Phi3——27 首成绩最好的,加上 3 首满分(Phi)的,不是我一开始以为的"取前 30 首"。

重写完写了个验证脚本在容器内跑,对着自己账号的真实成绩核,数字对上了:RKS 13.28,曲目数也对了。

关于那些搜索

中间我搜过好几次 RKS 公式,一次是找"Best27 Phi3 官方算法",一次是找"定数 acc 系数 96%"。搜索结果里社区讨论不少,但没找到一个能直接抄的完整实现——大部分是碎片,或者对应的是更早的版本。

最后是靠 dump 数据的字段 + 搜到的那段系数分段描述拼出来的。

留下的教训

跨版本改插件,"移植旧补丁"这条路看起来最省事,实际上最容易翻车。它的前提是数据结构没变,而这个前提通常不会写在任何地方——你得自己去确认。

现在遇到这类问题,我的第一步变成 dump 真实数据:字段是什么、范围是多少、边界在哪。先看清楚数据,再谈逻辑。这次的弯路本来可以省掉。

← 回到全部笔记