どの画面でも同じ船

デイリーランキングは、同じ洞窟の区間を飛ぶ難しさが古い小さな携帯電話でも144Hzのタブレットでもデスクトップブラウザでも等しい場合にのみ公平です。そのために何が必要だったか、そして何を等しくできなかったかについて。

開発日誌 · 2026年9月20日 · すべての投稿

日替わり洞窟についての記事は、すべてのプレイヤーにとって世界を同一にすることについてでした。今回は公平性のもう半分、つまり船を同一に振る舞わせることについてです。デバイスがゲームのプレイ方法を変え得る仕方には二つの独立した要因があり、それぞれに独立した修正が必要です。一つは画面が更新される頻度、もう一つは画面の大きさです。

問題その一: フレームレート

船には位置と速度があります。フレームごとに、重力または推力が速度を変え、速度が位置を変えます。これを書く明白な方法は次のとおりです。

vy += accel * dt;     // update velocity
py += vy * dt;        // then move by the NEW velocity

一見無害に見えますが、実は微妙に間違っています。二行目は、船がそのフレーム全体をすでにフレーム終了時点の速度で移動していたかのように扱っています。船が加速している場合、これは毎フレームaccel × dt²の半分だけ行き過ぎます。厄介なのは、フレームの長さであるdtがデバイスごとに異なるため、その行き過ぎ量も異なり、船はリフレッシュレートごとにわずかに異なる軌道を飛んでいたということです。

0.5秒間推力を保持した状態で測定しました。正確な答えは225ピクセルです。古い積分法では144Hzで228、60Hzで232、30Hzで240という結果になりました。三台のデバイス、同じ入力から三つの異なる距離です。

修正策は台形則で、フレームの前後の速度の平均を使います。

const vyPrev = vy;
vy += accel * dt;
py += (vyPrev + vy) * 0.5 * dt;   // average speed over the frame

一定の加速度に対してはこれは、フレームの長さがどうであれ厳密です。同一の入力スケジュールを再生すると、12Hzから144Hzの範囲で0.000ピクセルのばらつきになりました。以前は4.1ピクセルでした。テストは両方を検証します。新しい積分法がすべてのリフレッシュレートで一致すること、そして古い方が実際に発散していたことです。これにより、誰かが元に戻した場合、ランキングが静かにずれるのではなく、テストが失敗するようになっています。

二つの正直な留保事項

リフレッシュレート間のスコア差は埋まりませんでした。これは予想していました。シミュレートされたパイロットは、その後も144Hzで60Hzより約3分の1高いスコアを出しました。この差は物理演算の問題ではありません。入力の解像度の問題です。親指はフレームの境界でしか押す/離すを切り替えられないため、速い画面は実際により細かい制御を与えます。どんな積分法もこれを直せませんし、毎フレーム入力を切り替えるボットは人間に比べてこれを誇張します。物理演算の半分は今や正確で、残りはハードウェアの特性です。

60Hzではごくわずかな弱体化になっています。0.5秒間の上昇は、232ピクセルではなく225ピクセルをカバーするようになりました。これは補正せずに残しました。もし実機テストで船が鈍いと分かれば、レバーは推力の定数で、約3%増やせば古い0.5秒間の動作が復元されます。ちなみに推力はこれまでにプレイヤーのフィードバックで二度変更されており、その話が、私がこれを触ることに慎重である理由です。

問題その二: 画面の高さ

秒あたりピクセルの二乗で表される重力は、高さ375ポイントの携帯電話と高さ520ポイントのタブレットではまったく異なる意味を持ちます。定数が同じなら、同じ上昇でもタブレットでは画面のはるかに小さな割合しか横切らず、ゲームはより重く感じられるでしょう。

そこで定数は、ゲームの感触が調整・テストされた最大のiPhoneの横向きの高さである440ポイントという基準の高さに対して定義されています。他のどの画面でも、重力、推力、終端速度はすべてH / 440で乗算されます。通路の半分の隙間も高さに応じて拡大縮小するため、あらゆる軌道は基準の軌道と幾何学的に相似になります。秒あたりに通過する通路の割合が同じ、壁から壁までの時間が同じ、体感される反応の速さが同じです。大きい画面はピクセル単位でより急な加速を得て、小さい画面はより緩やかな加速を意図的に得ます。

これは今後のすべてのコードに対する一つのルールを伴います。垂直方向の動きについて判断するものは何であれ比率に基づかなければならないということです。終端速度の割合、高さの割合として。船の速度と比較する生の秒速ピクセル定数を使ってはいけません。その数値は一つのデバイスでしか正しくないからです。リテラルがどうしても必要な場合は、同じ倍率で乗算されます。

ウェブ版も同じルールに従っています。ブラウザビルドはキャンバスをその基準となる電話機と同じ寸法である956×440に固定するため、ブラウザ上のゲームはそのピクセルと物理演算の正確なコピーになります。以前のウェブビルドには独自の感触の倍率がありましたが、それは異なる制限によって生じた鈍さと戦うためだけに存在しており、その制限が一致した時点で削除されました。

問題その三: 画面の幅

高さは垂直軸です。幅は水平軸で、こちらのほうが微妙です。障害物はワールド内で固定された距離ごとに配置されます。洞窟は画面の幅の要素を含む速度でスクロールします。そのため、幅が広い画面では同じ障害物が画面上でより速く通り過ぎ、それぞれに反応するための時間は幅に比例して減少します。

これは実際の漏れでした。幅約1280ポイントの大型Androidタブレットは、小さな携帯電話に比べて約1.75倍速く共有洞窟に直面していました。そのため、幅はすべてのプラットフォームで956ポイントに制限されています。これは横向きの最も幅広いiPhoneの幅です。それより幅の広いデバイスは左右に黒帯が入ります。iPhoneでは何の効果もなく、大型のAndroidデバイスとデスクトップブラウザだけを制限します。

この上限には修正していない残余があります。プレイヤーの当たり判定の半径は幅に応じて拡大縮小しますが、通路は高さに応じて拡大縮小するため、より正方形に近いタブレットでは、携帯電話に比べて船が隙間に対して少し小さくなり、約20%寛容になります。これを修正するには当たり判定を変更する必要があり、それは独自のプレイテストが必要な感触の変更であり、寛容な方向に誤っているため、後回しにできます。

公平性を主張する代わりにテストする

これらはどれもプレイしていて目に見えるものではありません。数ピクセルのずれを感じ取ることはできませんし、誰も六台のデバイスで同時に同じ洞窟をプレイすることはありません。そのため、各主張にはそれを再現するテストがあります。物理テストは12Hzから144Hzのフレームレートで固定入力を積分し、洞窟テストは六種類のデバイスサイズで実際のスポナーを再生してバイト単位で結果を比較します。テストしていない公平性の特性は、私の経験上、すでに静かに壊れているものです。

要するに、TUNLは画面間で三つの独立した方法(フレームレート、高さ、幅)で公平であり、それぞれ原因も修正方法も残余も異なります。手持ちのどのデバイスでも、今日の洞窟で結果を自分の目で確かめることができます。

今日の洞窟を遊ぶ