すし積むの番付に載らなくなった:ゲームの数字を変えて、サーバーの検算を直し忘れていた(しかも二つ)
すし積む 開発の記録 / 2026年10月
ブラウザゲーム「すし積む」には、オンラインの番付(ランキング)があります。この番付が、普通に遊んで終わらせても、載らなくなっていました。画面には、「記録の辻褄が合わなかったため、載せられませんでした」と出ます。原因は、ゲームの数字を変えたのに、サーバーの検算の数字を直していなかったことでした。しかも、直したと思ったあとにも、もう一つ残っていました。
この記事は、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 金の桶までは届いていません。金の桶同士の合体を通る経路は、定数の見比べだけで確かめています。実際の記録では、確かめていません。
分かったこと
- 二つの場所に同じ数字を持つなら、片方を変えた時に、もう片方が壊れる。注意書きでは、足りませんでした。
- 「直った」と思っても、直ったのは一つだけかもしれない。報告された症状(金の桶に届かなくても載らない)が、直した原因で説明できるか、確かめてから「直った」と言うべきでした。
- 弾いた回数を数えていなかった。何人に起きたかが分からないのは、サーバーが「弾いた」ことを黙っていたからです。次は、弾いた理由(出題・得点など)を数えて、増えたら気づける形にしたいと思っています。
- 見比べる検査は、実際に動かして比べる検査にする。数字の一致だけでは、引き方の違いを拾えませんでした。
似た話は、番付の無料枠を半分にした記録や、10 秒ゲームのランキングを公平にした記録にも書いています。
ほかの記録
- 押すものを六つから一つに絞った:初めての人は、どれを押せばいいか分からなかった — タイトル画面に押せるものが六つ並んでいた。初めての人に必要なのは最初の一歩だと考えて一つに絞った。iframeで保存が消える問題と、画面を離れたら止まる直しも含めた記録。
- 音は聴けないので、波形を測った:すし積むの和楽器を、WebAudioで作る — 音声ファイルを使わず、箏・太鼓・拍子木・鉦をブラウザで合成した。聴けないので、波形のピークを測って音量を決めた。番付のしきい値も、自動プレイの実測で引き直した記録。
- CrazyGames のプレビューで日本語が文字化け:ファイルは正しかった。原因は特定できず、ASCII 表記に逃がした — ゲームポータルのプレビューで「大連鎖!」の「連」だけが壊れた。ファイルのバイト列は正しく、原因は特定できなかった。ASCII 表記に逃がした経緯と、14言語の枠の検査の記録。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。