FIELD NOTES

NOTE 04 · EVIDENCE

証拠と、ゲートと、自分のスクリーンショットを信じない理由

このプロジェクトでは「完了」のたびに証拠が要る。その仕組みと、実際に何を止めてきたか。

以下は開発者個人の記録で、内部マイルストーン、技術判断、失敗の経緯を含みます。現在の状態を述べるものであり、最終形でも、リリースの約束でもありません。

一人で作るとき、いちばん簡単に騙せる相手は自分だ

同僚もいない。コードレビューもない。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。すべて通過。 それでも今なおオプトインの選択肢であって、既定ではない。


三、自分のスクリーンショットを信じない

あるとき監査で、過去の正式パッケージに静的キャプチャの被写界深度更新の不具合が見つかった。 つまり、承認の判断に使われたスクリーンショットの被写界深度状態が間違っていた。

パッケージはすでに承認済みだった。見つけたあとにやったのは、そのパッケージを直すことではなく、 自前のハッシュを持つ修正済み六プリセットパッケージを追記することだ。 古い 60 ファイルのスロットはバイト一致のまま、1 バイトも動かしていない。

それ以来、スクリーンショットに対する態度が変わった。 スクリーンショットは人に見せるものであって、証明するものではない。 証明は検証器が出す *_OK マーカー、SHA-256 マニフェスト、再計算できるハッシュが担う。

この公式サイトのすべての画像に「ゲームプレイ映像をもとに再レンダリング」と明記しているのも 同じ理由だ。開発中の実機映像から出発し、再レンダリングを経て、雰囲気と構図を伝えるためのもの—— 生のスクリーンショットでもなければ、最終的な画面でもない。 そこを曖昧にしないことのほうが、画を強く見せることより大事だ。


四、本物は本物の環境で動かす

ローカル開発は固定されたローカルスタックを使う。Nakama はループバックにバインドし、 PostgreSQL は非公開、外に出るのは TLS の入口だけ。LAN 配備でも同じ厳格な接続プロファイル、 同じ HTTPS/WSS トランスポート、同じプロトコル/クライアント/コンテンツ ID を使う。

リモート側では、東京リージョン(ap-northeast-1)でのサービス復元検証が失敗した。 古い安定イメージが、プライベート CA チェーンの SSL 検証に失敗し、復元は成功しなかった。

失敗後の自動ロールバックは PASS。安全な終状態は別のイメージと A-068 証明書、 ECS 1/1/0、HTTPS 200、タスク定義リビジョン 27 だ。

記録にはそのまま書いた。ロールバックの成功は「古い安定版の復元成功」ではない。 この二つは違うもので、同じだと言ってしまうのがいちばん簡単な自己欺瞞になる。


五、三言語は最初から入っている

プレイヤー向けのテキストはすべて同じカタログを通る(zh_CN が権威、jaen が完全)。 名前付きプレースホルダは完全に一致していなければならない。 現在の三言語静的カタログは 590 キーある。

言語は表現レイヤーで、オンライン ID には決して入らない—— プロトコルに locale フィールドはなく、それを見張る専用のテストがある。

三言語を最初に入れたのは、「あとで足す」日は永遠に来ないからだ。


六、この仕組みが実際に止めたもの

  • 向きの yaw の誤り:高価な正式キャプチャの前にプローブが Goblin の両耳の占有ゼロを検出し、無効な候補チェーンを早期に切った。
  • Event ゼロのオンラインラン:ファイナライザがそのまま拒否して消去し、原因を捏造しなかった。
  • 読み取れないリリース ACK:締めでラン全体を拒否。最小限の的を絞った強化だけを入れ、 「この汎用的な失敗自体はその低レベル原因を証明しない」と明記した。
  • 被写界深度更新の不具合:追記の修正パッケージで対応し、履歴は書き換えなかった。
  • 東京の復元失敗:「失敗 + ロールバック成功」として記録し、「復元済み」とは書かなかった。

成功しか記録しない工程なら、これらは全部消えていた。


七、代償

この工程は遅い。検証器を書く時間が機能を書く時間を上回ることも多い。 何かが「終わった」あとにもう一度チェーンを走らせないと、そう口に出せない。

その代わりに、一人で作るときにいちばん希少なものが手に入る。 三か月前の自分が書いた結論を信用できる。

ゲームはまだ開発中だ。この記事は、それがどこまで来たかを私がどうやって知るのか、という話だった。