FIELD NOTES

NOTE 04 · EVIDENCE

证据、门,以及为什么我不相信自己的截图

这个项目里每一个「完成」都必须带着证据。这是那套流程的样子,以及它挡下过什么。

以下内容是开发者的个人记录,涉及内部里程碑、技术选择与失败过程。它描述的是当前状态,不是最终形态,也不构成任何发布承诺。

一个人做项目最容易骗的人是自己

没有同事、没有 code review、没有 QA。唯一会说「你这个还没做完」的人,就是你自己—— 而你恰好是最不想说这句话的那个人。

所以这个项目里,「完成」不是一种感觉,它是一种必须带着证据出现的状态。


一、证据是只追加的

被接受的 evidence_* 目录是不可变的。新的工作写到一个新的隔离目录里, 捕获和校验的脚本会拒绝覆盖已有的证据目录——不是警告,是直接失败退出。

失败的尝试不会被删掉,它们被披露

这条规则在实践中意味着一些不太舒服的事:

  • 一份预决策的封存清单,即使后来被批准了,它里面 p1_a_approved=falsep1_wp2_authorized=false 这些字段也保持原样。批准是后来追加的另一条记录, 不是回头去改那份封存件。
  • WP7 的验收清单在封存件里永远是 0/16,因为我当时通关试玩后没有逐条写备注。 这个 0/16 看起来很难看,但它是真的:我确实没有逐条填。后来的批准是另一份文档。

我一开始觉得这太严苛了。现在我认为这是整个流程里最有价值的一条。


二、机器指标是必要条件,不是充分条件

每一个新候选都按同一个模式发布:一个 *_v2 文件 + 一个运行时开关 + 自己的校验器 + 自己的证据目录。机器指标只是必要但不充分的检查。

只有被命名的人工门(Gate-Style-X、S10、P1-A/B)才能改变一个默认值。

所以仓库里长期存在这种状态:一套光照方案所有六项指标全部通过、性能达标、 证据齐全——而运行时默认值依然是老的那一套。因为通过指标和通过审美是两件事, 我不想让前者自动变成后者。

举个具体的:光照 V3 在 desktop_high 下六项指标全绿—— 均值 0.359717、标准差 0.209336、暗部 31.2903%、亮部 4.0923%、 深黑 5.1532%、暗部饱和度 0.387926。全部通过。它现在仍然是一个 opt-in 选项, 不是默认。


三、我不相信自己的截图

有一次审计发现,一个历史的正式包里有一个静态捕获的景深刷新缺陷—— 也就是说,那些用来做审批判断的截图,景深状态是错的。

包已经通过审批了。发现之后我做的不是改那个包,而是追加了一份修正过的六预设包, 带自己的哈希;旧的 60 文件槽位保持字节一致,一个字节都没动。

从那以后我对截图的态度变了:截图是给人看的,不是用来证明的。 证明要靠校验器打出来的 *_OK 标记、SHA-256 清单和可复算的哈希。

这也是为什么这个官网上的每一张图都明确标着「再渲染实机截图」。 它们来自开发中的实机画面,经过再渲染,用来传达气氛与构图—— 不是原始截图,也不是最终画面。把这个说清楚,比让图显得更厉害重要。


四、真实的东西跑在真实的环境里

本地开发用的是锁死的本地栈:Nakama 绑在回环地址、PostgreSQL 私有、 只暴露一个 TLS 入口。局域网部署也走同一套严格的连接档案、 同样的 HTTPS/WSS 传输、同样的协议/客户端/内容身份。

远程那边,一次东京区域(ap-northeast-1)的服务恢复验证失败了: 旧的稳定镜像因为私有 CA 链的 SSL 校验失败,恢复没有成功。

失败之后的自动回滚是 PASS。安全终态是另一个镜像 + A-068 证书,ECS 1/1/0、 HTTPS 200、任务定义修订版本 27

我在记录里写得很直白:回滚成功不等于「旧稳定版本恢复成功」。 这两件事是不同的,把它们说成同一件是最容易的自我欺骗。


五、三种语言从一开始就在

所有面向玩家的文本都走同一份目录(zh_CN 权威,jaen 完整), 占位符命名必须完全一致。当前的三语静态目录是 590 个键。

语言是表现层,永远不进入联机身份——协议里没有 locale 字段, 这一条有专门的测试在管。

我把三语放在最开始,而不是「以后再补」,是因为补的那一天永远不会到。


六、这套流程实际挡下过什么

  • 一次朝向 yaw 错误:探针在昂贵的正式捕获之前就发现 Goblin 双耳占据为零, 整条无效候选链被提前砍掉。
  • 一次零 Event 的联机运行:终结器直接拒绝并清除,没有编造原因。
  • 一次不可读的释放 ACK:收尾拒绝了整次运行,我只做了最小化的针对性加固, 并且明确写下「这个泛化失败本身证明不了那个底层原因」。
  • 一次景深刷新缺陷:通过追加修正包处理,没有改写历史。
  • 一次东京恢复失败:如实记录为失败 + 回滚成功,而不是「已恢复」。

如果这些事发生在一个只记录成功的流程里,它们全都会消失。


七、代价

这套流程很慢。写校验器的时间经常超过写功能的时间。每一次「完成」之后还要跑一遍链条, 才能说出口。

但它换来了一件对一个人做项目来说最稀缺的东西:我可以相信自己三个月前写的结论。

游戏还在开发中。这一篇写的是我怎么知道它到了哪一步。