Skip to content

ゲーム途中参加・再接続時に試合状態が再初期化される問題への対応 #87

Closed

Description

@coderabbitai

概要

現在の backend/src/game/game.service.ts における handleGameJoin() は、ルームの phase や既存 playerId の有無を十分に検証せず addPlayerToRoom() を呼び出しています。

そのため、以下のようなケースで進行中の試合状態が意図せず上書きされる可能性があります。

  • 試合中 (playing など) のルームへ新規参加した場合
  • 既存の playerId で再 join した場合
  • 切断済みプレイヤーが再 join したことで、alive・位置・stats が再初期化される場合

removePlayerFromRoom() は試合中プレイヤーを即削除せず alive = false にする挙動のため、再 join と組み合わさると「暗黙の蘇生」経路が残ります。

対応内容

以下を後続対応として実施する。

  1. handleGameJoin() でルーム phase を検証し、進行中ルームへの途中参加ポリシーを明確化する
    • 少なくとも、未対応の新規途中参加で状態を書き換えないこと
  2. playerId が既存プレイヤーと一致する場合は、無条件に addPlayerToRoom() で再初期化しない
    • 明示的に許可された再接続フローのみ、既存状態を復元する
  3. removePlayerFromRoom() 側も見直し、意図しない再 join だけでプレイヤーが復活しないようにする
  4. 必要に応じて再接続タイムアウトや参加可否ルールを整理し、クライアント/サーバー間の期待動作を明文化する

影響範囲

  • backend/src/game/game.service.ts
  • backend/src/game/logic/player.logic.ts
  • 必要に応じて backend/src/game/game.gateway.ts
  • 必要に応じて共有イベント仕様および再接続ポリシー周辺

背景

本件は PR では TODO として認識されているものの、現状のままだと進行中の試合の整合性を崩すリスクがあります。サーバー主導のゲーム進行に移行したため、join/rejoin の扱いは状態整合性の観点で早めに明確化しておく必要があります。

受け入れ条件

  • 進行中ルームへの新規途中参加で既存プレイヤー状態や stats が上書きされない
  • 同一 playerId の再 join で、未許可のケースでは状態が再初期化されない
  • 切断プレイヤーが暗黙に蘇生しない
  • 許可する再接続フローがある場合、その条件と復元内容がコード上で明確になっている
  • 可能であれば該当ケースを検証するテストが追加されている

参照

Requested by @cimura

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions