たれコマッシュのアイコン

たれコマッシュ

たれみみ部のブラウザ対戦ゲーム。物理は決定論で、バランスは数字で詰めています。

公開中
  • ゲーム
  • ブラウザ
  • TypeScript
  • Next.js
  • Supabase
ブラウザであそぶ たれみみ部について

できること

つくり

ゲーム本体 TypeScript。物理・当たり判定・勝敗の判定まで自前で書いていて、描画から切り離してあります。
置き場所 Next.js 14(App Router)で作った「たれみみ部」の中のページとして公開しています。
オンライン対戦 Supabase Realtime。対戦用のサーバープログラムもデータベースのテーブルも用意せず、チャンネル上のメッセージ交換だけで成り立たせています。
ランキング Supabase。ミニゲームで共通のスコアテーブルに、ゲームIDを付けて記録します。
テスト Vitest。バランス調整は、対戦を大量に回すシミュレーションをテストとして実行し、勝率の偏りを見ながら詰めています。

技術的におもしろいところ

物理を決定論にしてある

同じシードと同じ入力なら必ず同じ結果になるように物理を組んでいます。 乱数はシードから作った自前の生成器で回し、時間の刻みも固定にしてあるので、 何度実行しても再現します。

おかげでバランス調整を勘に頼らずに済みます。パラメータを変えるたびに大量の対戦を シミュレーションとして回し、勝率の偏りを数字で見ながら詰められる。 「なんとなく強すぎる気がする」を、そのまま数値で確かめられる状態にしてあります。

オンライン対戦をサーバーなしで成り立たせている

対戦サーバーは立てていません。部屋は Supabase Realtime のチャンネルそのもので、 4桁の番号がそのままチャンネル名になります。対戦の状態を保存するテーブルも作っていないので、 部屋は全員が抜けた時点で消えます。会員登録が要らないのもこのつくりのおかげで、 プレイヤーIDは部屋ごとの使い捨てです。

決定論のおかげで「今の状態」を送らなくていい

コマの位置も速度も回転も、通信では一切送っていません。送るのは共有のシード、 発射の設定、ボタンを押した合図といった数値だけ。物理が決定論なので、 同じ数値さえ配れば各端末が同じ試合をそれぞれ再生してくれます。 流れるデータが小さく、回線が細くても崩れにくい構成です。

そのかわり入力は全端末で同じタイミングに効かせる必要があります。 ボタンは押した瞬間ではなく、18tick(60Hz なので0.3秒)先の「適用tick」を決めて予約し、 全員がそのtickで同時に発動させます。この0.3秒が、合図が相手に届くまでの猶予です。 片道300msくらいまでならこれで吸収できます。

それでもずれる前提で、ずれたら直す

決定論といっても端末をまたぐと完全ではありません。三角関数のような計算の丸めが ブラウザや CPU でわずかに違い、まれに状態が枝分かれします。一度ずれると 仕切り直しや決着の瞬間がお互いにずれて、見た目が崩れます。

そこでホストを正とし、ホストが軽いチェックサムを定期的に流しています。 ゲストは自分の同じtickの値と突き合わせ、食い違ったらホストの状態を丸ごと送ってもらって 上書きします。毎フレーム同期する重いやり方ではなく、 ふだんは各自で再生し、ずれた時だけ直す、という薄いかけ方にしてあります。

入室の失敗をひとつずつ潰した

最初は「今この部屋にいる人」の一覧(presence)で部屋を見つけていたのですが、 モバイルブラウザがタブを休ませると、つながっているのにお互いが見えない、という事故が起きました。 いまは入室をメッセージのやりとりで成立させています。ゲストが呼びかけを繰り返し送り、 ホストが参加者の並びを返した時点で入室成立。presence は切断の検知だけに使っています。

部屋を作るときも、自分が送ったメッセージが自分に返ってくるかを先に確かめています。 返ってこない=Realtime が働いていないので、その場でエラーにします。 以前はここを見ていなかったため、誰も入れない部屋の中で待ち続けてしまうことがありました。

通信の仕様にはバージョン番号を振り、チャンネル名に含めています。 古いページを開いたままの端末と新しい端末が同じ部屋で混ざって誤動作することがなくなり、 食い違いは「部屋が見つからない」として現れるので、再読み込みで直ります。

同じ物理エンジンをレースでも使い回している

対戦の物理は、レースの「たれコマGP」と同じエンジンを共有しています。 ルールや勝敗の条件はゲームごとに外側で持たせて、動きの計算だけを共通化しているので、 片方で見つけた挙動の不具合を直すともう片方にも効きます。

ランキングは1つのテーブルに全ゲームが相乗り

ミニゲームごとにテーブルを作らず、ゲームIDで区別する汎用のスコアテーブルにまとめています。 たれコマッシュのスコアもこの仕組みに乗っているので、デイリー・週間・通算の集計は ほかのミニゲームと同じコードで済んでいます。

プライバシー・お問い合わせ

たれコマッシュはたれみみ部のサービスの一部として提供しています。 取り扱いはたれみみ部 プライバシーポリシーと利用規約に従います。

不具合のご報告、ご意見・ご要望、ランキングに登録した記録の削除依頼などは、 たれみみ部の「コンタクト」ページ、または Sizu dev のお問い合わせページからご連絡ください。