2004년 10월 01일
Battle.net의 등장.
이런 가운데 1995년 “디아블로”라는 뛰어난 게임이 등장했다. 별도의 서버가 존재하지는 않았지만 게임을 실행한 피어가 게임 서버가 될 수 있는 방식은 매우 획기적이었다. 또한 블리자드의 배틀넷이라는 인터넷을 경유한 게임 서비스가 각광을 받아 대단한 히트를 기록했다. 현재는 소수의 인원이 서버와 클라이언트를 겸한 애플리케이션을 실행시켜 즐기는 게임의 형태를 대개 “네트워크 플레이” 혹은 “넷플”이라고 부른다. 이러한 게임과 MUG를 간단히 비교해 보자.
우선 전송되는 데이터의 용량 차이이다. MUG의 경우는 서버를 따로 두고 있으므로 좋은 환경과 빠른 전용선을 사용할 수 있어 전송되는 데이터가 다소 많아도 무리는 없다.
또한 서버는 항시 운용되고 있고 많은 사용자가 접속하므로 같은 데이터 양이라도 MUG의 서버에 유입되는 용량은 엄청나다. 반면 넷플에서는 각 피어가 하나의 서버 역할을 하므로 쓸데없이 데이터가 많이 전송되면 서버 역할을 하는 피어에 엄청난 병목을 일으켜 게임 자체가 불가능하게 된다.
아마 블리자드도 이에 대한 고민을 많이 했을 것이다. 즉 낮은 대역폭의 회선에 걸맞게 데이터를 적게 전송하는 방법이 없이는 디아블로와 같은 게임은 불가능하다. 데이터를 압축해 전송하는 방법이 있었지만 이 역시 한계가 있었고 결국 채택된 방식이 “치명적이지 않은 수준의 오차를 허용하는 것”과 “오브젝트에 대한 데이터를 각 피어가 분산 저장하는 것” 이었다. 특히 후자의 경우는 현재 군사용으로 많이 사용되는 DIS(Distributed Simulation)와 관련이 깊은데, DARPA에서 이를 연구하면서 발전된 것이 Dead Reckoning이다. CPU의 파워가 부족하다든지, 장비의 설치문제라든지, 데이터를 여러 대의 시스템이 분산해 저장해야 하는 경우는 의외로 많다. 이때 가장 문제가 되는 것은 각 시스템이 갖는 객체(Entity)들을 동기화하는 것이다. 냉전시대 군비경쟁이 심화되면서 급속히 발전한 DIS는 이렇게 피어 서버를 사용하기 때문에 데이터를 분산 저장해야 하는 시스템에 매우 이상적으로 적용될 수 있었다.
* Latency Masking
디아블로에서 서버 역할을 하는 피어가 성능이 좋지 않을 경우 데이터를 몰아넣는 것은 불합리하다고 생각할 수 있다. 만약 MUG와 같이 한 서버에 데이터가 집중되면 매번 모든 클라이언트로부터 데이터를 전송 받아야 하고 (정확한 데이터는 서버만이 갖고 있으므로) 매번 요청이 있을 때마다 전송해 주어야 한다. 이렇게 되면 서버에 엄청난 부하가 걸릴 뿐 아니라 네트워크상의 병목 현상 때문에 게임 자체가 불가능해진다. 이런 방식은 별도의 서버를 운영하며 넓은 대역폭의 전용선을 제공할 수 있는 MUG에서나 가능한 방법이다.
이를 해결하기 위해서는 각각에 데이터를 분산시켜 저장할 수밖에 없다. 물론 이중에도 게임을 만든 클라이언트 즉, 다른 클라이언트와 구분되는 게임의 호스트는 존재한다. 호스트는 서버와 다르게 넷플에서 중요한 역할을 할 것이다. 그러나 호스트는 서버처럼 모든 데이터를 갖지 않으며 자신이 소유한 데이터와 소유자가 불분명한 데이터 즉, 모든 피어가 공통적으로 사용하는 데이터만을 저장하고 관리한다(예. 스타크에서의 중립생물). 각 피어는 자신이 소유한 데이터를 가지며 이를 저장하고 관리한다. 다시 말하면 각 피어가 소유한 데이터가 가장 정확한 데이터가 되는 것이다.
이 모델에서는 자신의 데이터가 변경되면 피어는 이 변경사실을 모든 피어에게 멀티캐스트한다. 호스트 역시 똑같은 하나의 피어로 참가하므로 다른 피어에게 데이터를 전송할 의무는 없다. CPU의 부하와 네트워크의 패킷이 각 클라이언트들에 거의 공평하게 나누어지는 것이다. 이때 만약 10Mbps의 LAN상에서 플레이한다면 실제로 한대에서 플레이하는 것처럼 보일 정도로 데이터 교환이 빠르고, 서로의 입력을 교환하면 이 모델에서도 간단히 넷플이 가능하다. 그러나 보통 전화접속이나 인터넷을 통한 게임을 시도하게 되므로 크든 작든 Latency가 생기며, 이는 게임의 중대한 방해요소가 된다. 따라서 치명적인 Latency를 처리하는 기술이 필요해졌고 이를 Latency Masking이라 부르게 되었다. Dead Reckoning은 바로 이러한 Latency Masking의 대표적인 기술이다.
* Rendevouz Positioning
각각의 피어는 자신이 갖지 않은 데이터에 대한 사본을 항상 유지시킬 의무가 있다. 이를 ghost라는 표현으로 쓰자면 ghost는 Dead Reckoning을 적용해 부드러운 움직임을 보여주나 실제 PDU의 데이터와 차이를 가질 수 있다. 그러나 동기화시 PDU와 ghost의 데이터에 차이가 있다고 ghost의 데이터를 전송된 PDU의 것으로 바로 바꾸면 안 된다. 급격하게 움직이고 동기화가 늦는 경우일수록 ghost가 한 지점에서 다른 지점으로 점프하는 것처럼 보이는 현상이 많이 일어난다. 이를 저크(jerk), 혹은 지터(jitter)라고 한다. 저크를 막기 위해서 사용하는 방법은 여러 가지 있으나 Rendevouz Positioning이 가장 이해하기 쉬운 방법이다. 이는 ghost와 PDU를 당장 동기화하지 않고 다음 동기화 시간까지 값이 같아지도록 맞추는 것이다.
예를 들어 현재 ghost의 좌표와 속도가 (100, 100) (10/sec, 20/sec)이고 전송된 PDU의 값은 (120, 130) (30/sec, 10/sec), 동기화는 1초씩일 경우 당장 ghost를 PDU에 맞추면 여러분의 객체는 순식간에 가로 20, 세로 30포인트를 점프하는 것처럼 보일 것이다. Rendevouz Positioning에서는 이렇게 하지않고 먼저 PDU가 다음 동기화시에 도달할 좌표를 구한다. 좌표는 (150, 140)일 것이다. 그러면 현재 좌표인 (100, 100)에서 다음 동기화시에 이 좌표에 도달하도록 속도값을 변경해준다. 변경한 속도값은 (50/sec, 40/sec)이 된다. 결론적으로 현재 전달된 속도는 (30/sec, 10/sec)이므로 가로, 세로 속도가 상당히 늘었지만 (100, 100)에서 (150, 140)까지 점프하지 않고 부드럽게 움직이는 모습을 보여줄 수 있다. 다음 동기화시에도 역시 같은 작업이 이루어진다. 이는 간단하게 저크를 없애고 실제 객체와 ghost간의 차이를 줄일 수 있는 좋은 방법이지만 급격한 움직임은 표현되지 않고 항상 느리게 움직이는 것처럼 보인다. 하지만 duel과 같이 관성이 작용해 급가속이나 감속이 되지 않는 객체의 움직임에는 매우 좋은 효과를 줄 수 있다. 이 방법은 급격한 변화를 표현하지 못하고 속도의 변화가 크다는 점에서 개선의 여지가 있으며 이에 대한 해결방안은 뒤에서 소개하겠다.
* Collision
자신의 데이터를 다른 피어에서 나타내려면 Rendevouz Positioning으로 간단히 해결할 수 있다. 그러나 이는 전혀 문제가 되지 않는다. 네트워크 게임에서 최대 문제는 바로 Collision이다. 만약 서버에 모든 데이터가 몰려 있다면 객체끼리의 Interaction 역시 서버에서 이루어지므로 이 결과에 대해서는 이의를 제기할 수 없다(MUG의 경우). 언제나 서버에 있는 데이터가 가장 정확하기 때문이다. 그런데 만약 자신이 소유한 어떤 객체와 소유하지 않은 객체간의 상호작용이 이루어졌다고 가정해 보자(배틀넷의 경우). 자신이 소유한 객체의 상태는 자신에게 있는 데이터가 가장 정확한 것이므로 이를 가지고 작업할 수 있다. 그런데 자신이 소유하지 않은(ghost만을 가지고 있는) 객체는 현재 상태를 정확하게 판단할 수 없다.
물론 정확히 알려면 이 객체의 소유주에게 질의를 보내 상태를 전달받으면 되지만, 문제는 데이터가 전달되는 동안 늦어져 이미 정확한 데이터가 아니다. 보여주는 정도라면 latency를 측정하고 부정확하나마 이 값을 더하여 예측치를 계산할 수 있지만 질롯의 움직임이나 시즈의 무빙샷 등 정확한 조작에 의해 성패가 좌우되는 경우는 latency에 의해 결과가 달라진다. 결국 이 정도의 차이는 무시할 수 있는 판정 시스템을 만들어야 하는데, 이 역시 경우에 따라 크게 달라지므로 딜레마가 아닐 수 없다. 레인보우 6나 퀘이크 등 순간에 승패가 결정되는 게임을 많이 해본 사람은 서버에서 자신의 컴퓨터까지의 latency도 게임 결과에 중대한 영향을 미치는 요소라는 사실을 알 것이다. 이런 종류의 넷플에서 대개 서버쪽에서 플레이하는 사람 혹은 ping이 낮은 사람이 유리해지는 것은 어쩔 수 없는 부분이다. 하지만 최대한 공평한 환경을 만들려고 노력은 해야되지 않을까? 이런 불리한 점을 어떻게 개선할 수 있을까 ?
네트워크 게임에서는 기본적으로는 플레이하는 상대끼리 계속 자신이 갖고 있는 PDU에 대한 정보를 전달하고 다른 클라이언트의 정보를 전달받는다. 문제는 전달받은 정보가 어떤 한 시점에 정확하다고 확신할 수 있는가이다. 어떤 이벤트가 발생해 PDU의 상태가 바뀌면 해당 PDU를 소유한 클라이언트는 최대한 빨리 정보를 다른 클라이언트들에게 보낸다.
* 불확정성 원리 - 정확한 값은 알 수 없다
첫 번째, 지구에서만 통신하는 경우는 로컬 랜으로 연결해서 게임을 하는 경우에 비견할 수 있다. 이때 지연은 특별한 문제가 없는 한 10ms 이내이며 네트워크 게임도 초능력자가 아닌 보통 인간이 플레이하는 이상, 0.01초의 차이는 무의미하다고 단정해도 무리가 없다. 이때의 지연은 완전 무시된다.
두 번째, 태양과 지구가 교신하는 경우는 공중망(PSTN)을 거쳐 서로 접속한 상황에 비유된다. 이 경우 지연은 100ms 이상이며 동체 시력이 매우 좋은 사람은 미세한 차이점을 발견할 수 있을 정도로 증가한다. 만약 선로의 상태가 나쁘거나 별도의 서버를 경유해 접속한다면 지연은 400~500ms까지 증가한다. 이때는 필연적으로 실제 PDU의 데이터와 ghost 사이에 오차가 생기며 서로의 데이터에 차이가 없도록 여러 가지 예측시스템을 사용하게 된다. 그러나 오차는 피할 수 없다. 인터넷의 표준 프로토콜인 TCP/IP의 기본 특성상 라우팅을 많이 하고 여러 곳을 거치면 지연이 늘어나는 것은 당연하다. 결국 이 경우에 가장 유효한 것은 다소의 오차는 무시하고 각 클라이언트가 항상 맞는 데이터를 가지고 있다고 생각하는 것이다.
앞에서도 언급했듯이 태양에 있는 사람이 현재 지구의 상태를 정확하게 알 수 있는 방법은 없다. 최소한 8분은 기다려야 그 사람의 얘기를 들을 수 있다. 하지만 그래도 상대방이 내 얘기를 듣고 있다고 생각하고 계속 말을 하는 것이 가장 경제적인 방법인 것처럼, 네트워크 플레이어에서도 자신이 가장 올바른 데이터를 가지고 있다고 판단하는 것이 가장 좋은 방법이다.
* 조정
latency masking하는 다른 방법을 생각해 보자. 스타크래프트에서는 자신의 유닛이 있는 곳만 fog가 걷히고 그 구역의 다른 유닛이나 지형을 볼 수 있도록 되어 있다. 만약 유닛들이 이렇게 각 클라이언트에서 서로 움직이고 있으나 거리가 멀어 상호작용의 가능성이 매우 낮다고 가정한다면, 이 유닛들의 위치를 정확하게 계산하기 위해서(사실은 이렇게 하는 것이 가장 좋지만) 동기화하는 부담을 질 필요는 없다. 왜냐하면 현재 유닛들은 너무 멀리 떨어져 있고 서로 간섭하지 않을 것이라고 판단되기 때문이다.
정확한 위치가 필요한 것은 서로간의 상호작용이 생겨서 판정이 요구될 때이지 이렇게 멀리 있을 때가 아니다. 이 경우는 어느 정도 제법 큰 오차까지도 허용될 수 있다. 동기화는 아주 러프하게 해도 좋으며 다만 저크가 발생하지 않도록 신경은 써야 한다. 이런 것을 Dead Reckoning과 같은 정확한 조정 (hard reconciliation)에 대해 대략적인 조정(soft reconciliation)이라 할 수 있다. 스타크래프트에서는 fog로 가려진 적 유닛은 그리지 않음으로써 네트워크에 대한 부하를 많이 줄일 수 있었을 것이다. 만약 서로의 유닛이 가까워져서 상호작용이 일어난다면 이때는 정확한 위치가 필요하다. 이때의 상호작용은 반드시 직접적인 공격이나 원조 등이 아니더라도 가까운 적의 위치는 눈으로 보고 공격하게 되므로 거리가 어느 정도 수준이 되면 정확하게 동기화하기 시작해야 한다. 객체를 부드럽게 움직이게 하기 위해서는 Dead Reckoning과 Rendevouz Positioning을 사용할 수 있지만 오차가 한계보다 커진 경우는 모든 클라이언트에게 메시지를 보내어 일시적으로 게임을 중단하고 정확한 위치로 이동시킨 후에 다시 모든 클라이언트에게 메시지를 보내 게임을 재 시작할 수 있다.
스타크래프트에서도 백병전시 유닛이 한꺼번에 많이 움직이면 게임이 멈칫멈칫하는 상황을 볼 수 있는데, 이 역시 동기화의 문제가 작용하고 있기 때문일 것이다. 어쨌든 많은 객체들을 한꺼번에 동기화 하는것은 어렵기 때문에 대략적인 중재는 여러 게임에서 빠르게 latency masking하는 방법으로 사용될 수 있다.
원본출처 - 모름 -_-;
요기까지만 읽고 이해해보도록 노력해보자;
우선 전송되는 데이터의 용량 차이이다. MUG의 경우는 서버를 따로 두고 있으므로 좋은 환경과 빠른 전용선을 사용할 수 있어 전송되는 데이터가 다소 많아도 무리는 없다.
또한 서버는 항시 운용되고 있고 많은 사용자가 접속하므로 같은 데이터 양이라도 MUG의 서버에 유입되는 용량은 엄청나다. 반면 넷플에서는 각 피어가 하나의 서버 역할을 하므로 쓸데없이 데이터가 많이 전송되면 서버 역할을 하는 피어에 엄청난 병목을 일으켜 게임 자체가 불가능하게 된다.
아마 블리자드도 이에 대한 고민을 많이 했을 것이다. 즉 낮은 대역폭의 회선에 걸맞게 데이터를 적게 전송하는 방법이 없이는 디아블로와 같은 게임은 불가능하다. 데이터를 압축해 전송하는 방법이 있었지만 이 역시 한계가 있었고 결국 채택된 방식이 “치명적이지 않은 수준의 오차를 허용하는 것”과 “오브젝트에 대한 데이터를 각 피어가 분산 저장하는 것” 이었다. 특히 후자의 경우는 현재 군사용으로 많이 사용되는 DIS(Distributed Simulation)와 관련이 깊은데, DARPA에서 이를 연구하면서 발전된 것이 Dead Reckoning이다. CPU의 파워가 부족하다든지, 장비의 설치문제라든지, 데이터를 여러 대의 시스템이 분산해 저장해야 하는 경우는 의외로 많다. 이때 가장 문제가 되는 것은 각 시스템이 갖는 객체(Entity)들을 동기화하는 것이다. 냉전시대 군비경쟁이 심화되면서 급속히 발전한 DIS는 이렇게 피어 서버를 사용하기 때문에 데이터를 분산 저장해야 하는 시스템에 매우 이상적으로 적용될 수 있었다.
* Latency Masking
디아블로에서 서버 역할을 하는 피어가 성능이 좋지 않을 경우 데이터를 몰아넣는 것은 불합리하다고 생각할 수 있다. 만약 MUG와 같이 한 서버에 데이터가 집중되면 매번 모든 클라이언트로부터 데이터를 전송 받아야 하고 (정확한 데이터는 서버만이 갖고 있으므로) 매번 요청이 있을 때마다 전송해 주어야 한다. 이렇게 되면 서버에 엄청난 부하가 걸릴 뿐 아니라 네트워크상의 병목 현상 때문에 게임 자체가 불가능해진다. 이런 방식은 별도의 서버를 운영하며 넓은 대역폭의 전용선을 제공할 수 있는 MUG에서나 가능한 방법이다.
이를 해결하기 위해서는 각각에 데이터를 분산시켜 저장할 수밖에 없다. 물론 이중에도 게임을 만든 클라이언트 즉, 다른 클라이언트와 구분되는 게임의 호스트는 존재한다. 호스트는 서버와 다르게 넷플에서 중요한 역할을 할 것이다. 그러나 호스트는 서버처럼 모든 데이터를 갖지 않으며 자신이 소유한 데이터와 소유자가 불분명한 데이터 즉, 모든 피어가 공통적으로 사용하는 데이터만을 저장하고 관리한다(예. 스타크에서의 중립생물). 각 피어는 자신이 소유한 데이터를 가지며 이를 저장하고 관리한다. 다시 말하면 각 피어가 소유한 데이터가 가장 정확한 데이터가 되는 것이다.
이 모델에서는 자신의 데이터가 변경되면 피어는 이 변경사실을 모든 피어에게 멀티캐스트한다. 호스트 역시 똑같은 하나의 피어로 참가하므로 다른 피어에게 데이터를 전송할 의무는 없다. CPU의 부하와 네트워크의 패킷이 각 클라이언트들에 거의 공평하게 나누어지는 것이다. 이때 만약 10Mbps의 LAN상에서 플레이한다면 실제로 한대에서 플레이하는 것처럼 보일 정도로 데이터 교환이 빠르고, 서로의 입력을 교환하면 이 모델에서도 간단히 넷플이 가능하다. 그러나 보통 전화접속이나 인터넷을 통한 게임을 시도하게 되므로 크든 작든 Latency가 생기며, 이는 게임의 중대한 방해요소가 된다. 따라서 치명적인 Latency를 처리하는 기술이 필요해졌고 이를 Latency Masking이라 부르게 되었다. Dead Reckoning은 바로 이러한 Latency Masking의 대표적인 기술이다.
* Rendevouz Positioning
각각의 피어는 자신이 갖지 않은 데이터에 대한 사본을 항상 유지시킬 의무가 있다. 이를 ghost라는 표현으로 쓰자면 ghost는 Dead Reckoning을 적용해 부드러운 움직임을 보여주나 실제 PDU의 데이터와 차이를 가질 수 있다. 그러나 동기화시 PDU와 ghost의 데이터에 차이가 있다고 ghost의 데이터를 전송된 PDU의 것으로 바로 바꾸면 안 된다. 급격하게 움직이고 동기화가 늦는 경우일수록 ghost가 한 지점에서 다른 지점으로 점프하는 것처럼 보이는 현상이 많이 일어난다. 이를 저크(jerk), 혹은 지터(jitter)라고 한다. 저크를 막기 위해서 사용하는 방법은 여러 가지 있으나 Rendevouz Positioning이 가장 이해하기 쉬운 방법이다. 이는 ghost와 PDU를 당장 동기화하지 않고 다음 동기화 시간까지 값이 같아지도록 맞추는 것이다.
예를 들어 현재 ghost의 좌표와 속도가 (100, 100) (10/sec, 20/sec)이고 전송된 PDU의 값은 (120, 130) (30/sec, 10/sec), 동기화는 1초씩일 경우 당장 ghost를 PDU에 맞추면 여러분의 객체는 순식간에 가로 20, 세로 30포인트를 점프하는 것처럼 보일 것이다. Rendevouz Positioning에서는 이렇게 하지않고 먼저 PDU가 다음 동기화시에 도달할 좌표를 구한다. 좌표는 (150, 140)일 것이다. 그러면 현재 좌표인 (100, 100)에서 다음 동기화시에 이 좌표에 도달하도록 속도값을 변경해준다. 변경한 속도값은 (50/sec, 40/sec)이 된다. 결론적으로 현재 전달된 속도는 (30/sec, 10/sec)이므로 가로, 세로 속도가 상당히 늘었지만 (100, 100)에서 (150, 140)까지 점프하지 않고 부드럽게 움직이는 모습을 보여줄 수 있다. 다음 동기화시에도 역시 같은 작업이 이루어진다. 이는 간단하게 저크를 없애고 실제 객체와 ghost간의 차이를 줄일 수 있는 좋은 방법이지만 급격한 움직임은 표현되지 않고 항상 느리게 움직이는 것처럼 보인다. 하지만 duel과 같이 관성이 작용해 급가속이나 감속이 되지 않는 객체의 움직임에는 매우 좋은 효과를 줄 수 있다. 이 방법은 급격한 변화를 표현하지 못하고 속도의 변화가 크다는 점에서 개선의 여지가 있으며 이에 대한 해결방안은 뒤에서 소개하겠다.
* Collision
자신의 데이터를 다른 피어에서 나타내려면 Rendevouz Positioning으로 간단히 해결할 수 있다. 그러나 이는 전혀 문제가 되지 않는다. 네트워크 게임에서 최대 문제는 바로 Collision이다. 만약 서버에 모든 데이터가 몰려 있다면 객체끼리의 Interaction 역시 서버에서 이루어지므로 이 결과에 대해서는 이의를 제기할 수 없다(MUG의 경우). 언제나 서버에 있는 데이터가 가장 정확하기 때문이다. 그런데 만약 자신이 소유한 어떤 객체와 소유하지 않은 객체간의 상호작용이 이루어졌다고 가정해 보자(배틀넷의 경우). 자신이 소유한 객체의 상태는 자신에게 있는 데이터가 가장 정확한 것이므로 이를 가지고 작업할 수 있다. 그런데 자신이 소유하지 않은(ghost만을 가지고 있는) 객체는 현재 상태를 정확하게 판단할 수 없다.
물론 정확히 알려면 이 객체의 소유주에게 질의를 보내 상태를 전달받으면 되지만, 문제는 데이터가 전달되는 동안 늦어져 이미 정확한 데이터가 아니다. 보여주는 정도라면 latency를 측정하고 부정확하나마 이 값을 더하여 예측치를 계산할 수 있지만 질롯의 움직임이나 시즈의 무빙샷 등 정확한 조작에 의해 성패가 좌우되는 경우는 latency에 의해 결과가 달라진다. 결국 이 정도의 차이는 무시할 수 있는 판정 시스템을 만들어야 하는데, 이 역시 경우에 따라 크게 달라지므로 딜레마가 아닐 수 없다. 레인보우 6나 퀘이크 등 순간에 승패가 결정되는 게임을 많이 해본 사람은 서버에서 자신의 컴퓨터까지의 latency도 게임 결과에 중대한 영향을 미치는 요소라는 사실을 알 것이다. 이런 종류의 넷플에서 대개 서버쪽에서 플레이하는 사람 혹은 ping이 낮은 사람이 유리해지는 것은 어쩔 수 없는 부분이다. 하지만 최대한 공평한 환경을 만들려고 노력은 해야되지 않을까? 이런 불리한 점을 어떻게 개선할 수 있을까 ?
네트워크 게임에서는 기본적으로는 플레이하는 상대끼리 계속 자신이 갖고 있는 PDU에 대한 정보를 전달하고 다른 클라이언트의 정보를 전달받는다. 문제는 전달받은 정보가 어떤 한 시점에 정확하다고 확신할 수 있는가이다. 어떤 이벤트가 발생해 PDU의 상태가 바뀌면 해당 PDU를 소유한 클라이언트는 최대한 빨리 정보를 다른 클라이언트들에게 보낸다.
* 불확정성 원리 - 정확한 값은 알 수 없다
첫 번째, 지구에서만 통신하는 경우는 로컬 랜으로 연결해서 게임을 하는 경우에 비견할 수 있다. 이때 지연은 특별한 문제가 없는 한 10ms 이내이며 네트워크 게임도 초능력자가 아닌 보통 인간이 플레이하는 이상, 0.01초의 차이는 무의미하다고 단정해도 무리가 없다. 이때의 지연은 완전 무시된다.
두 번째, 태양과 지구가 교신하는 경우는 공중망(PSTN)을 거쳐 서로 접속한 상황에 비유된다. 이 경우 지연은 100ms 이상이며 동체 시력이 매우 좋은 사람은 미세한 차이점을 발견할 수 있을 정도로 증가한다. 만약 선로의 상태가 나쁘거나 별도의 서버를 경유해 접속한다면 지연은 400~500ms까지 증가한다. 이때는 필연적으로 실제 PDU의 데이터와 ghost 사이에 오차가 생기며 서로의 데이터에 차이가 없도록 여러 가지 예측시스템을 사용하게 된다. 그러나 오차는 피할 수 없다. 인터넷의 표준 프로토콜인 TCP/IP의 기본 특성상 라우팅을 많이 하고 여러 곳을 거치면 지연이 늘어나는 것은 당연하다. 결국 이 경우에 가장 유효한 것은 다소의 오차는 무시하고 각 클라이언트가 항상 맞는 데이터를 가지고 있다고 생각하는 것이다.
앞에서도 언급했듯이 태양에 있는 사람이 현재 지구의 상태를 정확하게 알 수 있는 방법은 없다. 최소한 8분은 기다려야 그 사람의 얘기를 들을 수 있다. 하지만 그래도 상대방이 내 얘기를 듣고 있다고 생각하고 계속 말을 하는 것이 가장 경제적인 방법인 것처럼, 네트워크 플레이어에서도 자신이 가장 올바른 데이터를 가지고 있다고 판단하는 것이 가장 좋은 방법이다.
* 조정
latency masking하는 다른 방법을 생각해 보자. 스타크래프트에서는 자신의 유닛이 있는 곳만 fog가 걷히고 그 구역의 다른 유닛이나 지형을 볼 수 있도록 되어 있다. 만약 유닛들이 이렇게 각 클라이언트에서 서로 움직이고 있으나 거리가 멀어 상호작용의 가능성이 매우 낮다고 가정한다면, 이 유닛들의 위치를 정확하게 계산하기 위해서(사실은 이렇게 하는 것이 가장 좋지만) 동기화하는 부담을 질 필요는 없다. 왜냐하면 현재 유닛들은 너무 멀리 떨어져 있고 서로 간섭하지 않을 것이라고 판단되기 때문이다.
정확한 위치가 필요한 것은 서로간의 상호작용이 생겨서 판정이 요구될 때이지 이렇게 멀리 있을 때가 아니다. 이 경우는 어느 정도 제법 큰 오차까지도 허용될 수 있다. 동기화는 아주 러프하게 해도 좋으며 다만 저크가 발생하지 않도록 신경은 써야 한다. 이런 것을 Dead Reckoning과 같은 정확한 조정 (hard reconciliation)에 대해 대략적인 조정(soft reconciliation)이라 할 수 있다. 스타크래프트에서는 fog로 가려진 적 유닛은 그리지 않음으로써 네트워크에 대한 부하를 많이 줄일 수 있었을 것이다. 만약 서로의 유닛이 가까워져서 상호작용이 일어난다면 이때는 정확한 위치가 필요하다. 이때의 상호작용은 반드시 직접적인 공격이나 원조 등이 아니더라도 가까운 적의 위치는 눈으로 보고 공격하게 되므로 거리가 어느 정도 수준이 되면 정확하게 동기화하기 시작해야 한다. 객체를 부드럽게 움직이게 하기 위해서는 Dead Reckoning과 Rendevouz Positioning을 사용할 수 있지만 오차가 한계보다 커진 경우는 모든 클라이언트에게 메시지를 보내어 일시적으로 게임을 중단하고 정확한 위치로 이동시킨 후에 다시 모든 클라이언트에게 메시지를 보내 게임을 재 시작할 수 있다.
스타크래프트에서도 백병전시 유닛이 한꺼번에 많이 움직이면 게임이 멈칫멈칫하는 상황을 볼 수 있는데, 이 역시 동기화의 문제가 작용하고 있기 때문일 것이다. 어쨌든 많은 객체들을 한꺼번에 동기화 하는것은 어렵기 때문에 대략적인 중재는 여러 게임에서 빠르게 latency masking하는 방법으로 사용될 수 있다.
원본출처 - 모름 -_-;
요기까지만 읽고 이해해보도록 노력해보자;
# by | 2004/10/01 22:43 | STUDY



