Lab/lab-p2p

P2P対戦ゲーム公開中2026

ブラウザ同士が直接つながるP2P対戦。エアホッケーと早押しゲームを、6桁のルームコードで即対戦できます。

サイトを開く
lab-p2p(WebRTCサーバーレス対戦)

Screenshots

lab-p2p(WebRTCサーバーレス対戦) スクリーンショット 1

Overview

概要

WebRTCのDataChannelを使い、ブラウザ同士が直接通信して1対1で対戦するサーバーレスゲームです。ゲームのデータはサーバーを経由せずピア間を直接流れ、シグナリング(接続確立の合図)だけをNext.jsのAPI Routeとポーリングで自前実装しています。6桁のルームコードを共有すれば対戦開始。リアルタイム物理のエアホッケーと、1〜25を昇順で早取りする反射神経ゲーム『早押し25』の2種を収録します。

How to use

遊び方・使い方

片方が部屋を作ると6桁のコードが発行され、相手がそれを入力すると接続します(URLクエリでの共有も可能)。エアホッケーはマレットを動かしてパックを打ち合い7点先取、早押し25は5×5に散らばった1〜25を相手より早く昇順でタップして得点を競います。接続はGoogleのSTUNを利用しますが、対称NAT同士など環境によっては繋がらない場合があります。成績はブラウザに保存されます。

Tech stack

技術スタック

TypeScriptNext.js 16React 19WebRTCTailwind CSS v4

追加npm依存はなく、サーバー側もRoute Handlerのみ。接続状態はuseReducerのステートマシン(idle→signaling→connecting→connected→ingame→result)で管理し、IPあたりのレート制限を設けています。エアホッケーはCanvas 2D、早押し25はDOMグリッドで描画します。

Highlights

工夫した点

  • シグナリングはpm2単一プロセスのメモリ上Map(TTL10分)でルームを保持し、offer/answerをポーリングで交換。DataChannelはUDP的な『game』(順序保証なし)と順序保証ありの『control』の2本を用途で使い分け
  • 同期はホスト権威方式を採用。ホストが60Hzで物理を回し30HzでSTATEを全送信、ゲストは自マレットを即時反映しつつパック等を100ms遅延補間で描画(欠落時は速度外挿)。ロックステップは不採用
  • PING/PONGでRTTとクロックオフセットを指数移動平均で推定し、3回連続無応答で切断を検知。受信バッファはリングバッファ化しGCを抑制、メッセージは判別共用体で型安全にエンコード/デコード

To improve

改善したい点

  • TURNサーバーを持たないため、対称NAT同士など一部ネットワークでは接続できない
  • ホスト権威ゆえホスト側が有利になりうる部分の補正に伸びしろがある
  • 再接続・観戦・チャットなど対戦周りの機能が最小限

What's next

今後の展望

  • ゲーム種類の追加(対戦パズル等)
  • 簡易マッチメイキングやランキング
  • 遅延補正(クライアント予測・ロールバック)の高度化

Category

ゲーム

Genre

P2P対戦ゲーム

Year

2026

Status

公開中