Cloudflare Durable Objectsでゲーム部屋を管理した設計
常設VPSを使わず、部屋ごとのリアルタイム状態をDurable Objectsで管理した理由と設計上の工夫をまとめます。
オンライン対戦では、参加者のチーム、役割、公開済みカード、現在の手番を全員で共有する必要があります。最初は一般的なNode.jsサーバーとSocket.IOも検討しましたが、個人運用で常設VPSを保守し続ける負担を減らすため、Cloudflare WorkersとDurable Objectsへ移行しました。
部屋単位で状態を分ける
部屋IDごとに1つのDurable Objectを割り当て、参加者一覧とゲーム状態をその中へ集約しています。同じ部屋への操作が同じオブジェクトに届くため、複数の参加者がほぼ同時にカードを選んだ場合でも、状態更新の順序を整理しやすくなります。
切断をどう扱うか
一時的な通信断を永続メンバーとして残すと、開始条件を満たせなくなります。このゲームでは再接続の完全な復元より、短いセッションでロビーを正常に保つことを優先し、切断したプレイヤーはメンバー一覧から取り除く方針にしました。ホストが抜けた場合は、残っている参加者へ権限を移します。
サーバーレスでも設計は必要
サーバーを管理しなくてよいことと、状態管理を考えなくてよいことは別です。誰が変更できるか、ゲーム開始後に役割を変えられるか、二重操作をどう防ぐかを先に定義しておかないと、実装が増えるほど不整合が起きます。小規模なゲームでも、状態遷移を文章で整理してからコードへ落とすことが重要でした。