게임 동기화 모델의 고민 흔적들 :: 게임제작[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

게임제작
[1]
등록일:2019-12-27 10:51:54 (0%)
작성자:
제목:게임 동기화 모델의 고민 흔적들

출처 : https://yakolla.tistory.com/62


동기화 모델을 구현하기에 앞서 이런저런 고민 했던 것인데, 도움이 될까 하고 정리해 본다.


기본 정의

게임 오브젝트의 상태를 동기화시킨다.

말이 어려울 수도 쉬울수도 있지만, 살펴보자.


게임 오브젝트는 게임 세계에 존재하는 모든 것으로 보면 된다.

예) 캐릭터, 몹, 아이템 등


상태란 게임 세계에서 발생하는 이동, 공격등의 명령으로 게임 오브젝트의 속성 변화를 나타냄. 

예) 이동이라면, x,y의 값이 변경

     공격이라면, hp의 값이 변경


동기화란 Peer간에는 네트워크 지연, 하드웨어의 스펙 차이로인해 시간 차이가 발생하는데 이 시간차를 줄이는 방법이다.


대표적인 동기화 모델

첫 번째는 클라이언트끼리 동기화를 맞춘다.

스타크래프트가 이에 해당하며, 클라이언트 중 가장 느린 클라이언트에 시간이 맞춰진다.

상태정보의 틀어짐은 없지만, 해킹에 취약하다. 

또한, 느린 클라이언트에 맞춰지니 모두가 느려져 사용자들에게 짜증을 줄 수 있다.

구현이 상대적으로 단순하고 쉽다.


둘 째는, 서버와 동기화를 맞춘다.

LOL이 이에 해당하며, 클라이언트가 느리면 느린만큼 손해를 갖는 구조이고, 

상태정보의 틀어짐이 있어 예측과 보정을 해야 한다.

서버의 허락을 받고 명령이 수락되므로 해킹에 강하지만,

허락 받아야 하므로 반응속도가 떨어진다.

또한, 타 클라이언트가 느려진다고 모두가 느려지진 않지만, 서버가 느려지면 모두가 느려진다.


마지막으로 클라이언트가 먼저 계산하고, 서버와 오차를 보정해 나가며 동기화를 맞춘다.

FPS와 디아블로가 이에 해당하며, 빠른 반응성이 필요할 때 사용한다.

상태정보의 틀어짐이 있어 예측과 보정을 해야 한다.


첫 번째 방법이었던 클라이언트끼리의 동기화는 나름 단순하다. 일명 Lock step으로 구현하면 된다.

여기서는 서버와 동기화를 맞추는 모델에 대해서 생각해 보겠다.


도표에서 사용한 용어 정의

P1과 P2는 서로 다른 Peer이며.

P1와 P2는 각 각 200ms과 400ms ping을 갖는다.

S는 Server이며, Tick 100ms(FPS=10)의 프레임 간격을 갖는다.



고려할 갖 가지 상황

서버의 상태정보와 피어의 명령 전달은 ping 시간 만큼 걸린다.

서버 허락을 받아야 하는 구조.

P1의 S.T1 시점에 좌표 2,0으로 이동명령을  내리고 서버의 허락을 기다린다. 

S의 S.T3에 P1의 명령이 도착하여 허락을 받게된 후, P1의 이동을 시작한다. 


동시에 P2의 S.T1 시점에 P1 위치 0,0을 보고 창을 던지는 명령을 내리고 서버의 허락을 기다린다.

S의 S.T5에 P2의 명령이 도착하여 허락을 받게된 후, P2역시 창을 던지기 시작한다.


이 구조는 각 peer간에 처리되는 내용은 동일하지만, 과거 상태를 보며 행동하기 때문에. 느린 만큼 손해를 본다. 

즉, P1와 P2 각 각의 S.T1 시점에 행위를 하였지만, 

P1의 ping이 빠르기 때문에, P2보다는 기민하게 움직일 수 있다.

이에 비해 P2는 둔하기 때문에, P1을 창으로 맞추기가 어려워진다.


손해를 줄이기 위해 어느 정도의 과거까지 게임 진행에 무리가 없을지

다시 말해, 허용하는 ping 값을 정한다.





서버 허락없이 클라이언트에서 명령을 먼저 처리하고 오차를 보간하는 구조

P1의 S.T1 시점에 좌표 2,0으로 이동명령을  내리고 서버 허락없이 이동하기 시작한다.

S의 S.T3에 P1 명령이 도착할 때에는 지연시간을 고려해 보간한다.


P2의 S.T1 시점에 P1 위치 0,0을 보고 창을 던지는 명령을 내리고 서버 허락없이 창을 던지기 시작한다.

S의 S.T5에 처리될 때에는 지연시간을 고려해 P1위치를 이전 시간으로 돌려 히트 판정을 시도한다.

이전 시간으로 돌렸더니 히트가 성공한다면, 

P2 입장에서는 자연스럽겠지만, P1 입장에서는 갑자기 피격되는 상황이 벌어진다.

마찬가지로 P2 역시 갑자기 피격될 수 있다.


이 구조는 지연시간에 따른 시간 되돌기기가 사용되는데, 어느 정도까지 되돌릴 것인지 정한다.





서버에서 보내주는 정보가 일정하지 않거나 유실

P1의 S.T1 시점에 좌표 2,0으로 이동명령을 내리고, 다시 S.T2시점에 좌표 1,0으로 이동명령을 보냈다. 

즉, P1은 2,0까지 이동하진 않아야 한다.

하지만, 두 번째 명령이 늦거나 유실되었다면, P1는 좌표 2,0까지 이동시켜야 한다.

이렇게 뒤 늦게 온 정보를 보간을 해야 하며, 이동시켜야 할 거리가 길다면, 워프시켜야 하겠지.



클라가 서버시간을 알아야 캐릭터 상태를 보간을 할 수 있는데, 서버시간 동기화가 필요하다. 하지만 ping이 고르지 않은 상황에서 서버시간 동기화를 어떻게 할까나.

클라이언트는 서버로 부터 받은 서버시간을 자체적으로 흘러가게 한다

또한, 서버시간 동기화 메시지를 받을 때마 클라이언트의 서버시간과 서버의 서버시간을 비교해 본다.

게임에 따라 서버시간 보정을 할지 말지는 모르겠다.

하지만 ping에 따라, 다음과 같은 현상이 발생한다.


ping이 고정이면, 클라 자체적으로 흘려보낸 서버시간과 동일하며, ping만큼 서버 상태보다 과거를 본다.
게임에서 정한 오차범위 내에 과거를 보고 있다면 괸찮을 듯
ping이 길어지면, 클라의 서버시간이 더 빠르다.
서버의 캐릭터 상태 메시지가 늦어, 클라에서 자체적으로 진행한 캐릭터 상태와 오차가 발생한다.
일시적인거라면, 거슬리지 않겠지만,
지속적으로 느려진거라면, 캐릭터 상태 보간 역시 지속적으로 필요하다.
지속적인 보간은 어색하지 않을까.
차라리 늦어진 ping만큼 클라의 서버시간 역시 늦추는게 좋지 않을까.


아래 그림은 ping이 점점 길어져, 클라의 서버시간과 서버에서 받은 서버시간과 오차가 생기는 도표이다.



ping이 짧아지면, 클라의 서버시간이 더 느리다.

초반에는 네트워크 부하가 있었던지 느렸다가, 네트워크 상태가 원활하게 변경되어 빨라진 경우다.

서버의 상태 데이터와 오차가 줄면 좋은 것이니 클라의 서버시간을 당겨 주면 좋겠지.


아래 그림은 ping이 빨라지면서, 클라의 서버시간보다 받은 서버시간이 더 빨라지는 도표이다.


ping이 들쑥날쑥,

클라의 서버시간을 당기거나 늦춘다면, 천천히 부드럽게 하는게 좋지 않을까

일시적인거라면, 재빠르게 서버시간을 조정해도 부담이 없겠지만,


동기화를 구현한 예제

간단함을 위해 서버는 Node.js를 이용했고,

클라는 웹브라우져를 이용했다.

통신은 웹소켓을 사용했다.


Node.js 서버코드 보기


클라코드 보기

http://jsfiddle.net/yakolla/KTkZL/


테스트 해보기

서버 실행하기 

Node.js서버에 해당 코드를 파일로 저장하여 그 파일을 실행

웹소켓 모듈이 필요하므로, 없다면, 다음 명령을 콘솔에서 실행한다.

npm install websocket


클라 실행하기

서버 실행 후, 클라코드 링크를 클릭해 웹브라우져에서 실행

성공적으로 서버에 연결되었다면, 노란색 원이 출력된다.

마우스로 클릭하면, 원이 이동한다.

스페이스를 누르면, 마우스 방향으로 총알을 쏜다.

총알을 맞아 hp가 0이되면, 5초 후에 부활한다.


ping은 서버에서 보내온 메시지를 딜레이 시킨다.

ping 값이 길 수록  좀 더 오래된 과거 서버 상태를 본다.


간단한 테스트 예)

첫 번째 클라를 실행 후, 멀리 이동시킨다.

이동 중, 두 번째 클라를 실행하여, 첫 번째 클라의 원의 위치가 동기화 되는지 확인


클라 실행 모습





[본문링크] 게임 동기화 모델의 고민 흔적들
[1]
코멘트(이글의 트랙백 주소:/cafe/tb_receive.php?no=34903
작성자
비밀번호

 

SSISOCommunity

[이전]

Copyright byCopyright ⓒ2005, SSISO Community All Rights Reserved.