게임이 다음과 같이 작동한다고 가정해봅시다.
- 클라이언트에서 플레이어 캐릭터를 조종하는 명령을 서버에 전송
- 서버에서 플레이어 캐릭터의 이동 연산
- 일정 시간마다 클라이언트에 이동 정보 전송
- 클라이언트는 이동 정보를 받고 추측항법으로 플레이어 캐릭터 위치를 부드럽게 업데이트
이럴 경우 네트워크 품질이 좋지 않을 때 답답할 수 있습니다. 플레이어가 이동 조작을 하면, 캐릭터는 약간의 지연 시간 후에 움직일 것입니다. 또한 이동 조작키를 떼면, 캐릭터는 바로 멈추지 않고 약간의 지연 시간 후에 멈출 것입니다. 플레이어가 입력한 명령이 서버를 거치고 연산된 정보가 다시 클라이언트에게 오기까지 시간이 걸리기 때문입니다.
이를 해결하기 위해서는 서버와 클라이언트 간의 통신 횟수를 줄이면 되겠죠. 클라이언트에 사소한 것들을 처리하면 됩니다. 플레이어가 조종하는 캐릭터의 위치 계산은 클라이언트에서 하고, 그 결과를 서버에게 전송해주는 것입니다. 이렇게 되면 서버에서 연산하는 횟수도 줄게 됩니다.
하지만 앞서 상황들에서 보았듯이 클라이언트에서 판단하는 것은 해킹의 위험이 따릅니다. 캐릭터의 이동 속도가 조작이 될 가능성이 있겠죠. 이를 해결하기 위해서 다음과 같은 작업이 필요합니다.
- 클라이언트가 캐릭터의 이동 정보를 서버에 전송
- 서버는 이동 정보를 받아 유효한 값인지 검사
또는 다음과 같이 해야 합니다.
- 클라이언트가 캐릭터의 명령 정보를 서버에 전송. 클라이언트에서 위치 계산. 단, 이동 정보는 전송 X
- 서버는 명령 정보에 따라 캐릭터 이동 처리. 이동 정보를 클라이언트에 전송.
- 클라이언트는 앞선 캐릭터 위치를 무시하고 서버에서 전송한 메시지에 따라 캐릭터 이동.
두 가지 방법 모두 장단점이 있겠죠. 제가 생각하기에 첫 번째 방법의 경우, 클라이언트와 서버 간의 통신 횟수는 적지만 서버의 처리량이 늘게 된다는 것이 단점인 것 같습니다.
두 번째 방법의 경우, 해킹을 막는 데에는 효과적이지만 레이턴시가 높고 균일하지 않으면 캐릭터의 움직임이 손상됩니다. 주고받는 메시지의 레이턴시가 어느 정도 균일하고 낮은 경우(50밀리초 이하)에 한해 채택하는 것이 일반적이라고 하네요.
또 다른 기술 중에 '일단 보여 주고 나중에 얼렁뚱땅하기' 방법도 있다고 합니다. 기획 영역과도 관련이 있는 부분이라고 하네요.
- 플레이어의 행동 명령을 서버에 전송. 동시에 행동을 연출하는 일부 모습을 클라이언트에서 즉시 시작.
- 서버에서는 받은 행동 명령을 처리. 캐릭터에 가해야 하는 행동을 클라이언트에 전송.
- 클라이언트는 메시지를 받으면 연출해야 하는 나머지 부분을 시작.
블리자드의 <디아블로3>에서 이 방법을 사용해서 플레이어 공격 처리를 한다고 하니다. 플레이어가 공격 키를 누르면 캐릭터는 일단 공격 모션을 취합니다. 서버는 공격 명령 메시지를 받아 처리하고 그 결과를 클라이언트에 보내죠. 클라이언트는 이 결과까지 받으면 공격 모션에 뒤따르는 사운드나 이펙트 연출이 발생합니다.
레이턴시가 없을 경우에는 캐릭터의 공격 모션과 동시에 이펙트가 발생합니다. 만약 레이턴시가 높다면 모션만 보이고 이펙트가 나중에 발생하게 됩니다.
이 방법에도 문제는 있지만, 그래도 캐릭터가 일단 행동을 한다는 점에 있어서 낫게 느껴질 수 있겠습니다. 공격 키를 눌렀는데로 아무것도 하지 않는 것과 일단 모션이라도 취하는 것을 비교해보면, 심리적으로 후자를 더 선호하지 않을까 싶네요.