# すし積むの番付に載らなくなった：ゲームの数字を変えて、サーバーの検算を直し忘れていた（しかも二つ）

> 番付に、普通に遊んでも載らなくなった。ゲームの数字を変えて、サーバーの検算を直し忘れていた。金の桶の褒美（8,000→25,000）と、降るネタ（3種→5種）の二つ。注意書きでは守れず、同じ種で出題を比べる検査を足した。

- URL: https://koshinstudio.com/notes/rank-verify-mismatch/
- 公開: 2026-10-23
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  書いた人：Koshin (https://koshinstudio.com/about/#operator)（Web エンジニア・アプリエンジニア）　公開：2026-10-23
すし積む 開発の記録 ／ 2026年10月

  ブラウザゲーム「すし積む (https://koshinstudio.com/works/)」には、オンラインの番付（ランキング）があります。この番付が、普通に遊んで終わらせても、載らなくなっていました。画面には、「記録の辻褄が合わなかったため、載せられませんでした」と出ます。原因は、ゲームの数字を変えたのに、サーバーの検算の数字を直していなかったことでした。しかも、直したと思ったあとにも、もう一つ残っていました。

  この記事は、2026 年 10 月 23 日の作業と、リポジトリのコミットから書いています。

## 番付の検算は、何をしているのか

  誰でも書き込める番付は、点を書き換えた偽の記録が入りがちです。そこで、遊んだときの手順（いつ、何を落とし、何が合体したか）を、点と一緒にサーバーへ送り、サーバーが点を数え直して、申告と合わなければ載せない作りにしています（server/verify.js）。

  物理演算（ネタがどう転がったか）までは再現しません。無料の枠の CPU 時間（1 回の呼び出しで 10 ミリ秒）に収まらないからです。代わりに、「帳尻」だけを見ます。

- 出題の並び：種（乱数の元）から作り直した並びと、落としたネタが一致するか

- 在庫：同じネタが二つ無いのに、合体していないか

- 得点：書き留めた出来事から足し直して、申告と一致するか

- 間合い：落とす間隔、連鎖の親、注文の中身が、決まりの範囲か

  この方式の弱点は、ゲーム側の数字と、サーバー側の数字が、一つでもずれると、正しい記録まで弾くことです。

## 一つ目：金の桶の褒美が 8,000 のままだった

  9 月 10 日に、「W 金の桶」（金の桶を二つ作って合体させる）に手が届くように、遊びの長さと褒美を調整しました。このとき、金の桶同士の合体で入る点（GOLDEN_BONUS）を、8,000 から 25,000 に上げました（コミット 174bb2b）。検算の側は、8,000 のままでした。

     | ゲーム（index.html） | 検算（verify.js）

      金の桶同士の合体 | +25,000 | +8,000

  金の桶を二つ作って合体させた遊びは、ゲームが 25,000 を足し、サーバーが 8,000 で数えるので、必ず食い違います。W 金の桶まで届いた、一番良い記録だけが載らない状態でした。この件を直して（コミット 2753293）、番付サーバーに反映しました。

## 二つ目：降ってくるネタが、3 種のままだった

  直したあとで、「普通に遊んで、すぐ終わったときも載らなかった」と報告がありました。金の桶に届いていない遊びです。一つ目では説明がつきません。

  調べると、同じ 9 月 10 日のコミット（6ebabc3）で、降ってくるネタを 3 種から 5 種に増やしていました。シャリ・玉子・エビに、サーモンとマグロを足し、重みをつけて引く形です（ROLL_W = [1, 1, 2, 3, 2]）。検算の側は、「3 種から、同じ確率で引く」のままでした。

     | ゲーム | 検算

      ネタの種類 | 5 種（重みつき） | 3 種（同じ確率）

      1 手ごとの引き方 | 乱数 1 つで、重みの合計を超えるまで引き算 | 乱数 1 つに 3 を掛けて切り捨て

  種から作り直した出題の並びが、ほぼ毎回ずれます。ずれた最初の一手で、「出題が合わない」と弾かれます。つまり、9 月 10 日以降のゲームでは、金の桶に届かなくても、普通に遊んだ記録のほぼ全部が弾かれるはずでした。W 金の桶の件は、本命の影に隠れていた二つ目の食い違いでした。

  何人が載せられなかったかは、数えられません。サーバーのコードには、弾いた回数を数える仕組みが、ありませんでした。

## 注意書きがあったのに、起きた

  verify.js の冒頭には、最初から、こう書いてありました。

> ここの定数は index.html と同じ値でなければならない。片方だけ触ると正しい記録が弾かれるので、必ず両方を直すこと。

  注意書きは、あったのです。それでも、9 月 10 日の 14:05 から 14:34 までの約 30 分に、ゲームの調整のコミットを 5 つ重ねていて、その中に検算の修正は入っていませんでした。書いておくだけでは、守れません。そこで、守れない前提で、機械に見張らせることにしました。

  tools/verify-sync.mjs は、次の二つを調べます。

- 点に関わる定数（合体の点・金の桶の褒美・連鎖の上限・落とす間隔など）と、式（連鎖の倍率・注文の褒美）が、ゲームと検算で同じか

- ゲームの rollItem() と、検算の makeRoller() に、同じ種を 6 つ与え、2,000 手ずつ出題させて、並びが一致するか

  直す前のコードで走らせると、金の桶の褒美の食い違いと、出題の並びの食い違い（6 種すべて）を、どちらも検出しました。直したあとは、12,000 手すべてが一致しました。一括検査（tools/check.mjs）の最初にも入れてあります。

  定数を見比べるだけの検査では、二つ目（出題の重み）は、見つかりませんでした。数字ではなく、引き方そのものが変わっていたからです。実際に動かして比べる検査にして、初めて拾えました。

## ゲームを実際に動かして、確かめた

  見比べる検査が通っても、「実際に出てくる記録が通る」ことの証明にはなりません。そこで、釣り合いを測る道具（ゲームを仮想の時計で早送りして、機械に遊ばせるもの）で、実際のゲームが書き出した記録を、検算に通してみました。

    モード | 遊んだ数 | 検算 | 点の範囲

      おまかせ | 4 | 4 件とも通った | 36,368 〜 54,836

      ご注文 | 4 | 4 件とも通った | 81,857 〜 166,105

  8 件とも、点の数え直しまで一致しました。そのうえで、番付サーバーを再び反映し、私が公開中のゲームで普通に遊んで、番付に載ることを確認しました。

  機械に遊ばせた 8 件は、W 金の桶までは届いていません。金の桶同士の合体を通る経路は、定数の見比べだけで確かめています。実際の記録では、確かめていません。

## 分かったこと

- 二つの場所に同じ数字を持つなら、片方を変えた時に、もう片方が壊れる。注意書きでは、足りませんでした。

- 「直った」と思っても、直ったのは一つだけかもしれない。報告された症状（金の桶に届かなくても載らない）が、直した原因で説明できるか、確かめてから「直った」と言うべきでした。

- 弾いた回数を数えていなかった。何人に起きたかが分からないのは、サーバーが「弾いた」ことを黙っていたからです。次は、弾いた理由（出題・得点など）を数えて、増えたら気づける形にしたいと思っています。

- 見比べる検査は、実際に動かして比べる検査にする。数字の一致だけでは、引き方の違いを拾えませんでした。

  似た話は、番付の無料枠を半分にした記録 (https://koshinstudio.com/notes/ranking-free-tier/)や、10 秒ゲームのランキングを公平にした記録 (https://koshinstudio.com/notes/stopwatch-rank/)にも書いています。
