YJ — 턴 상태 분리 스냅샷
1. 주요 변경사항
TurnMachine을 새로 만들어 현재 턴, 타임아웃 생명, 왕 대기 승리 조건을PlayerController에서 일부 분리했다.GameConfigSO와GameConfig.asset을 추가해 턴 제한 시간, 타임아웃 횟수, 승격 행 설정을 데이터로 뺐다.- 포로 재배치 후
EndTurn()이 호출되도록 변경해 드롭 행동도 턴 소비 행동으로 처리했다. - 서버의
S_GameOver수신 처리를 브로드캐스트에서 무시로 바꿔 클라이언트 승패 조작 취약점을 막았다. PacketHandler의 턴 종료 처리 조건을 단순화해 서버 확정 턴 전환을 항상 반영하도록 바꿨다.
2. 코드 품질 리뷰
TurnMachine 도입은 좋은 방향이다. 턴, 생명, 왕 대기 상태가 PlayerController 안에 흩어져 있던 구조를 줄이려는 의도가 분명하다. GameConfigSO도 매직 넘버를 씬 인스펙터 값에서 데이터 에셋으로 옮긴 점에서 긍정적이다. 다만 현재 구현은 “분리”에 머물렀고, “권한의 주인”은 아직 정리되지 않았다. TurnMachine이 각 클라이언트에서 독립 생성되므로 네트워크 지연, 재접속, 패킷 중복 상황에서 턴 상태가 갈라질 수 있다.
가장 큰 위험은 게임 종료 처리다. 서버가 S_GameOver를 무시하도록 바꾼 것은 보안상 맞다. 그러나 클라이언트의 SendGameOverPacket() 호출은 그대로 남아 있다. 즉, 조작 취약점은 막았지만 서버가 승패를 새로 판정해서 내려주는 경로는 아직 없다. 이 상태에서는 한 클라이언트는 결과 UI를 띄우고, 다른 클라이언트는 게임이 계속되는 식의 분기 가능성이 있다.
case PacketID.S_GameOver:
Console.WriteLine("[Security] 클라이언트로부터 잘못된 S_GameOver 수신. 무시합니다.");
break;
또한 Start()에서 config.maxTimeoutCount를 바로 참조한다. 현재 씬에는 연결됐지만, 새 씬·테스트 씬·프리팹 재사용 시 null이면 즉시 런타임 예외다. 설정 에셋을 쓸 때는 OnValidate나 Awake에서 명시적으로 실패시키고, 어떤 값이 필수인지 로그로 남기는 편이 좋다.
3. 진행도 평가
이번 변경은 턴 시스템을 별도 클래스로 빼고 설정을 ScriptableObject화했다는 점에서 구조적 전진이 있다. 특히 이전처럼 모든 룰 값이 PlayerController에 직접 붙어 있는 상태보다는 유지보수성이 좋아졌다. 그러나 멀티플레이 게임으로 보면 아직 핵심 상태가 서버 권위로 정착하지 않았다.
진행도는 약 35%로 본다. 로컬 핵심 루프 일부는 동작 가능한 단계로 보이나, 네트워크 권한 모델·게임 종료 동기화·문서화가 부족하다. 다음 단계에서 기능을 더 붙이면 속도는 날 수 있지만, 지금 권한 경계를 고정하지 않으면 디버깅 비용이 급격히 커진다.
4. 다음 권장사항
- 게임 종료는 클라이언트 송신 패킷이 아니라 서버 판정 이벤트로 바꿔야 한다.
TurnMachine의 주 상태를 서버가 소유하게 하고 클라이언트는 표시와 입력 요청만 담당하게 정리해야 한다.GameConfigSO누락 시 명확히 실패하도록 null 방어와 기본값 검증을 추가해야 한다.- 이동·드롭 수신 처리에 중복 패킷, 불법 좌표, 턴 불일치 검증을 넣어야 한다.
- 기술 문서에 패킷별 송신자, 수신자, 검증 책임, 상태 변경 주체를 표로 작성해야 한다.
5. 문서화 상태
design 점수는 2점이다. 프로젝트의 의도나 게임 규칙 일부는 추정 가능하지만, GDD placeholder가 남아 있어 코어 루프와 플레이 경험 목표가 문서로 검증되지 않는다.
technical 점수는 1점이다. 커스텀 네트워크 스택을 쓰고 있는데 권한 모델, 패킷 흐름, 서버 검증 책임이 문서화되어 있지 않다. 지금은 코드를 읽어도 “누가 진짜 상태를 소유하는가”가 명확하지 않다.
spec 점수는 1점이다. 턴 제한 시간, 타임아웃 횟수, 승격 행 같은 수치는 생겼지만 입력·상태·결과 매핑과 씬 구성 사양이 없다. 테스트 체크리스트로 쓰기에는 아직 부족하다.
6. Backlog
- 커스텀 네트워크 스택의 권한 모델·프로토콜 사양은 아직 없다.
TurnMachine이 클라이언트 로컬 상태라 지연·재접속 대응 기준이 없다.C_/S_패킷 타입명과 실제 방향 불일치는 계속 디버깅 위험을 만든다.docs/gdd.md,docs/tdd.md의 placeholder 문제는 해결되지 않았다.- 매칭·대기실·인게임 씬 분리 설계가 아직 없다.
- 포로 재배치 금지 규칙은 룰 출처와 의도 확인이 필요하다.
concept.md의 닫히지 않은 코드블록 문제도 남아 있다.
7. 이전 Backlog 해결
- 서버가
S_GameOver를 클라이언트 입력으로 받아 브로드캐스트하던 문제는Session.cs에서 무시 처리로 바뀌었다. 다만 이는 조작 수용을 막은 것이며, 서버 권위 게임 종료 판정 경로는 별도 작업으로 남아 있다.