8. 지연 보상: 클라 예측, 서버 재조정, 보간/외삽, lag compensation
난이도 상내 답안
모범답안
모범답안 — 지연 보상: 클라 예측, 서버 재조정, 보간/외삽, lag compensation
난이도: 상
핵심 답변
- 권위 서버: 게임 상태의 진실은 서버가 갖는다. 클라는 입력을 보내고 서버 결과를 받아 표시. 클라를 믿으면 **치트(위치/데미지 조작)**가 자유로워지므로 신뢰하지 않는다.
- 클라이언트 예측: 입력을 서버 응답을 기다리지 않고 로컬에서 즉시 적용해 반응성을 확보. 서버 결과가 오면 **재조정(reconciliation)**으로 어긋남을 보정.
- 재조정: 클라는 입력에 시퀀스 번호를 붙여 보관. 서버가 "이 입력까지 반영한 권위 상태"를 보내면, 클라는 그 상태에서부터 **아직 미확인인 입력들을 다시 재생(replay)**해 현재로 보정한다.
- 원격 엔티티: 과거 스냅샷 사이를 보간해 부드럽게 그린다(약간의 의도적 지연 버퍼). 스냅샷이 끊기면 속도로 외삽.
- lag compensation: 서버가 발사 시점의 화면(과거 상태)으로 되감아 피격을 판정 → 쏜 사람 기준 공정. 부작용으로 "엄폐물 뒤에서 맞는" 현상.
깊이 있는 설명 (왜, 메커니즘)
권위 서버
- 모든 충돌·데미지·이동 검증을 서버가 한다. 클라가 "나 순간이동했고 너 죽었어"라고 보내도 서버가 검증·거부할 수 있어야 한다.
- 클라를 신뢰하면 speedhack/aimbot/텔레포트/데미지 조작이 막을 길이 없다. 그래서 클라는 입력(의도)만 보내고, 결과는 서버가 결정한다. 단점은 입력→반영에 RTT 지연이 생기는 것 → 아래 기법들로 가린다.
클라이언트 예측 + 서버 재조정
- 예측: 유저가 W를 누르면 서버 응답을 기다리지 않고 클라가 즉시 캐릭터를 앞으로 옮긴다. 동시에 그 입력을 서버로 전송하고, (시퀀스 번호 + 입력)을 미확인 큐에 저장.
- 서버는 받은 입력들을 권위적으로 처리하고, 주기적으로 "시퀀스 N까지 반영한 너의 권위 위치"를 클라에 보낸다.
- 재조정: 클라는 서버가 준 권위 상태(시퀀스 N 시점)를 기준으로 삼고, **N 이후 아직 미확인인 입력들을 그 상태 위에 다시 시뮬레이션(replay)**해 "지금" 위치를 재계산한다.
- 예측이 맞았으면 결과가 같아 화면 변화 없음.
- 어긋났으면(서버가 충돌/보정) 위치가 살짝 튄다 → 이걸 부드럽게 보정(스무딩)해 롤백을 덜 거슬리게 한다.
- 핵심은 결정론적 시뮬레이션 + 시퀀스 번호 기반 재생. 같은 입력을 같은 시작 상태에 적용하면 클라·서버가 같은 결과여야 한다.
보간 vs 외삽 (원격 엔티티)
- 보간(interpolation): 서버 스냅샷은 띄엄띄엄(예: 20~30Hz) 온다. 원격 캐릭터를 과거 두 스냅샷 사이를 보간해 그린다. 이를 위해 일부러 렌더 시점을 과거로 100ms 정도 지연(interpolation delay)시킨다. 부드럽지만 남이 항상 약간 과거로 보인다.
- 외삽(extrapolation / dead reckoning): 다음 스냅샷이 늦거나 안 오면, 마지막 속도·방향으로 미래를 추정해 그린다. 끊김을 가리지만, 추정이 틀리면(상대가 갑자기 멈춤·방향전환) 튀거나 벽을 뚫는 보정이 필요.
- 트레이드오프: 보간 = 부드럽지만 지연↑(과거 표시), 외삽 = 최신성↑이지만 오차·튐 위험. 보통 보간을 기본, 패킷 손실 시 짧게 외삽으로 메운다.
lag compensation (피격 판정 되감기)
- 문제: 쏜 사람 화면엔 보간 때문에 적이 과거 위치에 보인다. 그 위치에 정확히 조준해 쐈는데, 패킷이 서버에 도착했을 땐 적이 이미 움직여 빗나간다 → "분명 맞췄는데 안 맞음."
- 해결: 서버가 각 엔티티의 **위치 히스토리(최근 수백 ms)**를 보관. 발사 패킷이 오면, 그 클라이언트가 봤던 시점(현재 - RTT/2 - interpolation delay)으로 적들을 되감아 그 시점 위치로 명중 판정. → 쏜 사람 기준 공정.
- 부작용: 되감기 때문에 맞은 사람 입장에선 "이미 엄폐물 뒤로 숨었는데 맞는" 현상(behind-cover hit / peeker's advantage). 핑 차이가 클수록 두드러진다. 게임은 되감기 허용 한도(예: 200~250ms)를 두어 극단적 핑 악용을 제한한다.
응용/실무 연결 (게임서버에서)
- 로컬 플레이어: 예측 + 재조정 → 입력 즉시 반응, 어긋나면 보정.
- 원격 플레이어: 보간(+필요 시 외삽) → 부드러운 움직임.
- 피격 판정: 서버 권위 + lag compensation → 공정성과 반응성 균형.
- 발사체/투사체는 예측이 어려워(궤적·충돌) 보통 서버 권위로 두되, 시각 효과만 클라에서 즉시 재생.
- tick rate(서버 시뮬 주파수, 예: 60Hz)와 snapshot rate(전송 주파수, 예: 20Hz)를 분리해 대역폭과 정밀도를 조율한다. 관심 영역(AoI)으로 가까운 엔티티만 자주 보낸다.
흔한 오답·함정
- "클라 예측을 켜면 치트에 취약" → 예측은 표시용일 뿐, 권위는 여전히 서버. 서버가 거부하면 재조정으로 되돌아온다.
- "보간 지연은 버그다" → 의도된 지연. 이걸 없애면 패킷 지터로 원격 캐릭터가 떨린다.
- "lag compensation이 없으면 고핑이 유리" → 오히려 보정이 없으면 고핑 유저가 계속 빗나가 불리. 보정이 형평성을 맞춘다. 단 과하면 저핑 피해자가 손해.
- "외삽이 보간보다 항상 좋다" → 외삽은 오차·튐 위험. 보통 보간이 기본.
- "재조정은 위치만 보면 된다" → 입력 시퀀스 번호로 "어디까지 반영됐는지" 알아야 미확인 입력만 정확히 재생한다.
꼬리질문 대비
- Q. 결정론(determinism)이 왜 중요한가? A. 재조정의 replay가 정확하려면 같은 입력+같은 상태 → 같은 결과여야 한다. 부동소수점/난수/물리 순서가 클라·서버에서 어긋나면 미스프레딕션이 잦아진다.
- Q. 고무줄 현상(rubber-banding)의 원인은? A. 클라 예측이 서버와 크게 어긋나(패킷 손실, 서버 보정) 위치가 반복적으로 뒤로 당겨지는 것. 손실 복구·스무딩·예측 오차 제한으로 완화.
- Q. lockstep(결정론적 동기) 모델과 무엇이 다른가? A. RTS에서 흔한 lockstep은 모든 클라가 같은 입력을 받아 동일 시뮬을 돌린다(상태 대신 입력만 전송). 지연·동기화에 민감하고 한 명이 느리면 전체가 기다린다. FPS는 보통 클라 예측 + 서버 권위.
- Q. 스냅샷 압축은 어떻게? A. 델타 압축(이전 스냅샷 대비 변경분만), 비트 패킹, 양자화, AoI로 관심 밖 엔티티 제외 → 대역폭 절감.