게임 개발을 위해 네트워킹을 통해 시계를 동기화하는 방법은 무엇입니까?


10

나는 시간 기반 측면이 많은 게임을 만들고 있습니다. 나는 네트워크가 멈추고 패킷이 진행되지 않을 때 (그리고 패킷이 수신되는 시간과 그렇지 않은 시간) 플레이어 위치를 추정하는 데 시간을 사용합니다. 플레이어가 방향을 선택하고 움직일 수 없다는 점에서 팩맨 형 게임이므로 시스템이 의미가 있습니다 (또는 적어도 그렇게 생각합니다).

그래서 두 가지 질문이 있습니다. 1) 네트워크에 지연이 있기 때문에 처음에 게임의 시계를 어떻게 동기화합니까? 2) 동기화하지 말고 동일하다고 가정하십시오 (내 코드는 표준 시간대와 독립적입니다). 사람들이 시계를 속임수로 바꾸는 슈퍼 경쟁 게임은 아니지만 여전히 그렇습니다.

게임이 Java 및 Python으로 프로그래밍 중입니다 (프로젝트로 병렬 개발).



5
나는이 질문이 gamedev.stackexchange.com에 이미 포함되어 있거나 적어도 거기에 속한다고 확신합니다.
congusbongus

1
@ KongXu : 잘 모르겠습니다. 이 작업은 일반적으로 게임에서 수행되는 작업이지만 본질적으로 게임 개발에만 국한된 것은 아닙니다. 다른 많은 분산 시스템에는 동기화 된 시계가 필요합니다.
Jan Hudec

2
IPv4 옵션 TIMESTAMP를 이미 사용해 보셨습니까? 자세한 정보는에있다 linux.die.net/man/7/socket 거기에서에 linux.die.net/man/3/cmsg 에서 작은 예제 프로그램을 다음과 pdbuchan.com/rawsock/rawsock.html 전과 마지막 IPv6 섹션.
ott--

2
게임 (응용 프로그램)이 시스템 시계를 건드리지 않아야합니다.
Reinstate Monica-M. Schröder

답변:


9

시스템 의 시계 를 동기화 하는 것은 확실히 좋지 않다고 생각합니다 . 사용자는 시스템 설정을 만질 것을 기대하지 않으며 많은 시스템에서 허용하지 않습니다.

타임 스탬프를 한 쪽 시계에서 다른 쪽 시계로 변환하기 위해 상관 관계를 갖기 만하면됩니다. 반면, 플레이어 위치를 예측하기 위해이 상관 관계를 사용하려면이 상관 관계가 다소 정확해야합니다 (예 : 적어도 100 분의 1 초). 시스템 클럭 임의의 머신간에 이처럼 상관 관계 가 없습니다 . 따라서 NTP 테마의 일부 변형을 사용하여 네트워크 대역폭을 보존하기 위해 다른 메시지에 포함 된 상관 관계를 직접 설정해야 합니다.

기본 아이디어는 타임 스탬프를 보낸 각 패킷과 다른 쪽에서 마지막 패킷을 받았을 때 시퀀스 번호 및 타임 스탬프를 보낸 것입니다. 예를 들어, 패킷 Q가 1000으로 전송되었고 패킷 P가 500으로 수신되었다고 표시하면 패킷 P가 0으로 전송되고 800에서 Q를 수신하는 것보다 왕복이 (800-0) 인 경우 )-(1000-500) = 300. 아 시메트리를 알 수있는 방법이 없으므로 패킷이 어느 방향 으로든 반 (틱) 틱을 취한다고 가정하면됩니다. 그리고이 원격 타임 스탬프는 로컬보다 1000-(800-150) = 350 틱입니다. 왕복은 다를 수 있습니다. 클록이 합리적으로 정확하다고 가정하면 장기적인 평균 상관 관계를 사용해야합니다.

시계에도 시스템 시계를 사용하고 싶지는 않습니다. 중간에 재 동기화되어 트랙에서 벗어날 수 있습니다. 당신은 사용해야 clock(CLOCK_MONOTONIC)유닉스 또는 GetTickCount(하지 않도록하는 API를 현재 Java 또는 Python으로 포장하는 방법) Windows에서.


참고 : SO_TIMESTAMP소켓 옵션 ( 질문에 대한 의견에서 ott가 언급 한 socket (7) 참조 )은 패킷을 수신하는 이벤트 루프의 대기 시간 효과를 분리하는 데 유용합니다. 노력할 가치가 있는지 여부는 필요한 정밀도가 얼마나 좋은지에 달려 있습니다.


1

어떤 선수의 시계가 올바른지 어떻게 알 수 있습니까? 당신은하지 않으므로 참조 시계를 사용하십시오 .

NTP는 여기서 과잉입니다. ~ 1 초의 정확도 만 필요하므로 rdate를 사용 하거나 많은 클럭 동기화 알고리즘 중 하나를 선택하십시오 .

당신이 방법을 선택한 하나, 각 플레이어의 기계가 (시스템 시계를 변경하지 않고) 그 방법에 따라 시간을 받도록하십시오. 기준 UTC 시간과 플레이어의 시스템 시계 UTC 시간간에 차이가 무엇이든 유효 오프셋입니다. 봇 이동 또는 광선 추적 총알 등을 추정하기 위해 시간 관련 계산을 수행 할 때마다 시스템 시간을 얻은 후이 오프셋을 고려합니다. UTC를 사용하면 시간대 요소가 제거됩니다.


1

나는 두 번째로 NTP를 사용하거나 시스템 시계 근처에 가면 안된다고 진술합니다. 실제로이 요구 사항을 검토하면 다음과 같은 요구 사항이 있음을 알게됩니다.

  • 이전 프레임 이후에 시간이 얼마나 걸리므로 시간 기반 작업을 진행할 수 있습니다. 클라이언트와 서버에서 속도가 다를 경우 클라이언트와 서버에서 다를 수 있습니다 (예 : 고정 된 20Hz로 실행되는 서버 또는 원하는 속도로 실행되는 클라이언트가 표시 될 수 있음).
  • 현재지도가 시작된 이후 경과 된 시간입니다. 이 타이머는 0부터 시작하는 타이머 (시작할 때 클라이언트와 서버 모두에서 0으로 초기화)이며 서버 시간은 "마스터"로 간주되므로 서버는이 시간의 현재보기를 각 프레임마다 클라이언트에 보냅니다. 서버에서 실행됩니다. 이것은 현재 서버 시간을 취하고 서버가 시작된 시간을 빼거나 위의 프레임 당 시간을 누적하여 얻을 수 있습니다. 위의 클라이언트 측 프레임 당 시간을 사용하여 두 개의 연속 서버 프레임간에 보간 점을 생성 할 수도 있습니다.
  • 다른 모든 시간이 진행되는 기준 "기본 시간" 이것은 클라이언트와 서버 모두에서 동일 할 수 있지만 (모든 게임 유형에 반드시 필요한 것은 아님), 게임 시작시 (또는 현재 맵) 초기화되지만 새 게임이나 새 맵이 아닌 한 변경되지 않습니다. -시작).

이것은 간단한 개요입니다-대기 시간 / 드롭 된 패킷 등과 같은 문제를 처리하려고 시도하지는 않지만 모든 것이 기반이되어야하는 기본 프레임 워크입니다.

마지막 항목 원하는 경우 표준 시간대를 사용할 있지만이 중 어느 것도 시스템 시계 근처에 있거나 다른 표준 시간대와 같은 문제에 대해 걱정할 필요가 없습니다. 중요한 것은 실제 경과 시간은 고해상도 제로 기반 타이머를 사용하여 측정되므로 시간대 차이와 완전히 무관합니다. 서버에서 실제 현재 시간을 찾고 싶으십니까? 경과 시간을 기준 시간으로 추가하면됩니다. 클라이언트도 마찬가지입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.