Search

260722_2314_Lag Compensation_FPS에서 화면상으로는 맞춘 샷이 서버에서는??

출처

FPS에서 화면상으로는 맞춘 샷이 서버에서는 빗나간 것으로 판정되는 이유는, 상대 위치가 네트워크 지연만큼 과거 시점으로 보이기 때문입니다.
상대가 이동하면, 그 정보는 서버를 거쳐 내 클라이언트로 도착합니다.
그래서 서버는 상대의 "현재"보다 한 박자 늦은 위치를 보고,
나는 그보다도 더 늦은 시점의 상대를 화면에서 보게 됩니다.
이 상태에서 내가 화면의 상대를 정확히 조준해 쏴도, 서버 입장에서는 이미 상대가 그 자리를 떠난 상태 → 미스 판정이 납니다.
[실제 상대] ───────────▶ 위치 A (이미 이동함) [서버가 아는 상대] ────▶ 위치 B (조금 과거) [내가 보는 상대] ──────▶ 위치 C (더 과거) 내가 C를 조준해서 사격 → 서버는 B/A 기준으로 판정 → "빗나감" 처리
Plain Text
복사

원인 파악을 해봅시다 :)

멀티플레이 FPS는 보통 권한 있는 서버(Authoritative Server) 구조입니다.
클라이언트가 "맞췄다"고 주장해도, 최종 히트 판정은 서버가 합니다.
그런데 클라이언트마다 핑이 다르고, 패킷도 왕복 시간이 걸립니다.
그래서 "내가 본 세상"과 "서버가 알고 있는 세상"이 항상 어긋납니다.
즉 이런 상황입니다 :(
사격 입력 → 서버 도착까지 RTT/2 지연 상대 위치 정보 → 서버 → 나에게 오기까지 또 지연 → 내 화면의 상대 ≈ 실제보다 수십~수백 ms 과거 → 그대로 서버 현재 좌표로 판정하면 명중률이 무너짐
Plain Text
복사

여기서 우리가 꼭 알아가야할 핵심 개념!!: Lag Compensation (렉 보상)

Lag Compensation은 사격 판정 때 서버가 상대 위치를 현재가 아니라, 사격자가 봤던 과거 시점으로 되감아(rewind) 검사하는 기법입니다!
플레이어는 상대의 미래 위치를 예측할 필요 없이, 화면에 보이는 대로 조준하면 됩니다.
아래는 서버가 하는 일의 흐름입니다!
1. 사격자의 핑 + 보간(Interpolation/Lerp) 지연을 계산 2. "이 사격자가 그 순간 보고 있었을 시각"을 역산 3. 다른 플레이어들의 위치를 그 과거 시각으로 되돌림 4. 그 상태에서 레이캐스트/히트박스 검사 5. 판정 후 모든 플레이어를 다시 현재 위치로 복원
Plain Text
복사
한 줄 요약: 서버가 잠깐 시간을 되감아서, "너가 본 그 장면" 기준으로 맞춰줬는지 확인해 주는 것!
참고: Valve의 Source 엔진 문서

왜 그냥 서버 현재 위치로 판정하면 안 될까?

보정 없이 서버 현재 좌표만 쓰면:
내가 본 것: 상대가 크로스헤어 한가운데 서버가 아는 것: 상대는 이미 0.1초 전에 옆으로 이동 → 맞춘 샷이 계속 미스 → "에임이 맞는데 안 맞음" 체감이 폭발
Plain Text
복사
그래서 FPS는 사격자 경험(내가 본 대로 맞추기) 을 우선해 Lag Compensation을 씁니다.

자주 하는 오해들입니다!

오해 1. "서버가 현재 위치만 보면 공정하다"

이론상 서버 시각은 하나지만, 플레이어마다 보는 시점 자체가 다릅니다.
현재 위치만 쓰면 핑이 있는 모든 사람이 손해를 봅니다. 공정해 보여도 체감은 최악입니다!

오해 2. "Lag Compensation이면 무조건 내가 유리하다"

Lag Compensation은 사격자 쪽 공정성을 올립니다.
반대로 피격자 입장에서는 "이미 엄폐했는데 맞음" 같은 상황이 생길 수 있습니다.

오해 3. "클라이언트가 맞췄다고 하면 그냥 히트다"

그건 클라이언트 권한(Hit Detection)에 가깝고, 치트에 취약합니다.
현대 FPS는 보통 서버 권한 + Lag Compensation 조합을 씁니다.

부작용: "숨었는데 맞았다"

Lag Compensation의 대표 부작용입니다!
상대 시점: 코너 뒤로 완전히 숨음 → 안전하다고 생각 내 시점: 아직 상대가 코너 밖에 보임 → 그 과거 위치를 조준해 사격 서버: 내 과거 시점 기준으로 되감아 판정 → 히트! → 상대: "이미 숨었는데 왜 맞지?"
Plain Text
복사
이게 흔히 말하는 "벽을 뚫고 맞았다 / 엄폐했는데 죽음" 체감의 한 원인입니다.
(피커스 어드밴티지, 핑 차이, 보간 지연 등과 겹치면 더 크게 느껴집니다.)
그래도 사람들은 보통:
"피했는데 맞는 상황" 보다 "맞췄는데 빗나가는 상황" 을 더 싫어합니다.
그래서 Lag Compensation의 부작용이 있어도, 대부분의 FPS는 이 트레이드오프를 받아들입니다.

해결(설계) 방법

1. Lag Compensation 적용 (기본)

사격 판정 시 상대를 사격자의 관측 시점으로 rewind 합니다.
rewind_time = server_time - (shooter_latency + interpolation_delay) → 그 시각의 히트박스로 레이캐스트 → 끝나면 월드 상태 복원
Plain Text
복사

2. 되감기 상한 두기 (sv_maxunlag 같은 클램프)

핑이 비정상적으로 큰 사람까지 무한정 과거로 되감으면 피격자가 너무 손해입니다.
설정 개념
의미
효과
maxunlag / rewind clamp
최대 되감기 시간 제한 (예: 200ms)
극단적 핑 악용/부작용 완화
초과 시
일부만 보정하거나 예측 조준 요구
사격자도 일부 책임 분담

3. Interpolation(보간)까지 같이 보정하기

클라이언트는 패킷 사이 위치를 부드럽게 잇기 위해 의도적으로 조금 늦게 그립니다.
이 지연(Lerp)도 Latency의 일부이므로, Lag Compensation 계산에 반드시 포함해야 합니다!
총 보정량 ≈ 네트워크 지연 + 클라이언트 보간 지연
Plain Text
복사

4. 히스토리 버퍼 유지

서버는 최근 N ms 동안의 플레이어 위치/히트박스 스냅샷을 보관해야 rewind가 가능합니다.
[서버 메모리] t-200ms: player positions... t-100ms: player positions... t-0ms : player positions... ← 현재 사격 도착 → t-120ms 상태로 잠깐 되돌렸다가 판정 → 복원
Plain Text
복사

5. 치트 방지: 타임스탬프를 맹신하지 않기

클라이언트가 보낸 "내가 쏜 시각"을 그대로 믿으면 조작 여지가 있습니다.
서버는 측정된 핑 기반 보정 + maxunlag 클램프 + 비정상 tick 폐기 등으로 제한합니다.

Lag Compensation vs 관련 기법 차이

둘(셋) 다 "지연을 견디게" 하지만 목적이 다릅니다 !!!!
Client-side Prediction
Interpolation
Lag Compensation
누구를 보정?
나 자신
다른 플레이어 그리기
사격/히트 판정
어디서?
클라이언트
클라이언트
서버
목적
내 조작을 즉시 반응시키기
상대 움직임을 부드럽게
화면에 보이는 대로 맞추기
부작용
예측 실패 시 러버밴딩
상대가 조금 늦게 보임
엄폐 후 피격 체감
Prediction = "내 움직임 먼저 보여주기"
Interpolation = "남 움직임을 부드럽게 늦춰 보여주기"
Lag Compensation = "맞췄는지 판정할 때 시간을 되감기"

정리해봅시다!

1.
내가 보는 상대는 항상 과거다. 핑과 보간 때문에 서버 현재와 어긋난다.
2.
그래서 FPS는 사격 판정 때 Lag Compensation으로 시간을 되감아 "화면에 보이는 대로" 맞춰준다.
3.
대신 피격자 입장에서는 "숨었는데 맞음" 부작용이 생긴다. 이건 의도된 트레이드오프다.
4.
사람들은 보통 미스 판정(맞췄는데 안 맞음) 을 더 싫어해서, Lag Compensation을 받아들인다.
5.
실무에서는 rewind 상한, lerp 포함 보정, 위치 히스토리, 타임스탬프 검증까지 같이 설계해야 한다.

이상!