10秒ピッタリのランキングを、公平にする:小数3桁・同着・書き込み回数

English version

10秒ピッタリ 開発の記録 / 2026年10月

10秒ピッタリで止めろ!は、頭の中で10秒を数えて止めるだけのゲームです。3回勝負で、誤差が小さいほど強い。これにランキングをつけるとき、「公平とは何か」を、三つの場所で決める必要がありました。リポジトリの README とコードの注記に残っている理由で書きます。

表示は小数3桁まで

誤差は、ブラウザの performance.now() で測ります。README によると、この時計は、セキュリティ対策(Spectre)のために、わざと精度が落としてあります。Chrome は 5 マイクロ秒、Safari と Firefox は 1 ミリ秒刻み、とのことです。

ここで、誤差を 6 桁まで表示するとどうなるか。時計の粗い端末ほど、末尾が 000 になりやすく、有利になってしまいます。iPhone 勢が上位を独占する、というのが README の見立てです。そこで、3 桁に切って、全端末を揃えることにしました。計測の起点も、click ではなく、pointerdown の event.timeStamp を使います。click には、余計な遅れが乗るからです。

同着は、思ったより起きる

3 桁にすると、「ぴったり 0.000」は、1 回あたり 1/1000 の確率で出ます。3 回のうち、どれか 1 回でも 0.000 になる確率は、約 1/333。これで「3回のうちベスト 1 回」の盤を作ると、0.000 の同着が詰まります。

そこで、同着のときは、残り 2 回の誤差の合計が小さいほうを上にします。それも同じなら、先に出したほうです。0.000 を出して、しかも残り 2 回も揃えた人が上に来るので、まぐれの 1 回だけの人と、区別がつきます。

なお、「合計」と「平均」のランキングは、順位が完全に一致します(3 で割るだけだからです)。だから、1 本にまとめてあります。そのうえで、別の軸として、「ベスト 1 回」の盤を置きました。平均が実力、ベスト 1 回が運、という考えです。

書き込み回数を数える

ランキングは、Cloudflare Workers と KV(キーと値の保存場所)でできています。コードの注記では、KV の書き込みは、無料枠で 1 日 1,000 回です。この枠に収めるために、次のことを決めています。

それから、記録はクライアントからの申告なので、不正は防げません。README にも、そう書いてあります。だから、毎日リセットする前提で運用します。日付は日本時間で切り、今日のぶんは 3 日で消えます。

公開の前後に直したこと

公開した日のつまずき

最初に Cloudflare Pages へ出したとき、--branch を付けませんでした。そのとき居た作業ブランチの名前が、Pages の本番ブランチとして登録されてしまいました。その後、--branch main で出しても、プレビューに入るだけで、公開している URL は変わりません。1 時間、気づきませんでした。

ダッシュボードで、本番ブランチを main に直しました。もう一つ、混同していた点があります。デプロイ一覧の「Production」の行に出るブランチ名は、そのデプロイを出したときの名前で、設定を変えても書き換わりません。設定を見るのは、プロジェクト一覧の「Production branch」の列です。

分かったこと

公平さは、桁数と、同着と、書き込み回数で、できている。

どれも、ゲームの面白さには見えない部分です。ただ、3 桁に切る、同着の決め方を先に決めておく、という二つは、遊ぶ人から見える順位の納得感に、直接効きます。

この記事は、リポジトリの README、コードの注記、コミット(2026年9月8日〜12日)の記録から書きました。ブラウザごとの時計の精度は、README の記述によります。

この話に出てくるもの

遊ぶ作品ページへ

ほかの記録

コメント

感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。

押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。