mcpField
M
multiplayer-game

multiplayer-game

github.com/rivet-dev開発447.2k 回インストール1 日前に更新
リポジトリ

multiplayer-game について

RivetKit でマルチプレイヤーゲームを開発する人向けの実装ガイドです。ゲーム種別ごとに、シミュレーション、同期、マッチメイキング、永続化、チート対策の設計パターンを整理しています。

主な機能

  1. 01ゲームループとティックレートのパターン
  2. 02物理演算と空間インデックスの指針
  3. 03状態同期とレプリケーション
  4. 04Actor 構成とマッチメイキングのパターン
  5. 05永続化とチート対策の実践

活用シーン

  1. 01ゲームのマッチメイキングとライフサイクル設計
  2. 02サーバーシミュレーションと状態同期方式の選定
  3. 03大規模ワールドをチャンク Actor に分割
  4. 04クライアントの移動やゲーム操作の検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rivet-dev/skills --skill multiplayer-game

インストール後、Claude Code で/multiplayer-gameを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

BASE_SKILL.md
index.json
openapi.json
reference/actors/
access-control.md
actions.md
actor-runtime-socket.md
appearance.md
authentication.md
communicating-between-actors.md
connections.md
debugging.md
design-patterns.md
destroy.md
errors.md
events.md
fetch-and-websocket-handler.md
helper-types.md
http-api.md
input.md
inspector-tabs.md
keys.md
kv.md
lifecycle.md
limits.md
metadata.md
queues.md
reference/actors/quickstart/
backend.md
cloudflare.md
effect.md
next-js.md

詳細

マルチプレイヤーゲーム

重要:作業を始める前に、このスキルのディレクトリにある BASE_SKILL.md を必ず読んでください。デバッグ、エラー処理、状態管理、デプロイ、プロジェクトのセットアップに関する重要なガイダンスが記載されています。これらのルールとパターンは、すべての RivetKit の作業に適用されます。以下の内容は、すでに読み、理解していることを前提としています。

動作するサンプル

参考実装が必要な場合は、次のテンプレートにある動作するサンプルのコードを直接読んでください。

RivetKit でマルチプレイヤーゲームを構築するためのパターンです。ジャンルごとに応用できる実践的なチェックリストとして用意されています。

スターターコード

GitHub にある動作するサンプルのいずれかから始めて、ゲームに合わせて調整してください。マッチメイキングとライフサイクルのフローを一から作成しないでください。

ゲームの分類スターターコードよくある例
バトルロイヤルGitHubFortnite、Apex Legends、PUBG、Warzone
アリーナGitHubCall of Duty の TDM/FFA、Halo Slayer、Counter-Strike のカジュアル、VALORANT のアンレート、Overwatch のクイックプレイ、Rocket League
IO スタイルGitHubAgar.io、Slither.io、surviv.io
オープンワールドGitHubMinecraft のサバイバルサーバー、Rust のようなワールド、MMO のゾーン/チャンクワールド
パーティーGitHubFall Guys のプライベートロビー、カスタムゲームルーム、ソーシャルパーティーセッション
2D 物理演算GitHub見下ろし型の物理演算バトル、2D アリーナゲーム、プラットフォーム格闘ゲーム
3D 物理演算GitHub物理演算サンドボックスセッション、3D アリーナゲーム、移動の実験場
ランク戦GitHubチェスのランキング戦、対戦型カードゲーム、デュエルアリーナのランク戦キュー
ターン制GitHub通信チェス、Words With Friends、非同期ボードゲーム
放置系GitHubCookie Clicker、Idle Miner Tycoon、Adventure Capitalist

サーバーシミュレーション

ゲームループとティックレート
パターン使用する場合実装ガイダンス
固定リアルタイムループバトルロイヤル、アリーナ、IO スタイル、オープンワールド、ランク戦run 内で sleep(tickMs) を実行し、c.aborted の場合は終了します。
アクション駆動型の更新パーティー、ターン制スケジュールされたティックではなく、アクション/イベントに応じてのみ状態を変更し、ブロードキャストします。
粗いオフライン進行放置型の進行を含むすべてのモードc.schedule.after(...) を粗い間隔(例:5〜15 分)で使用し、経過した実時間に基づいて進行分を適用します。
物理演算

シンプルなゲームでは、まず独自のキネマティクスロジックから始めます。ジョイント、積み重なった剛体、高密度の衝突、複雑な形状(回転ポリゴン、カプセル、凸包、三角形メッシュ)が必要になったら、フル機能の物理エンジンに切り替えます。

シミュレーションごとにエンジンを1つ選びます。フロントエンド専用のライブラリをバックエンドのシミュレーション経路に含めず、サーバーの状態を信頼できる情報源として扱います。

次元主なエンジン代替エンジンコード例
2D@dimforge/rapier2dplanck-js、matter-jsGitHub
3D@dimforge/rapier3dcannon-es、ammo.jsGitHub
空間インデックス

物理演算を伴わない空間クエリには、単純な O(n^2) のチェックではなく、専用のインデックスを使います。

インデックスの種類推奨事項
AABB インデックスAOI、可視性、コライダーを持たないエンティティには、動的な集合には rbush、静的に近い集合には flatbush を使います。
ポイントインデックス最近傍または半径内のクエリには、d3-quadtree を使います。

ネットワーキングと状態同期

ネットコード
モデル使用する場面実装
ハイブリッド(クライアントの移動、サーバーの戦闘)シューティングゲーム、アクションスポーツ、ランク戦のデュエルクライアントが移動を管理し、レートを制限した位置更新を送信します。サーバーはチート対策のために検証します。戦闘(飛翔体、命中、ダメージ)は完全にサーバーが権限を持ちます。
補間を使ったサーバー権威型IO スタイル、永続ワールドクライアントは入力コマンドを送信します。サーバーは固定ティックでシミュレーションを実行し、権威あるスナップショットを配信します。クライアントはスナップショット間を補間します。
サーバー権威型(基本ロジック)ターン制、イベント駆動型サーバーが離散的なアクション(ターン、フェーズ遷移、投票)を検証して適用します。クライアントは確定済みの状態を表示します。
リアルタイムデータモデル
  • スナップショットと差分:状態をイベントとして配信します。参加時や再同期時には完全なスナップショットを送信し、その後は通常の更新としてティックごとの差分を送信します。
  • ティックごとにまとめる:イベントは小さく、型を明確にします。高頻度の更新はティックごとにまとめます。
  • ゲームの更新に UI フレームワークの状態を使わない:シミュレーションには React の状態ではなく、requestAnimationFrame または Canvas/Three.js のループを使います。UI フレームワークの状態はメニュー、HUD、フォーム用にします。
  • ブロードキャストと接続ごとの送信:共有更新には c.broadcast(...) を、プライベートデータやプレイヤーごとのデータには conn.send(...) を使います。
シミュレーションロジックの共有

共有シミュレーションロジックは、クライアントとサーバーの両方で実行されます。たとえば、速度を積分してワールド境界内に収める applyInput(state, input, dt) 関数は、クライアントでは予測に、サーバーでは検証に使えます。

  • ハイブリッドモード:クライアントは共有の移動ロジックを主な権限として実行し、サーバーはチート対策の検証に実行します。
  • サーバー権威型モード:クライアントは共有ロジックを補間と予測にのみ使用します。
  • 純粋性を保つ:移動の積分、入力変換、衝突ヘルパー、定数のみを含めます。
  • 共有コードは src/shared/ に配置する:副作用のない決定的なヘルパーは src/shared/sim/* に配置します。
インタレスト管理

各クライアントが受信する内容を制御して、帯域幅を削減し、情報漏えいを防ぎます。

プレイヤーごとのレプリケーションフィルター
  • 関連性でフィルタリングする:近接度、視線、チーム、ゲームフェーズに基づいて、各クライアントにはそのプレイヤーに関連する状態のみを送信します。
  • シューティングゲームとアクションゲーム:近接度と、必要に応じて視野角チェックによってレプリケーションを制限します。
  • サーバー側のみで処理する:クライアントには、見るべきでないデータを決して送信しないでください。
シャーディングされたワールド
  • 大規模なワールドを分割する:worldId:chunkX:chunkY をキーとするチャンクアクターを使います。
  • 近くのチャンクを購読する:クライアントは近隣のパーティション(たとえば 3x3 のチャンク範囲)のみに接続します。
  • 必要な場合のみ使う:小規模なマッチの標準構成としてではなく、ワールドが大規模で状態が多い場合(サンドボックス型建築ゲーム、MMO)にのみ使います。

バックエンドインフラストラクチャ

永続化
  • インメモリ状態:毎ティック変化するリアルタイムのゲーム状態(プレイヤーの位置、入力、試合フェーズ、スコアなど)に最適です。
  • SQLite(rivetkit/db):クエリやインデックス、長期的な永続化が必要な、大規模またはテーブル形式の状態(タイル、インベントリ、マッチメイキングのプールなど)に適しています。複数のアクションが同じアクターに同時にアクセスする可能性があるため、DB の処理はキューを通じて直列化してください。
マッチメイキングのパターン

以下のアーキテクチャパターン全体で使用する、一般的な構成要素です。

アクターのトポロジー
プリミティブ使用する場面一般的な所有範囲
matchmaker["main"] + match[matchId]セッションベースのマルチプレイヤー(バトルロイヤル、アリーナ、ランク戦、パーティー、ターン制)マッチメイカーが検索と割り当てを担当します。マッチがライフサイクルとゲームプレイの状態を管理します。
chunk[worldId,chunkX,chunkY]シャーディングが必要な広大な連続ワールド各チャンクがローカルプレイヤー、チャンクの状態、ローカルシミュレーションを管理します。
world[playerId]プレイヤーごとの進行ループ(放置型/ソロのワールド状態)プレイヤーごとのリソース、建物、タイマー、進行状況を管理します。
player[username]マッチをまたいで再利用する標準プロフィール/レーティング永続的なプレイヤー統計(レーティングや勝敗など)を管理します。
leaderboard["main"]多数のマッチ/プレイヤー間で共有するランキング全体のスコア順一覧と上位リストを管理します。
キューイング戦略
  • 複数のプレイヤーが同時にマッチメイカーへアクセスする可能性があるため、競合を防ぐには、検索/作成、キューへの追加/キューからの削除、終了などのアクションをアクターのキューを通じて直列化する必要があります。
  • マッチ内のアクション(ゲームプレイ、スコア計算)は、マッチメイカーへ書き戻さない限り、キューイングは不要です。

セキュリティとチート対策

まずこの基本項目を実施し、競技性の高い環境や高リスクな環境では、さらにセキュリティを強化してください。

基本チェックリスト
  • ID:信頼できる通信上の ID として c.conn.id を使用します。パラメーター内の playerId/username は信頼できない入力として扱い、サーバーが発行した割り当て/参加チケットを通じて紐付けます。
  • 認可:呼び出し元が対象エンティティを変更する権限を持つこと(ルームへの参加、ターンの所有権、ホストのみが実行できるアクションなど)を検証します。
  • 入力検証:サイズや長さを制限し、列挙値を検証し、ユーザー名(長さ、使用可能な文字、無制限の Unicode の回避)を検証します。
  • レート制限:スパムにつながりやすいアクション(チャット、参加/退出、発砲、移動の更新)に対して、接続ごとにレート制限を設けます。
  • 状態の整合性:派生状態(スコア、勝利条件、順位)はサーバー側で再計算します。インベントリ、通貨、リーダーボードの合計値をクライアント側で変更できるようにしてはいけません。
移動の検証

クライアント側で移動を決定するモード(ハイブリッド方式)では、滑らかな動作のために、クライアントから位置/回転の更新を送信できます。ただし、サーバーは次の項目を必ず実施する必要があります。

  • 経過時間に基づいて、更新ごとの最大変化量(速度上限)を適用します。
  • テレポートを拒否するか、補正します。
  • ワールドの境界を適用します(該当する場合は基本的な衝突判定も行います)。
  • 更新頻度を制限します(例:最大 20Hz)。

アーキテクチャパターン

以下の各ゲームタイプでは、最初に概要表を示し、その後にアクターとライフサイクルを詳しく説明します。

バトルロイヤル
トピック概要
マッチメイキング開始前のロビーのうち、最も人数が多いロビーへすぐに振り分けます(同数の場合は、最も古いロビーを優先します)。定員に達するまでプレイヤーはロビーで待機し、その後マッチが開始されます。
ネットコードハイブリッド方式です。移動、カメラ、ローカルでの予測はクライアントが担います。ゾーンの状態、飛翔体、ヒット判定、脱落、戦利品、最終順位はサーバーが担います。
ティックレート1 秒あたり 10 ティック(100ms)で、ゾーンの進行とライフサイクルの確認に固定ループを使用します。
物理演算クライアントが移動を担い、サーバーがアンチチート検証を行います。飛翔体、ヒット判定、ダメージはサーバー権限で処理されます。3D には @dimforge/rapier3d、トップダウン 2D には @dimforge/rapier2d を使用します。

アクター

  • キー: matchmaker["main"]

  • 責任: ロビーの検索または作成、保留中の予約の追跡、収容人数の管理を行います。

  • アクション

    • findMatch
    • pendingPlayerConnected
    • updateMatch
    • closeMatch
  • キュー

    • findMatch
    • pendingPlayerConnected
    • updateMatch
    • closeMatch
  • 状態

    • SQLite
    • matches
    • pending_players
    • player_count には、接続中と保留中のプレイヤーが含まれます
  • キー: match[matchId]

  • 責任: ロビー/進行中/終了の各フェーズ、プレイヤーの状態、ゾーンの進行、脱落を管理します。

  • アクション

    • connect
    • 移動および戦闘アクション
  • キュー

    • なし
  • 状態

    • JSON
    • phase
    • players
    • zone
    • eliminations
    • snapshot data

ライフサイクル

sequenceDiagram
	participant C as Client
	participant MM as matchmaker
	participant M as match

	C->>MM: findMatch()
	alt no open lobby
		MM->>M: create(matchId)
	end
	MM-->>C: {matchId, playerId}
	C->>M: connect(playerId)
	M->>MM: pendingPlayerConnected(matchId, playerId)
	MM-->>M: accepted
	Note over M: lobby countdown -> live
	M-->>C: snapshot + shoot events
	M->>MM: closeMatch(matchId)
アリーナ
トピック概要
マッチメイキングモード別の固定人数キュー(duo、squad、ffa)を使用し、定員に達した場合にのみマッチを作成して、(FFA を除き)チームを事前に割り当てます。
ネットコードハイブリッド方式です。移動、予測、スムージングはクライアントが担います。チームまたは FFA の割り当て、飛翔体、ヒット判定、フェーズ遷移、スコアリングはサーバーが担います。
ティックレート1 秒あたり 20 ティック(50ms)で、進行中のチーム戦および FFA のスナップショットには、より頻度の高いループを使用します。
物理演算中程度から高強度です。移動はクライアントが担い、サーバーが検証を行います。戦闘およびエンティティはサーバー権限で処理されます。

アクター

  • キー: matchmaker["main"]

  • 責任: モード別のキューを管理し、定員に達したマッチを作成して、チームを割り当て、割り当てを公開します。

  • アクション

    • queueForMatch
    • unqueueForMatch
    • matchCompleted
  • キュー

    • queueForMatch
    • unqueueForMatch
    • matchCompleted
  • 状態

    • SQLite
    • player_pool
    • matches
    • 接続およびプレイヤーごとにキー付けされた assignments
  • キー: match[matchId]

  • 責任: マッチの各フェーズと、スコアや勝利条件に関わるマッチ中のプレイヤー/チームの状態を管理します。

  • アクション

    • connect
    • ゲームプレイアクション
  • キュー

    • なし
  • 状態

    • JSON
    • phase
    • players
    • team assignments
    • score and win state

ライフサイクル

sequenceDiagram
	participant C as Client
	participant MM as matchmaker
	participant M as match

	C->>MM: queueForMatch(mode)
	Note over MM: enqueue in player_pool
	Note over MM: fill when capacity reached
	MM->>M: create(matchId, assignments)
	Note over MM: persist assignments
	MM-->>C: assignmentReady
	C->>M: connect(playerId)
	Note over M: waiting -> live when all players connect
	M->>MM: matchCompleted(matchId)
IO スタイル
トピック概要
マッチメイキングオープンロビーから、定員に達していない中で最も人数の多いルームにルーティングします。ルームの人数はハートビートで更新され、必要に応じて新しいロビーが自動作成されます。
ネットコード補間を用いたサーバーオーソリテーティブ方式です。クライアントは入力インテントを送信し、補間を行います。移動、境界、ルームへの所属、正規スナップショットはサーバーが管理します。
ティックレート10 ティック/秒(100ms)で、軽量なルームスナップショットを定期的に送信します。
物理演算低~中程度の強度です。サーバーオーソリテーティブなキネマティック移動を採用し、衝突が複雑になった場合に限り、物理エンジンを段階的に導入します。

アクター

  • キー:matchmaker["main"]

  • 責務:プレイヤーを最も人数の多いオープンロビーにルーティングし、予約と収容人数を追跡します。

  • アクション

    • findLobby
    • pendingPlayerConnected
    • updateMatch
    • closeMatch
  • キュー

    • findLobby
    • pendingPlayerConnected
    • updateMatch
    • closeMatch
  • 状態

    • SQLite
    • matches
    • pending_players
    • 収容人数には保留中の予約が含まれます
  • キー:match[matchId]

  • 責務:マッチごとの移動シミュレーションを実行し、スナップショットをブロードキャストします。

  • アクション

    • connect
    • setInput
  • キュー

    • なし
  • 状態

    • JSON
    • players
    • inputs
    • movement state
    • snapshot cache

ライフサイクル

sequenceDiagram
	participant C as Client
	participant MM as matchmaker
	participant M as match

	C->>MM: findLobby()
	alt no open lobby
		MM->>M: create(matchId)
	end
	MM-->>C: {matchId, playerId}
	C->>M: connect(playerId)
	M->>MM: pendingPlayerConnected(matchId, playerId)
	MM-->>M: accepted
	Note over M: fixed tick simulation
	M-->>C: snapshot events
	M->>MM: closeMatch(matchId)
オープンワールド
トピック概要
マッチメイキングワールド座標を基にクライアント主導でチャンクにルーティングし、隣接チャンクとの接続を通じて近隣のチャンクウィンドウを事前ロードします。
ネットコードサンドボックスではハイブリッド方式(クライアント移動と検証)、MMO のようなフローではサーバーオーソリテーティブ方式です。チャンクへのルーティング、永続化、正規ワールド状態はサーバーが管理します。
ティックレートチャンクアクターごとに 10 ティック/秒(100ms)で、負荷はアクティブなチャンク数に応じて増加します。
物理演算大規模運用では中~高程度です。チャンク内のシミュレーションは、サーバーオーソリテーティブ方式(MMO のような形式)にも、サーバー検証付きのクライアント移動(サンドボックスのような形式)にもできます。

アクター

  • キー:chunk[worldId,chunkX,chunkY]
  • 責務:チャンク内のプレイヤー、ブロック、移動ティック、チャンクへの所属を管理します。
  • アクション
    • connect
    • enterChunk
    • addPlayer
    • setInput
    • leaveChunk
    • removePlayer
  • キュー
    • なし
  • 状態
    • JSON
    • connections
    • players
    • 1 つのチャンクキーにスコープされた blocks

ライフサイクル

sequenceDiagram
	participant C as Client
	participant CH as chunk

	Note over C: resolve chunk keys from world position
	loop each visible chunk
		C->>CH: connect(worldId, chunkX, chunkY, playerId)
		Note over CH: store connection metadata
	end
	C->>CH: enterChunk/addPlayer
	loop movement updates
		C->>CH: setInput(...)
		CH-->>C: snapshot
	end
	C->>CH: leaveChunk/removePlayer or disconnect
	Note over CH: remove membership and metadata
パーティー
トピック概要
マッチメイキングパーティーコードと明示的な参加操作を使う、ホスト作成のプライベートパーティーフローです。
ネットコードサーバーオーソリテーティブ方式(基本ロジック)です。メンバーシップ、ホスト権限、フェーズ遷移はサーバーが管理します。
ティックレート継続的なティックはなく、更新はイベント駆動型です(join、start、finish)。
物理演算ロビーを中心とするフローでは低強度です。リアルタイムのミニゲームを追加しない限り、通常は専用の物理演算やインデックス作成は不要です。

アクター

  • キー:matchmaker["main"]

  • 責務:パーティーの作成・参加フローを処理し、参加チケットを検証し、パーティーの人数を追跡します。

  • アクション

    • createParty
    • joinParty
    • verifyJoin
    • updatePartySize
    • closeParty
  • キュー

    • createParty
    • joinParty
    • verifyJoin
    • updatePartySize
    • closeParty
  • 状態

    • SQLite
    • parties
    • パーティーの検索と参加検証に使う join_tickets
  • キー:match[matchId]

  • 責務:パーティーメンバー、ホストの役割、準備完了フラグ、フェーズ遷移を管理します。

  • アクション

    • connect
    • startGame
    • finishGame
  • キュー

    • なし
  • 状態

    • JSON
    • members
    • host
    • ready state
    • phase
    • party events

ライフサイクル

ホストのフロー
sequenceDiagram
	participant H as Host Client
	participant MM as matchmaker
	participant M as match

	H->>MM: createParty()
	MM-->>H: {matchId, partyCode, playerId, joinToken}
	H->>M: connect(playerId, joinToken)
	M->>MM: verifyJoin(...)
	MM-->>M: allowed
	M->>MM: updatePartySize(playerCount)
	H->>M: startGame() / finishGame()
	M->>MM: closeParty(matchId)
参加者のフロー
sequenceDiagram
	participant J as Joiner Client
	participant MM as matchmaker
	participant M as match

	J->>MM: joinParty(partyCode)
	MM-->>J: {matchId, playerId, joinToken}
	J->>M: connect(playerId, joinToken)
	M->>MM: verifyJoin(...)
	MM-->>M: allowed / denied
	M->>MM: updatePartySize(playerCount)
ランク戦
トピック概要
マッチメイキングELO ベースのキューでマッチングします。待ち時間が長くなるにつれて検索範囲が広がります。
ネットコードハイブリッドです。クライアントがローカル予測と補間を使って移動を制御します。サーバーが投射物、命中判定、試合結果、レーティングの更新を制御します。
ティックレート1 秒あたり 20 ティック(50ms)です。固定されたライブティックによって、決定論的なペースとブロードキャスト間隔を維持します。
物理演算中程度から高強度です。クライアントが移動し、サーバーが検証と、サーバー主導の戦闘/命中判定を行います。

アクター

  • キー:matchmaker["main"]

  • 責務:レーティングベースのキュー管理、マッチング、割り当ての永続化、完了通知の配信を行います。

  • アクション

    • queueForMatch
    • unqueueForMatch
    • matchCompleted
  • キュー

    • queueForMatch
    • unqueueForMatch
    • matchCompleted
  • 状態

    • SQLite
    • player_pool
    • matches
    • レーティング範囲と接続スコープを含む assignments
  • キー:match[matchId]

  • 責務:ランク戦のフェーズ、スコア、勝者の報告を管理します。

  • アクション

    • connect
    • ゲームプレイアクション
  • キュー

    • なし
  • 状態

    • JSON
    • phase
    • players
    • score
    • winner
    • completion payload
  • キー:player[username]

  • 責務:正規のプレイヤー MMR と勝敗プロフィールを保存します。

  • アクション

    • initialize
    • getRating
    • applyMatchResult
  • キュー

    • なし
  • 状態

    • JSON
    • rating
    • wins
    • losses
    • match counters
  • キー:leaderboard["main"]

  • 責務:上位プレイヤーを保存し、提供します。

  • アクション

    • updatePlayer
  • キュー

    • なし
  • 状態

    • SQLite
    • リーダーボードのスコア行
    • 上位リストの順序

ライフサイクル

sequenceDiagram
	participant C as Client
	participant MM as matchmaker
	participant P as player
	participant M as match
	participant LB as leaderboard

	C->>MM: queueForMatch(username)
	MM->>P: initialize/getRating
	P-->>MM: rating
	Note over MM: store queue row + retry pairing
	MM->>M: create(matchId, assigned players)
	MM-->>C: assignmentReady
	C->>M: connect(username)
	M->>MM: matchCompleted(...)
	MM->>P: applyMatchResult(...)
	MM->>LB: updatePlayer(...)
	Note over MM: remove matches + assignments rows
ターン制
トピック概要
マッチメイキング非同期のプライベート招待とパブリックキューで、同じパターンのマッチングを行います。
ネットコードサーバー主導(基本ロジック)です。クライアントは送信前に手を作成できます。サーバーが手番の所有権、確定済みの手のログ、手番順、完了状態を管理します。
ティックレート継続的なティックはありません。手の送信と手番の移行によって更新が行われます。
物理演算非常に低強度です。リアルタイムの物理演算ループはなく、離散的なルール検証のみです。インデックス作成は任意で、主に規模が大きい場合の盤面やクエリの利便性を目的とします。

アクター

  • キー:matchmaker["main"]

  • 責務:非同期マッチ向けのプライベート招待とパブリックキューのマッチングを処理します。

  • アクション

    • createGame
    • joinByCode
    • queueForMatch
    • unqueueForMatch
    • closeMatch
  • キュー

    • createGame
    • joinByCode
    • queueForMatch
    • unqueueForMatch
    • closeMatch
  • 状態

    • SQLite
    • matches
    • player_pool
    • 招待とキューのマッピング用の assignments
  • キー:match[matchId]

  • 責務:盤面の状態、手番順、手の検証、最終結果を管理します。

  • アクション

    • connect
    • makeMove
  • キュー

    • なし
  • 状態

    • JSON
    • board
    • turns
    • players
    • connection presence
    • result

ライフサイクル

パブリックキュー
sequenceDiagram
	participant A as Client A
	participant B as Client B
	participant MM as matchmaker
	participant M as match

	A->>MM: queueForMatch()
	B->>MM: queueForMatch()
	Note over MM: pair first two queued players
	MM->>M: create(matchId) + seed X/O players
	MM-->>A: assignment/match info
	MM-->>B: assignment/match info
	A->>M: connect(playerId)
	B->>M: connect(playerId)
	A->>M: makeMove()
	B->>M: makeMove()
	opt all players disconnected for timeout
		Note over M: destroy after idle timeout
	end
	M->>MM: closeMatch(matchId)
プライベート招待
sequenceDiagram
	participant A as Client A
	participant B as Client B
	participant MM as matchmaker
	participant M as match

	A->>MM: createGame()
	MM-->>A: {matchId, playerId, inviteCode}
	B->>MM: joinByCode(inviteCode)
	MM->>M: create(matchId) + seed X/O players
	MM-->>A: assignment/match info
	MM-->>B: assignment/match info
	A->>M: connect(playerId)
	B->>M: connect(playerId)
	A->>M: makeMove()
	B->>M: makeMove()
	M->>MM: closeMatch(matchId)
アイドルゲーム
トピック概要
マッチメイキングマッチメーカーはありません。各プレイヤーは、プレイヤーごとの直接アクターと、共有のリーダーボードアクターを使用します。
ネットコードサーバー権威型(基本ロジック)です。クライアントはUIと建設の意図を管理します。サーバーはリソース、生産率、建設の検証、リーダーボードの合計値を管理します。
ティックレート継続的なティックはありません。大まかな間隔にはc.schedule.after(...)を使い、経過した実時間からオフライン中の進行を計算します。
物理演算標準的なアイドルゲームのループでは使用しません。遷移(build、collect、upgrade)は離散的であり、空間インデックスは必要ありません。

アクター

  • キー:world[playerId]

  • 責務:1人のプレイヤーの進行状況、建物、生産スケジュール、状態の更新を管理します。

  • アクション

    • initialize
    • build
    • collectProduction
  • キュー

    • なし
  • 状態

    • JSON
    • プレイヤーごとの建物
    • resources
    • timers
    • progression state
  • キー:leaderboard["main"]

  • 責務:全体のスコアを保存し、リーダーボードの更新を提供します。

  • アクション

    • updateScore
  • キュー

    • updateScore
  • 状態

    • SQLite
    • プレイヤーをキーとするscoresテーブル
    • 現在のリーダーボード合計値

ライフサイクル

sequenceDiagram
	participant C as Client
	participant W as world
	participant LB as leaderboard

	C->>W: getOrCreate(playerId) + initialize()
	Note over W: seed state + schedule collection
	W-->>C: stateUpdate
	loop gameplay loop
		C->>W: build() / collectProduction()
		W->>LB: updateScore(...)
	Note over LB: upsert scores
	LB-->>C: leaderboardUpdate
	W-->>C: stateUpdate
	end

リファレンスマップ

アクター
CLI
クライアント
クックブック
デプロイ
一般
セルフホスティング

コメント