YJ — 로비 씬 및 룸 매칭 스냅샷
1. 주요 변경사항
LobbyScene.unity가 추가되고Game.unity는GameScene.unity로 이름이 바뀌었다. 로비 UI에는 자동 매칭, 방 생성, 코드 입장 입력이 배치되어 있다.- 서버에
GameRoom,RoomManager가 도입되어 기존 전역 턴/보드 상태를 방 단위 상태로 옮기려는 방향이 보인다. S_Login에roomId가 추가되어 클라이언트가 방 번호를 받을 수 있게 되었다.- 이동, 드롭, 턴오버, 게임오버 브로드캐스트가
SessionManager.Broadcast에서room.Broadcast로 일부 전환되었다.
2. 코드 품질 리뷰
방 단위 상태로 옮긴 방향 자체는 맞다. 이전 전역 turnMachine 과 piecePositions 는 두 게임이 동시에 열리는 순간 바로 깨지는 구조였고, 이번 변경은 그 문제를 인식했다는 점에서 전진이다. 다만 구현이 아직 위험하다. Program.cs 의 OnAcceptHandler 는 PacketHandler.HandleRoomRequest(session, 0) 로 자동 매칭을 수행한 직후 다시 RoomManager.Instance.FindRoom(1) ?? CreateRoom() 후 room.Enter(session) 를 호출한다. 같은 세션이 두 번 입장할 수 있고, session.Room 이 마지막 방으로 덮이며, 이미 보낸 S_Login 의 roomId/teamId 와 실제 서버 상태가 어긋난다. 이 상태는 테스트가 아니라 첫 접속부터 재현 가능한 치명적 흐름 버그다.
패킷 계약도 정리되지 않았다. S_Login 은 IPacket 을 구현하지 않고 Write() 가 byte[] 를 반환하는 반면, 다른 패킷은 ArraySegment<byte> 를 반환한다. 서버와 클라이언트의 Packet.cs 복사본도 같은 방식으로 수정되어 있어 지금은 우연히 Send 시그니처가 받아주는지에 의존한다. 개선하려면 S_Login : IPacket 으로 복원하고 Protocol, Read, Write 패턴을 다른 패킷과 동일하게 맞춰야 한다.
자료구조/복잡도 관점에서는 RoomManager.GetRoomList() 가 매 자동매칭마다 new List<GameRoom>(_rooms.Values) 를 만들고 선형 탐색한다. 현재 방 수가 작다면 성능 병목은 아니지만, 자동매칭 hot path 가 될 코드에서 불필요한 복사와 O(n) 탐색을 고정해 버린다. waitingRoomQueue 또는 HashSet/GameRoom 대기 목록을 별도로 유지하면 비용이 줄고 “1명 대기 중인 방” 이라는 도메인 상태도 명확해진다. 더 중요한 것은 GameRoom.Sessions 와 PiecePositions 가 락 없이 변경된다는 점이다. 서버 수신 스레드가 병렬이면 리스트와 딕셔너리 상태가 찢어진다.
3. 진행도 평가
이번 커밋은 “로비/룸” 이라는 필요한 축을 건드렸다는 점에서 의미 있는 전진이다. 그러나 빌드 설정에는 GameScene.unity 만 남아 있고 LobbyScene.unity 가 포함되지 않아 실제 시작 흐름이 확정되지 않았다. 로비 UI 버튼도 m_OnClick 이 비어 있어 화면 구성과 기능 연결 사이의 간극이 크다.
진행도는 약 34%로 본다. 핵심 게임 루프 일부와 서버 구조의 초안은 있으나, 접속·매칭·씬 전환·턴 동기화가 안정적으로 이어지는 2인 플레이 빌드까지는 아직 거리가 있다. 특히 네트워킹 부채가 누적되는 속도가 빠르므로 다음 커밋은 기능 추가보다 흐름 정정이 우선이다.
4. 다음 권장사항
Program.cs의 중복 입장 흐름을 즉시 제거한다. 접속은 세션 생성까지만 하고, 방 입장은 명시적 로비 요청 패킷으로 처리하는 편이 좋다.LobbyScene을 Build Settings 에 넣고 앱 시작 씬을 로비로 정한다. 이후S_Login수신 시에만GameScene으로 이동하게 만든다.S_Login을 포함한 모든 패킷의 인터페이스와 직렬화 규칙을 하나로 통일한다. 클라/서버 복사본을 수동으로 벌리는 방식은 곧 사고가 난다.GameRoom의 상태 변경은 단일 네트워크 처리 큐 또는 명확한 lock 범위에서 수행한다. 방 리스트만 잠그고 내부 상태를 방치하면 문제는 남는다.- 자동매칭은 전체 방 복사 후 선형 탐색이 아니라 대기 방 큐로 표현한다. 이 편이 성능보다 상태 의미 측면에서 더 안전하다.
5. 문서화 상태
design 점수는 3점이다. 게임 콘셉트와 장기류 룰의 윤곽은 있으나, 로비/매칭/대전 흐름이 플레이어 경험 관점에서 문서화되어 있지 않다.
technical 점수는 2점이다. 이번 커밋의 핵심은 커스텀 TCP 서버와 룸 상태인데, 권한 모델, 패킷 표, 세션 생명주기, 재접속 정책이 문서에 없다. 신규 인원이 코드를 읽지 않고 구조를 이해하기 어렵다.
spec 점수는 2점이다. 씬 구성, 버튼 동작, 방 생성/입장 실패 조건, 게임 시작 조건 같은 테스트 가능한 사양이 없다. _sample/docs 수준과 비교하면 체크리스트로 쓸 수 있는 구체성이 부족하다.
6. Backlog
- 커스텀 네트워크 스택의 권한 모델·프로토콜 사양은 여전히 없다. 지금은 패킷 클래스 자체도 계약이 흔들리고 있어 우선순위가 높다.
- 클라이언트 로컬 턴 상태와 서버 턴 상태의 관계가 아직 명확하지 않다.
S_SyncStatus만으로 지연·재접속 대응이 된다고 보기 어렵다. - GDD/TDD placeholder 문제는 이번 커밋에서 손대지 않았다. 문서 기반 개발 흐름은 아직 약하다.
- 로비 씬은 추가되었지만 빌드 설정과 버튼 연결이 빠져 있어 “씬 분리 설계 완료” 로 볼 수 없다.
- 포로 재배치 규칙 출처와
concept.md코드블록 문제도 변경 근거가 없으므로 그대로 이월한다.