公開: 2026年10月25日 ・ 筆者: Toshi(開発者)
バズ走の地形は毎日0時に変わり、その日のうちは世界中の全員が同じコースを走ります。これは「サーバーがその日の地形を配っている」のではなく、各自の端末が同じ計算式で同じ地形を作っているだけです。この記事では、その計算の中身を順に説明します。
初期版は Math.random() で穴や壁を置いていました。テストを重ねるうちに、同じ腕前でも地形の引き次第でスコアが数倍変わることが分かり、「記録を比べても意味がない」という根本的な問題に行き当たりました。ランゲームの楽しさの半分は「友達より遠くまで行った」という比較にあるので、ここは譲れません。
そこで、乱数の種(シード)を日付から作る方式に切り替えました。種が同じなら、乱数列も同じ。乱数列が同じなら、地形も同じ。これで「今日のコース」が成立します。
種は日本時間の日付を YYYYMMDD 形式の整数にしたものです(例:2026年10月25日なら 20261025)。ランキングAPIの seed パラメータもこの値をそのまま使っていて、「今日のTOP10」は同じ種で走った記録だけを集めています。
ただし、日付の整数をそのまま種にすると、隣り合う日の種はほとんど同じビット列になり、乱数生成器によっては似た地形が続くことがあります。そこで種には定数 0x9E3779B9(黄金比に由来する値で、ハッシュの撹拌によく使われます)をXORしてから渡しています。これだけで連続する日の地形がはっきり変わります。
JavaScriptの Math.random() は種を指定できないため、自前の擬似乱数が必要です。採用したのは mulberry32 という32ビットの生成器で、コードは数行、速度も十分、そして何よりどのブラウザでも同じ結果が出ます。ゲームの公平性にとって「環境によらず同じ列が出る」ことは、乱数の統計的な質よりも重要でした。
function mulberry32(a){
return function(){
a |= 0; a = a + 0x6D2B79F5 | 0;
let t = Math.imul(a ^ a >>> 15, 1 | a);
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296;
};
}
let rand = mulberry32(DAILY_SEED ^ 0x9E3779B9);
ゲームをリスタートするたびに rand を同じ種で作り直しています。こうすることで、1日のうちは何回走っても1回目とまったく同じ地形になり、「穴の位置を覚える」という上達の道筋が生まれます。
地形は画面の右端で少しずつ生成されます。1区画を作るたびに、乱数を決まった回数・決まった順序で引きます。
| 乱数 | 用途 |
|---|---|
| gapRoll | この区画に穴を作るかどうか |
| gapSize | 穴の幅(距離が伸びるほど上限が広がる) |
| lvlRoll | 地面の高さを変えるかどうか |
| wRoll | 壁を置くかどうか・高さ |
| itemRoll / itemYRoll | ★(三段ジャンプ解禁)を出すか・その高さ |
ここで大事なのは「使わない乱数も必ず引く」ことです。たとえば穴を作らない区画でも gapSize を引いておかないと、分岐によって乱数の消費数が変わり、同じ種でも地形がずれてしまいます。条件分岐の前に必要な乱数をすべて引く、というのが決定性を保つコツです。
地形が同じでも、速度の変化が端末によって違えば公平になりません。速度は時間ではなく走った距離で決まるようにしています。
| 項目 | 値 | 意味 |
|---|---|---|
| 初速 | 340 px/秒 | 50px = 1m なので約6.8m/秒 |
| 最高速度 | 1,150 px/秒 | 約23m/秒。ランキングAPIの不正判定にも同じ値を使用 |
| 加速(通常) | 9 | ゆっくり速くなる |
| 加速(300m以降) | 16 | いわゆる「300mの壁」。ここから判断時間が短くなる |
フレームレートが違う端末でも結果が揃うよう、1フレームの経過時間(dt)を掛けて更新し、タブが裏に回ったときはdtに上限を設けて「一気に進む」ことを防いでいます。
ランキングに記録を送るとき、端末は distance(距離)と一緒に seed(その日の種)と elapsed(プレイ時間)を送ります。サーバー側では「最高速度23m/秒 × プレイ時間」を超える距離や、理論上の上限20,000mを超える申告を拒否しています。地形生成とスピードの設計値がサーバーの検証値と一致しているからこそできる、簡単で効果的な不正対策です。
次の記事:画像を1枚も使わずに世界を描く — Canvasだけの落書きグラフィック
⚽ いますぐ走る