네트웍 게임을 개발할때 부딪히는 물리적 한계가 두가지 있습니다.
Bandwidth 와 Latency
Bandwidth의 한계로 신호를 많이 보낼 수 없는 것 뿐만아니라, 자주 보낼 수도 없습니다.
기본적으로 리얼타임게임에서는 매 프레임 마다 상태 정보를 갱신해야 합니다.
만약 30FPS 정도의 갱신률을 가진 게임을 네트웍 플레이로 만든다면 1초에 30번 플레이어의 상태정보를 전송해야합니다.
전송만 하는게 아니라.. 다른 플레이어들의 정보도 전송 받아야 하지요.
이렇게 하면 아무리 넉넉한 Bandwidth를 가졌다 해도 플레이어의 숫자가 늘어남에 따라 금방 Bandwidth가 차 버립니다.
네명정도를 최대 플레이어 수로 제한 한다면 모르지만 제한된 Bandwidth 내에서 많은 수의 동시 플레이어를 지원하려면 우선 매프레임 마다 정보를 보내는 걸 포기해야합니다.
그런데 게임은 기본적으로 매프레임 마다 전체 상태를 갱신해야 하는데, 이걸 매프레임 마다 보내지 않는 다면 정보가 전달되지 않는 프레임 동안에는 어떻게 하지요??
이때 사용되는 기법이 바로 Dead Reckoning 입니다.
Dead라는 말은 신호를 받지 못하고 있는 상태를 말합니다.
즉 신호가 전달 되지 않으니 신호가 죽은셈이죠.
Reckoning은 추산하다는 뜻으로 신호가 없는 동안에도 추측으로 계산한다는 겁니다.
다시말해서 신호가 없는 동안에도 이전에 받았던 신호를 바탕으로 추산해서 상태정보를 갱신한다는 겁니다.
Dead Reckoning은 주로 플레이어의 위치정보를 갱신하는데 사용됩니다.
물론 데드 레커닝 없이 매 프레임마다 플레이어의 위치값을 주고 받을 수 있으면 좋지만.. 제한된 Bandwidth 때문에 그렇게 할 수가 없지요.
그렇다면 플레이어의 정보를 전달할때 현재의 위치 값 뿐만아니라 위치 값이 전달되지 않는 동안에도 위치 값을 추측하는데 데 필요한 부가적인 정보를 같이 보내야 합니다.
이런 정보는 보통 속도나 가속도 값이 됩니다.
물론 속도만 보낼 수도 있고, 가속도 까지 보낼 수도 있습니다.
경우에 따라서는 위치값만 보내더라도 이전 위치 값을 기초로 속도를 구해서 처리 할 수 도 있습니다.
고등학교때 배운 물리공식을 상기하면..
X = X0 + V * t + 1/2 * A * t * t
(X :위치, V :속도, A :가속도, t :시간)
최근에 받은 위치값과 속도, 가속도를 이용해서 쉽게 이후 시간의 위치를 추측할 수 있죠.
물론 이 값은 어디까지나 추측일 뿐이고 신호가 없는 동안에 일반적으로 운동상태가 바뀌어졌겠죠.
이럴 경우 다음 신호가 전달 되어 왔을때 추측한 값이랑 비교해보면 서로 다르겠지요.
차이가 별로 없다면 추측한 값은 버리고 새로 받은 위치정보로 갱신해버리면 족하지만... 그렇지 않은 경우 새로받은 위치정보로 갱신해버리면 워프하듯이 갑자기 위치가 바뀌어 버리고 어색하게 보일 겁니다.
우리가 네트웍 게임을 하다보면 흔히 목격하는 광경이죠.
이런 경우 바로 갱신하지 말고 새로받은 위치 정보로 새로운 추측을 해서 현재의 추측값에서 새로운 추측값으로 부드럽게 연결할 수도 있습니다.
이러면 겉보기 결과는 좀 더 나아지겠지만 공짜로 되는 건 아니지요.
부가적인 계산이 더 추가되겠지요.
CPU타임이 남아 돈다면 모르지만 그렇지 않다면 그냥 워프되는걸 감수 해야지요.
이처럼 신호가 없는 동안에 간단한 물리공식을 이용해서 위치값을 추정 할 수는 있는데..
그러면 다음 문제는 신호를 얼만큼 덜 보낼 것인가이죠.
예컨데 30FPS 의 게임의 경우 매 5프레임 마다 보낼 수도 있고 10프레임 마다 보낼 수도 있고, 15프레임 마다 보낼 수도 있고, 혹은 1초에 한번만 보낼 수도 있지요.
이건 사실 정답이 없지요.
게임이나 네트웍 등의 상태에 따라 다르겠죠.
일률적으로 몇 프레임 마다 보내는 방법 외에.. 필요할때만 보내는 방법도 생각할 수 있습니다.
이런 경우는 서버에서도 데드 레커닝을 해야하지만..
각 클라이언트에서 날아오는 플레이어 위치정보를 그때 그때 다른 클라이언트로 전달하는 대신 서버도 나름대로 클라이언트와 똑 같은 방식으로 데드래커닝을 하고 있다가 받은 정보가 추측한 값이랑 적정한 문턱값 이상으로 차이가 발생했을때만 다른 클라이언트에 보내는 겁니다.
실제적인 적용에 있어서는 여러가지 다양한 방법을 생각해 볼 수 있겠지요.
다음의 문제는 latency가 되는데 여태까지의 논의는 어디까지나 latency 가 없다는 전제하에서 그런 것이고, latency까지 고려한다면 문제는 좀 더 복잡해 집니다.
보통 실용적인 견지에서 동일한 LAN상에서라면 latency를 무시해도 무방하지만 인터넷을 통해서 접속을 하게 되면 이제는 latency를 무시 할 수 없게 됩니다.
미국처럼 대양을 건너 다른 대륙까지 연결되는 경우가 아닌 국내에서 서로 접속한다고 해도 latency는 심각하게 고려해야 합니다.
물론 바둑이나 장기처럼 Turn 방식으로 진행되는 게임들에는 전혀 상관 없는 얘기 것지만...^^;
latency 문제는 다음에...
네트웍 게임을 개발하면서 많은 경우 간과 되고 있는 부분이 Latency를 어떻게 처리 할 것인가 입니다.
대개 Bandwidth(대역폭)에 대해서는 인지하고 있는데...
Lantency의 경우는 근본적인 원인을 알지못하고, Modem 이라서 느리다는 식으로 이해하는게 보통이죠.Lantency는 우리말로 번역한다면 신호지연 이라고 할 수 있습니다.
네트웍의 한 노드에서 다른 노드로 신호가 전달되는데 시간지연이 생긴다고 이해하시면됩니다.구체적인 데이타의 형태가 어떠하던 결국 네트웍을 타고 전달되는 신호는 전자기신호입니다.
단순히 전기신호일 수도 있고, 광케이블인 경우는 빛 신호가 될것이고, 인공위성이라면 전자기파 신호이겠죠.
빛도 전자기파의 한종류이므로 결국은 모두 전자기 신호이죠.그런데 아인슈타인의 특수상대성이론에 의하면 물리적으로 가장 빠른 속도는 빛의 속도입니다.
정보의 전달도 마찬가지로 빛의 속도가 최대치입니다.
이보다 더 빨리 전달될 수는 없습니다.
(적어도 아인슈타인의 상대성이론을 능가하는 이론이 나오기 까지는...)일반적인 네트웍 어플리케이션에서는 이러한 정보전달 속도의 한계가 전혀 문제 될 게 없습니다.
주로 대역폭이 문제가 되지요.
하지만 리얼타임으로 상호작용해야 하는 게임의 경우는 중요한 문제가 됩니다.
혹자들은 네트웍상에서 정보는 결국 전자기신호로 전달되므로 빛의 속도로 전달될 것이고, 빛의 속도는 엄청빠르기 때문에 문제될게 없다고 생각할 수도 있습니다.하지만 바로 이 빛의 속도라는 한계가 문제가 됩니다.
초속 3십만킬로미터 라는 어마어마한 빠르기의 빛의 속도라고 해도 리얼타임 게임을 하기에는 느립니다.같은 게임방내에서 랜으로 접속된 컴퓨터 들 사이라면 무시해도 되지만 인터넷을 통 해 미국에 있는 컴퓨터와 통신을 한다면 문제가 됩니다.
간단하게 계산을 해보지요.
흔히들 알고 있기로 빛이 1초에 지구를 7바퀴 반을 돌 정도의 속도라고 알고 있습니다.
계산을 편하게 하기 위해서 이것보다는 조금 빠른 1초에 열바퀴도는 속도라고 합시다.
그렇다면 지구를 한바퀴도는데는 약 1/10초가 걸립니다.
그러니까 100밀리세컨드죠.
미국이라면 우리나라를 기준으로 대충 지구 반대편에 있으므로 반바퀴 정도라고 보면 됩니다.
그러면 미국까지 가는데는 대략 50밀리세컨드가 소요됩니다.
1/20초이죠.게임 프로그램은 보통 프레임 단위로 모든 걸 처리하므로 FPS가 30인 게임이 있다면 1/30초 안에 모든 작업을 완료해야 합니다.
그런데 미국까지 신호가 가는데만도 1/20초가 걸리니 게임프로그램이 한 프레임을 갱신하는데 주어진 시간보다 더 느립니다.흔히들 네트웍 게임을 하면 Ping 이니 lag이니 해서 Ping값이 높은 모뎀은 나가라고 들 하지요.
하지만 제아무리 기가급의 초초고속 인터넷망에 물려있다해도 물리적인 제한을 넘을 수는 없습니다.
미국까지 ping하면 패킷이 미국까지 갔다 와야하므로 최소한 1/10초는 걸립니다.
흔히들 대역폭이 커다는 걸 네트웍의 속도가 빠른 걸로 표현하니까 신호가 전달되는데 걸리는 시간이 빠른 것과 혼돈을 하는데, 대역폭은 어디까지나 단위시간당 전달되는 데이타의 양이지 결코 신호가 전달되는 속도를 말하는게 아닙니다.물론 지금까지 따져본 것은 신호전달의 물리적 한계인 빛의 속도만 고려한 겁니다.
하지만 인터넷 상에서 실제로 신호가 전달되려면 여러개의 라우터를 거쳐서 지정된 주소의 컴퓨터로 전달됩니다.
라우터가 신호를 받으면 즉시 전달하는게 아니라.. 버퍼에 대기시켰다가 어디로 가는 신호인지 구분해서 보내게 되므로 라우터가 신호를 처리하는데 걸리는 시간까지 포함시켜야지요.
세밀하게 따진다면 컴퓨터에 달린 네트웍카드에서 부터 벌써 하드웨어적인 지연이 생기죠.
프로그램이 데이타전송을 네트웍카드에 요청하면 즉시 신호가 전달되는게 아니라 네트웍 카드내의 버퍼에 잠시라도 대기했다가 라인이 비면 보내집니다.이런식으로 따지면 신호가 미국까지 가는데 더 많은 시간이 걸립니다.
실제로 미국에있는 서버를 선택해서 Ping을 때려보면 알 수 있습니다.
절대로 100밀리세컨드 이하로는 나오지 않습니다.
혹시라도 나오면 노벨물리학상을 탈 수 있을지도..
신호가 빛보다 빨리 전달되는 걸 발견했으니.. 대단한 과학적 발견입니다.^^;결론적으로 이러한 네트웍의 latency 는 결코 줄일 수 없는 물리적인 한계입니다.
그래서 인터넷상에서 이루어지는 게임의 경우 이러한 latency를 어떻게 잘 처리하는 냐가 중요한 문제가 됩니다.
더군다나 이러한 latency가 물리적인 신호전달속도에만 의해서 발생하는게 아니라 라우터를 거치면서도 발생하기 때문에.. 값이 고정되어 있지도 않습니다.그러니까 퀘이크나 언리얼 같은 게임은 3차원 엔진으로만 대단한게 아니라.. 대역폭은 제껴놓고라도 lantency를 극복하고 인터넷상에서 네트웍 플레이가 가능하게 한 것만으로도 대단한 겁니다.
< ps >
latency 를 극복한다는 건 latency를 없앤다는 뜻이 아니라....
(이건 결코 없앨수가 없지요. 빛보다 빠를 수는 없으니..)
latency가 존재함에도 불구하고 게임 플레이가 가능하게 한다는 뜻이죠...
물론 ping값이 300ms 를 넘어가기 시작하면 백약이 무효이긴 하지만....
실용적인 견지에서 300ms 이하에서는 latency를 잘 감추어서 플레이하는 플레이어들은 눈치 못채게 해야지요..
이게 결코 쉬운게 아니라는 거지요..
사실 150ms가 넘어가면 플레이어가 눈치 못채게 하기는 정말 힘듭니다.
'Programming > Network' 카테고리의 다른 글
DNS(도메인 네임 서버) 초기화 하는 방법 (0) | 2015.02.28 |
---|---|
레지스트리의 MaxUserPort 수정 (0) | 2015.02.07 |
NAT (Network Address Translation) (0) | 2015.02.07 |
공인 IP / 사설 IP (0) | 2015.02.07 |
"온라인 게임서버 프로그래밍 벤치마크" 초간단 정리 (0) | 2015.02.07 |