게임 서버에 있어서 상태를 저장하는 역할에 그칠 것이 아니라, 역시나 멀티 플레이에 지대한 영향을 미치는 부분을 간과해서는 안된다.
이러한 멀티 플레이 환경에서의 이동 동기화나 상태 교환에 있어서 우리는 서버-클라이언트 간의 정보 교환에 불가피하게 생기는 응답시간/대기시간이 발생한다는 점을 알고 있다.
Latency
란 한 지점에서 다른 지점으로 이동하는 데에 걸리는 시간을 의미한다.
RTL 또는 RTT (Round Trip Time)이란 다음과 같이 정의된다.
data packet이 source에서 destination으로 이동하고, 다시 source로 돌아오는 데에 걸리는 전체 시간
이러한 RTT는 네트워크 연결에서 물리적 거리
와 데이터 전송 속도
에 영향을 받게 되는,
클라이언트-서버 간 메시지 발신 및 응답 받는 왕복시간을 Ping
을 통해 측정한다.
앞서 말한 latency에 대해 괴리가 심하다면 사용자 UX에 매우 부정적인 영향을 줄 것이다. 따라서 네트워크 지연(latency)를 사용자가 느끼지 못하도록 숨기기 위해 다양한 방법으로 Latency Masking을 활용한다.
물론,
레이턴시를 감소시키기 위해서
- 서버 배치 최적화: 주요 플레이어 그룹에 가까운 지역에 데이터 센터를 배치하여 물리적 거리 줄이기
- UDP 프로토콜 활용: reliability보단 빠른 전송속도의 UDP 활용
- 네트워크 코드 최적화: 효율적인 데이터 패킷 설계 및 최소화된 데이터 전송량 유지
- CDN(Content Delivery Network) 사용: 정적 데이터에 대한 빠른 전달
- 패킷 크기 최적화: 오버헤드를 많이 발생시키지 않으면서 빠른 전송속도를 보장할 적당한 패킷 크기 설정
등의 방법들을 활용할 수 있다.
예측 및 보정 알고리즘을 이용하는 것으로, Latency에 대해 인지를 하여, 레이턴시 만큼의 이동을 예측하여 데이터를 전달한다.
예시 시나리오: 레이턴시가 100ms인 상황에서 속도가 1, 1초에 1번 패킷 전달의 경우
- 1초 뒤 보낼 패킷은 1.1초에 도착을 하니 1.1 x 1 (거리 = 속력 X 시간) 만큼의 값을 전달
이러한 내용의 위치 동기화를 어떤 방식으로 적용할 지에 대해, 내용은 다음과 같다.
게임의 세션마다 세션에 참여하는 유저들이 존재한다.
세션에 참여하는 유저들에 한해서 동기화가 필요한데,
서버는 Ping
을 통해, RTT
를 기록하여 데이터를 가지고 있게 된다.
이제 우리는 이 유저들에 대해 어떤 RTT를 기준으로 동기화를 진행할지 동기화 전략을 선택하면 된다.
보통의 동기화 전략은 다음과 같다.
세션에 참여한 플레이어들의 평균 RTT값을 기준으로 동기화 RTT를 설정하여 진행한다.
이 방법은 대부분의 플레이어에게 균형잡힌 UX를 제공하게 되며 극단적인 네트워크 환경을 가진 소수의 outlier들이 존재하더라도, 동기화에 사용될 latency에 대해 치명적인 영향을 주지 않을 것이다.
다만, 원래 높은 RTT를 가진 플레이어는 상대적으로 불리한 경험을 하게 될 수 있다.
보통은 유저간 실시간 상호작용보다 전체 동기화가 더 중요한 RTS에 사용된다.
세션 내 가장 높은 RTT를 가진 플레이어에 맞춰 동기화를 설정하여 모든 플레이어가 동일한 상태를 유지하도록 한다.
따라서, 높은 RTT의 유저가 영향을 주기 때문에 나머지에겐 비효율을 가져다 줄 수 있는 치명적인 단점이 있으므로, 실시간 판정이나 경쟁 요소가 핵심적인 게임이 아니라 동기화 자체가 매우 중요한 턴제 게임에 주로 사용된다.
Dynamic Latency Compensation은 각 유저의 RTT에 대해 유저 개별적으로 고려하여 동기화 처리하는 방식이다.
따라서 플레이어의 환경마다 다른 동기화 보정이 일어나는데 그만큼 구현과 성능 요구사항이 까다로운 편이다.