이 영상은 MMO에서 캐릭터가 앞으로 달리다 뒤로 끌려가는 러버밴딩이 왜 생기는지 보여 준다. 클라이언트는 입력 즉시 캐릭터를 움직이고 서버가 나중에 그 이동을 판정하는데, 둘의 결과가 어긋나면 서버 쪽 위치로 되돌려진다. 원인은 네트워크 지연과 서버·클라 상태 불일치 두 갈래이고, 완전히 없앨 수는 없지만 덜 생기고 덜 보이게 만들 수 있다.
0m부터 50m까지 눈금이 있는 길 위에 두 개의 점이 있다. 꽉 찬 점은 "클라 화면"의 내 캐릭터이고, 점선 원은 "서버 판정" 위치다. 처음에는 서버 위치가 클라를 살짝 뒤에서 따라오는데, 어느 순간 서버 점이 멈추고 "서버: 여기서 이동 인정 멈춤" 칩이 뜬다.
클라 점은 그 뒤로도 계속 달리다가 "↩ 보정 · 뒤로 끌려감" 표시와 함께 서버 점 위치로 튕기듯 되돌아간다. 그 다음 두 점이 다시 같이 움직인다.
화면 문구는 "앞으로 달렸는데 뒤로 끌려가는 현상 = 러버밴딩", "내 화면(클라)의 위치와 서버가 인정한 위치가 벌어졌다가, 서버 쪽으로 되돌려질 때 생깁니다"다. 게임 서버가 위치의 최종 권한을 갖고 있기 때문에 생기는 현상이다.
위 레인은 Client("입력 즉시 이동 (예측)"), 아래 레인은 Server("받은 입력 검증 → 확정")이고 가로축은 시간이다. 클라가 Move #1부터 Move #6까지 이동 입력을 차례로 보내고, 서버는 각각을 검증한 뒤 Ack #1~Ack #5로 응답한다. 첫 왕복 구간에는 RTT 표시가 붙는다. 입력을 보낸 뒤 판정이 돌아오기까지 최소 한 번의 왕복 시간이 걸린다.
클라는 Ack를 기다리지 않고 먼저 움직인다. 기다리면 모든 조작이 RTT만큼 늦게 반응하기 때문이다. 이렇게 서버 결과를 예상해 먼저 반영하는 것을 클라이언트 예측이라 한다.
마지막 Move #6에는 Ack 대신 빨간 Correction #6이 돌아오고, 클라 쪽에 "↩ 위치 되돌림"이 뜬다. 아래 문구가 두 경우를 정리한다.
- 판정 = 예측 → 아무 일도 없음 (대부분의 경우)
- 판정 ≠ 예측 → 보정 패킷이 클라 위치를 덮어씀 = 러버밴딩
Client와 Server 사이로 이동 패킷이 일정 간격으로 흘러가다가, 중간에 패킷들이 길 위에서 멈추고 일부는 빨갛게 떨어진다. "정체 · 손실 · 재전송 대기" 칩과 함께 원인 세 가지가 붙는다. 지연 스파이크, 패킷 손실, TCP 재전송 대기(Head-of-Line)다.
오른쪽 RTT (ms) 그래프는 평소 60ms 안팎에서 순간적으로 800ms대까지 치솟았다가 내려온다. TCP는 순서를 보장하기 때문에 앞 패킷 하나가 손실되면 재전송될 때까지 뒤에 도착한 패킷도 애플리케이션에 전달되지 않는다. 손실 하나가 그 뒤 입력 전체의 지연으로 번지는 이유다.
아래 레인에서 클라 캐릭터는 계속 달리지만 서버 캐릭터는 제자리에 서 있다가, 결국 클라가 서버 위치로 되돌려진다. 화면 문구는 "입력이 안 오는 동안 서버의 캐릭터는 제자리", "서버 정책에 따라 늦게 몰려온 입력은 거부되거나 잘린다 → 서버 위치로 되돌림"이다.
네트워크가 정상이어도 서버와 클라가 알고 있는 상태가 다르면 판정이 어긋난다. 화면은 네 칸으로 나뉘어 각 사례를 반복 재생한다.
- 속도 검증 (안티 스피드핵): 클라는 "이속 +30%" 버프로 달리는데 서버에서는 "버프 만료" 상태다. 서버 기준으로는 허용 속도를 넘으니 보정한다.
- 충돌 · 지형 불일치: 서버에서는 문이 닫혀 있다("서버: 문 닫힘"). 클라만 문을 통과하고, 서버 위치는 문 앞에서 멈춘다.
- 상태이상 선적용: 서버가 먼저
STUN을 걸었는데 클라는 아직 모르고 계속 이동한다. 스턴 시점 위치로 되돌아간다.
- 서버 틱 지연 (과부하): 칩이
Tick 20Hz에서 Tick 20Hz → 4Hz로 바뀐다. 과부하 서버가 밀려 쌓인 입력을 버리거나 잘라내서, 서버 위치는 틱마다 조금씩만 계단식으로 따라오고 결국 클라가 되돌려진다. 늦기만 하고 쌓인 입력을 모두 처리하면 되돌림은 없다.
네 경우 모두 클라 점이 먼저 나가고 서버 점이 뒤에 남았다가 클라가 끌려온다는 모양은 같다. 03과 달리 패킷은 제때 도착했고, 어긋난 것은 판정에 쓰인 상태다.
위쪽 패널은 같은 보정을 두 방식으로 처리한 결과를 나란히 보여 준다. "즉시 스냅"(보정 위치로 순간이동) 레인에서는 Correction을 받을 때마다 캐릭터가 뒤로 튄다. "재조정 + 스무딩"(미확인 입력 재적용 후 보간) 레인에서는 같은 보정을 받아도 실제 오차만큼만 부드럽게 밀린다.
차이는 서버가 보내 준 위치가 이미 과거 시점이라는 데서 나온다. 즉시 스냅은 그 과거 위치로 바로 옮기니 그 사이에 입력한 이동까지 사라진다. 재조정은 보정 위치에서 아직 Ack를 받지 못한 입력을 다시 적용해 현재 위치를 다시 계산한다.
아래에는 줄이는 방법 여섯 가지가 체크된다.
- 입력 시퀀스 번호 + Ack: 서버가 어디까지 처리했는지 클라가 안다.
- 재조정 (Reconciliation): 보정 위치에서 미확인 입력을 다시 적용한다.
- 오차 허용치: 작은 차이는 보정하지 않는다.
- 보정 보간 (Smoothing): 순간이동 대신 100~200ms에 걸쳐 이동한다.
- 이동은 UDP · 비신뢰 채널: HOL을 피하고, 최근 입력을 중복 전송한다.
- 서버 틱 여유 · 상태 동기화: 버프 · 상태이상 · 충돌을 같은 기준으로 판정한다.
시퀀스 번호 · 재조정 · 보간은 클라 쪽, 오차 허용치는 서버 쪽에서 보정 자체를 줄인다. 뒤의 둘은 03과 04의 원인을 줄이는 방법이다.
용어 정리
- 러버밴딩
- 클라 화면의 캐릭터가 서버가 인정한 위치로 끌려 되돌아가는 현상이다. 고무줄에 당겨지듯 보여서 붙은 이름이다.
- 서버 권한 (Server Authority)
- 위치, 체력 같은 게임 상태의 최종 결정권을 서버가 갖는 구조다. 클라 조작을 그대로 믿지 않아 치트를 막을 수 있다.
- 클라이언트 예측 (Prediction)
- 서버 응답을 기다리지 않고 입력 즉시 결과를 화면에 반영하는 방식이다. 조작감은 좋아지지만 서버 판정과 어긋날 수 있다.
- Ack
- 서버가 특정 입력을 받아 처리했다고 알려 주는 응답이다. 영상에서는
Ack #n이 Move #n에 대한 확인이다.
- Correction (보정 패킷)
- 서버 판정이 클라 예측과 다를 때 서버가 보내는, 그 입력 시점의 올바른 위치다. 클라는 여기서 미확인 입력을 다시 적용한다.
- RTT
- 패킷이 클라에서 서버로 갔다가 응답이 돌아오기까지의 왕복 시간이다. 흔히 핑이라고 부른다.
- 지연 스파이크
- 평소 낮던 RTT가 짧은 시간 동안 크게 튀는 현상이다. 영상의 RTT 그래프에서 60ms 안팎이던 값이 800ms대로 오른다.
- 패킷 손실
- 전송 중에 패킷이 사라져 상대에게 도착하지 않는 것이다. TCP에서는 재전송으로 복구되지만 그만큼 늦어진다.
- Head-of-Line (HOL) 블로킹
- 순서를 보장하는 TCP에서 앞 패킷 하나가 재전송을 기다리는 동안 뒤 패킷들도 전달되지 못하고 막히는 현상이다.
- UDP · 비신뢰 채널
- 재전송과 순서 보장이 없는 전송 방식이다. 이동 입력은 UDP로 보내되 패킷마다 최근 입력 몇 개를 중복해 실어 손실을 견딘다. 서버가 보내는 상태는 최신 값만 쓴다.
- 틱 / 틱레이트
- 서버가 게임 상태를 한 번 갱신하는 주기가 틱이고, 초당 틱 수가 틱레이트다.
20Hz는 50ms마다 한 번 판정한다는 뜻이다.
- 재조정 (Reconciliation)
- 보정을 받으면 그 위치에서 아직 Ack를 못 받은 입력을 다시 적용해 현재 위치를 다시 계산하는 기법이다.
- 보정 보간 (Smoothing)
- 보정된 위치로 순간이동하지 않고 짧은 시간(영상에서는 100~200ms)에 걸쳐 옮겨 가는 처리다.
- 오차 허용치
- 서버와 클라 위치 차이가 이 값보다 작으면 보정하지 않는 기준이다. 사소한 떨림을 줄인다.