如何通过网络同步时钟以进行游戏开发?


10

我正在写一个具有很多基于时间的方面的游戏。当网络停滞且数据包未通过时(以及接收和不接收数据包之间的时间),我用时间来帮助估计玩家的位置。从某种意义上说,这是一种吃豆子型游戏,玩家可以选择一个方向并且不能停止移动,因此该系统才有意义(或者至少我认为可以)。

所以我有两个问题:1)由于网络存在延迟,我如何在开始时同步游戏的时钟。2)可以不同步它们,只是假设它们是相同的(我的代码与时区无关)吗?这不是一个超级竞赛的游戏,人们会改变时钟以作弊,但仍然如此。

该游戏正在使用Java和Python进行编程(作为项目进行并行开发)


7
查找ntp
棘轮怪胎

5
我确定这个问题已经在gamedev.stackexchange.com上已经涵盖,或者至少它属于那里。
congusbongus

1
@CongXu:我不太确定。尽管这通常是为游戏完成的任务,但它并非固有地特定于游戏开发。许多其他分布式系统需要同步时钟。
2013年

2
您是否已经尝试过使用IPv4选项TIMESTAMP?有关更多信息,请访问linux.die.net/man/7/socket,然后访问linux.die.net/man/3/cmsg,然后访问pdbuchan.com/rawsock/rawsock.html上的一个小示例程序。IPv6部分。
ott--

2
游戏(应用程序)不应碰到系统时钟。
恢复莫妮卡-M.Schröder2013年

Answers:


9

我认为这是绝对不能确定synchornize时钟系统。用户不希望您触摸系统设置,许多系统甚至不允许您触摸。

您所需要做的就是建立一个关联,以将时间戳从一侧的时钟转换为另一侧的时钟。另一方面,如果您想使用这种相关性来预测玩家的位置,则需要使这种相关性非常精确,至少要达到百分之一秒。随机机器之间的系统时钟永远不会如此相关。因此,您应该使用NTP主题的一些变体来自己建立相关性,可能将其嵌入其他消息中以节省网络带宽。

基本思想可能是,对于每个发送了时间戳的数据包,您都将发送它,并在从另一端接收到最后一个数据包时发送它的序列号和时间戳。由此计算出往返次数:例如,如果数据包Q说它是在1000发送的,而数据包P是在500接收的,则给定的是,您在0发送数据包P并在800接收到Q,​​则往返数是(800-0 )-(1000-500)=300。无法知道不对称性,因此您仅假设数据包在任一方向上花费了一半(150)滴答声。而且该远程时间戳比本地时间戳提前1000-(800-150)= 350 ticks。往返行程会有所不同。如果您假设时钟相当精确,则应使用相关性的长期平均值。

请注意,您也不想使用系统时钟。他们可能会在中途重新同步,从而使您偏离轨道。您应该clock(CLOCK_MONOTONIC)在Unix或GetTickCountWindows上使用(不知道现在这些API如何用Java或Python包装)。


注意:SO_TIMESTAMP套接字选项(请参阅ott--在问题注释中提到的socket(7))对于区分接收数据包的事件循环的延迟影响很有用。是否值得付出努力取决于您需要多高的精度。


1

您怎么知道哪个球员的时钟是正确的?您没有,所以使用参考时钟

NTP在这里过大-您只需要约 1秒钟的精度-因此请使用rdate或从许多时钟同步算法中选择一种。

您选择了一种方法,让每个玩家的机器按照该方法选择时间(无需更改其系统时钟)。基准UTC时间与播放器系统时钟UTC时间之间的任何差异都是其有效偏移量。每当您进行与时间相关的计算以推断机器人运动或射线跟踪项目符号时,都将在获取系统时间后将此偏移量考虑在内。使用UTC将消除时区因素。


1

我第二次声明您不应该使用NTP或接近系统时钟。如果您实际检查了此要求,将会发现您具有以下需求:

  • 自上一帧以来已经过了多少时间,因此您可以推进任何基于时间的内容。如果两者的跳动速率不同,则客户端和服务器上的情况可能会有所不同(例如,您有时可能会看到服务器以20Hz的固定频率(或其他频率)运行,但允许客户端以所需的速度运行)。
  • 自从当前地图开始以来已经过去了多少时间。这是一个从零开始的计时器(在客户端和服务器启动时将其初始化为0),并且服务器时间被视为“主时间”,因此服务器针对每个帧将其当前时间视图发送给客户端在服务器上运行。可以通过获取当前服务器时间并减去服务器启动的时间,或通过累积上述每帧时间来获得。上面的客户端每帧时间也可以用于生成任意两个连续服务器帧之间的插值点。
  • 所有其他时间都从其开始的参考“基准时间”;这在客户端和服务器上可以是相同的(但并非绝对需要所有游戏类型),并且可以在游戏开始时(或当前地图)进行初始化,但之后不会更改(除非有新游戏-或新地图) -已启动)。

这是一个简化的概述-我不尝试处理延迟/丢包等问题,但这是整个事情的基础框架。

尽管最后一项可以根据需要使用时区,但是这些都不需要靠近系统时钟或担心诸如不同时区之类的问题。重要的是,实际经过时间是使用高分辨率的基于零的计时器来测量的,因此它们与时区差异完全不可知。是否想在服务器上找到实际的当前时间?只需将经过的时间添加到参考基准时间中就可以了。对于客户也是如此。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.