YJ — 네트워크 권위 전환 스냅샷
1. 주요 변경사항
C_Move/C_Drop요청과S_Move/S_Drop결과 브로드캐스트를 분리해 패킷 방향성이 전보다 명확해졌다.- 서버에
piecePositions, 왕 캡처 판정, 입궁 대기 승리 판정, 강제 종료 시 상대 승리 처리가 추가됐다. - 클라이언트는 로컬 즉시 이동을 줄이고 서버 응답을 받아
OnServerMove,OnServerDrop에서 보드를 갱신하는 방향으로 바뀌었다. S_SyncStatus로 라이프와 현재 턴을 내려주는 흐름이 추가됐지만, 이동 성공 시에는 여전히 클라이언트가 로컬 턴 전환을 수행한다.
2. 코드 품질 리뷰
이번 커밋은 방향 자체는 맞다. 클라이언트가 S_GameOver를 보내던 구조를 차단하고, 서버 패킷을 클라이언트가 송신하면 보안 로그를 남기도록 한 점은 분명한 개선이다. 다만 서버 권위 모델이 아직 절반만 구현됐다. 서버는 왕의 1칸 이동과 왕 캡처 정도만 검사하고, 일반 기물 이동 규칙·아군 말 충돌·포로 보유 여부·포로 배치 가능 칸은 클라이언트 판단에 의존한다. 이는 멀티플레이 보드게임에서 치명적인 설계 부채다.
PlayerController는 입력, UI, 네트워크 송신, 서버 이벤트 적용, 승패 처리, 포로 관리가 한 클래스에 계속 몰려 있다. 왜 문제냐면 네트워크 지연이나 중복 패킷이 들어왔을 때 어느 상태가 진짜인지 추적하기 어렵기 때문이다. 개선하려면 입력 컨트롤러, 보드 뷰 적용기, 네트워크 상태 적용기를 분리하고, 서버에서 받은 스냅샷 또는 명령 결과만 보드에 반영하는 흐름으로 좁혀야 한다.
자료구조/복잡도 관점에서는 FindPieceById가 서버 이벤트마다 FindObjectsOfType<Piece>(true)와 Array.Find를 수행한다. 현재 말 수가 작아 성능 병목은 아니지만, 네트워크 sync hot path에서 전체 Unity 오브젝트 검색이 반복되는 구조는 유지보수성과 안정성 모두에 나쁘다. BoardManager나 별도 registry에 Dictionary<int, Piece>를 유지하면 id 조회 비용이 고정되고, 서버 상태와 클라이언트 표시 상태를 대조하기도 쉬워진다.
3. 진행도 평가
이전 대비 네트워킹 방향은 전진했다. 특히 패킷 명명과 강제 종료 승패 처리, 서버 측 왕 이동 제한은 실제 플레이 문제를 해결하려는 흔적이 분명하다. 그러나 지금은 “서버 권위로 전환 중”이지 “서버 권위가 완성된 상태”가 아니다.
진행도는 약 38%로 판단한다. 핵심 루프는 일부 연결됐지만 TCP 패킷 파싱, 턴 동기화, 재접속, 룰 검증, 문서가 모두 불안정하다. 다음 단계에서 기능을 더 얹기보다 네트워크 상태 흐름을 정리해야 2인 플레이 디버깅 비용이 폭증하지 않는다.
4. 다음 권장사항
- 서버가 모든 이동·포로배치 합법성을 검증하게 만들고, 클라이언트는 요청만 보내도록 역할을 고정한다.
OnServerMove의 로컬EndTurn()의존을 제거하고, 턴 변경은S_SyncStatus또는 서버 결과 패킷 한 경로로 통합한다.- TCP는 메시지 경계를 보장하지 않으므로 클라이언트와 서버 모두 누적 수신 버퍼 기반 패킷 파서를 도입한다.
pieceId조회를Dictionary<int, Piece>registry로 바꿔 서버 이벤트 적용 경로에서 전체 오브젝트 검색을 제거한다.- 기술 문서에 패킷 ID, 송수신 방향, 상태 주인, 승패 판정 주체를 표로 명시한다.
5. 문서화 상태
design 점수는 3점이다. 컨셉 문서가 일부 존재하는 것으로 보이나, 현재 커밋에서는 게임 경험 목표나 룰 선택 이유를 보강한 흔적이 없다. 특히 포로 배치 규칙처럼 원작과 다른 선택은 기획 근거가 필요하다.
technical 점수는 2점이다. 코드에는 커스텀 TCP 스택과 서버 권위 전환이 들어갔지만, 신규 개발자가 문서만 보고 권한 모델과 데이터 흐름을 이해할 수 있는 상태가 아니다. 지금은 코드가 사양서 역할을 대신하고 있어 위험하다.
spec 점수는 2점이다. 씬 구성, 입력, 턴 상태, 승패 조건, 네트워크 패킷의 성공·실패 결과가 테스트 체크리스트 수준으로 정리되어 있지 않다. _sample/docs 기준과 비교하면 아직 placeholder 단계에 가깝다.
6. Backlog
- 커스텀 네트워크 스택의 권한 모델·프로토콜 사양 부재는 계속 남아 있다. 패킷 이름은 좋아졌지만 문서화된 계약은 없다.
- 클라이언트 로컬
TurnMachine과 서버 턴 상태 분리 문제는 아직 해결되지 않았다. 이동 수신 시 로컬 턴 전환이 남아 있다. - GDD/TDD placeholder, 씬 분리, 포로 배치 룰 출처,
concept.md코드블록 문제는 이번 커밋에서 변경 근거가 없다. - 서버 보드 상태는
piecePositions만 추적해 캡처된 말의 소유권, 보유 포로 목록, 재접속 복원 상태를 표현하지 못한다.
7. 이전 Backlog 해결
- 패킷 타입명이 C_/S_ 의미와 실제 송수신 방향이 불일치하던 문제는 이번 커밋에서 해결된 것으로 본다. 클라이언트와 서버 양쪽
Packet.cs에C_Move/C_Drop요청과S_Move/S_Drop결과 패킷이 분리됐고, 서버도 클라이언트가S_패킷을 보내면 거부하도록 바뀌었다.