当前位置: 首页 > 面试题库 >

同步客户端-服务器游戏状态

颜新
2023-03-14
问题内容

我正在制作客户端服务器MMO风格的游戏。到目前为止,我已经建立了框架,以便服务器和客户端相互交互以提供状态更新。服务器维护游戏状态并定期计算下一个状态,然后每隔一段时间(每n毫秒)将其发送给所有客户端。用户可以在客户端查看此新状态并做出反应。然后,将这些操作发送回服务器进行处理,并发送给下一次更新。

明显的问题是这些更新在服务器和客户端之间传播需要花费时间。如果客户端采取行动攻击敌人,则在更新返回到服务器之前,服务器很有可能已将游戏状态推进到足够远的程度,以使敌人不再位于同一地点且不在范围内。

为了解决这个问题,我一直在努力提出一个好的解决方案。我看了看下面的内容,它对某些(但不完全)有所帮助:Mutli
Player游戏同步。我已经得出的结论是,我不仅可以传输游戏的当前状态,还可以传输其他信息,例如方向(或AI运动的目标位置)和速度。由此,在客户端,我拥有了“猜测”所需要的部分内容,即通过将游戏状态前进至未来的毫秒,可以了解实际状态(如服务器所看到的)。

问题是确定状态进展的时间,因为这将取决于服务器和客户端之间的延迟时间,这可能会有很大的不同。另外,我应该将游戏状态提升到客户端查看时的当前状态(即仅考虑更新到达客户端所花费的时间),还是应该进行得足够远,以便在发送响应时返回到服务器,届时它将是正确的状态(用于往返旅程的帐户)。

有什么建议?

重申:

1)计算发送和接收之间的时间量的最佳方法是什么?

2)我是否应该使客户端状态进展得足够远,以至于可以计入整个往返行程,或者仅仅是从服务器获取数据到客户端所花费的时间?

编辑:到目前为止我想出了什么

由于我已经在客户端和服务器之间来回传送了许多数据包,因此,如果需要,我不想添加该流量。当前,客户端将状态更新包(UDP)发送到服务器约150毫秒(仅当发生更改时),然后由服务器接收并处理它们。当前,服务器未发送对这些数据包的响应。

首先,我将让客户尝试估计他们的延迟时间。我会将其默认设置为50到100毫秒。我提议服务器(每个客户端)大约每2秒立即响应这些数据包之一,并在特殊的定时更新数据包中发回数据包索引。如果客户端收到定时数据包,它将使用索引来计算该数据包的发送时间,然后使用数据包之间的时间作为新的延迟时间。

这样可以使客户端合理地保持最新状态,而不会有过多的网络流量。

听起来可以接受,还是有更好的方法?这仍然不能回答第二个问题。


问题答案:

2)我是否应该使客户端状态进展得足够远,以至于可以计入整个往返行程,或者仅仅是从服务器获取数据到客户端所花费的时间?

假设服务器在时间T0发送状态,客户端在时间T1看到状态,玩家在时间T2做出反应,服务器在时间T3获得他们的答案,并立即对其进行处理。在此,往返延迟为T1-T0
+ T3-T2。在理想世界中,T0 = T1和T2 =
T3,观察时间与玩家行为处理之间的唯一延迟是玩家的反应时间,即T2-T1。在现实世界中,它是T3-T0。因此,为了模拟理想世界,您需要减去整个往返延迟:

T2-T1 = T3-T0 + (T1-T0 + T3-T2)

这意味着速度较慢的网络上的播放器会比速度较快的网络上的播放器看到更高级的状态。但是,这对他们没有好处,因为要花更长的时间才能处理完他们的反应。当然,如果两个玩家紧挨着并使用不同的速度网络,这可能会很有趣。但这是不可能的情况,不是吗?

整个过程存在一个问题:您在将来进行推断,这可能会导致荒谬的情况。其中有些功能,例如跳入墙壁很容易避免,但取决于玩家互动的功能则无法避免。1个

也许您可以颠倒您的想法:而不是进行预测,而是在T3-(T1-T0 +
T3-T2)时评估玩家的动作。如果您确定将以这种方式命中角色,请相应地降低其命中点。这可能比原始想法更容易,更现实,或者可能更糟,或者根本不适用。只是一个想法。

1想象两个玩家互相对抗。根据推断,它们在右侧彼此通过。实际上,其中一个改变了方向,最后它们在左侧彼此通过。



 类似资料:
  • 在开发我的在线游戏时,我试图了解更多关于安全的知识。 截获从服务器发送的数据包、使用某些软件修改数据包并将数据发送回服务器是否可能,以及有多困难? 下面是一个场景: 玩家与AI敌人进行战斗。一个玩家输掉了这场战斗,在战斗结束时,数据包被发送回服务器,记录发生的事情。是否可以在发送之前修改此数据包,并告诉服务器玩家已经赢得了这场战斗?如何读取并修改这些数据? 是否有可能说玩家与1个敌人进行了一场战斗

  • 问题内容: 我正在寻找一些通用策略,用于将中央服务器上的数据与并不总是在线的客户端应用程序进行同步。 在我的特定情况下,我有一个带sqlite数据库的android手机应用程序和一个带MySQL数据库的PHP Web应用程序。 用户将能够在电话应用程序和Web应用程序上添加和编辑信息。我需要确保即使手机无法立即与服务器通信,在一个地方所做的更改也会在所有地方反映出来。 我不关心如何将数据从手机传输

  • 实习,捕鱼棋牌类项目 # 一面 7/26 21min ## C++ 栈和堆的区别 const int *p 和 int * cont p 的区别 const 对象能调用全部成员函数吗 继承 public private protected 的区别 class struct 怎么计算大小 内存对齐是什么,为什么要内存对齐,内存对齐的规则 小端大端的区别 ## Unity Awake Enable S

  • 我想要将获得的统计数据存储在服务器端数据库中,但我不太确定基本值。具体到一款移动游戏,我在想应该尽量减少来回传递的数据量。 在客户端存储这些项目/字符的基本值,使用Prefab/Scriptable对象(我使用的是Unity)是不是一个坏主意?战斗将在客户端进行,服务器主要处理对玩家游戏数据数据库的读/写。玩家之间的主要互动将不会是玩家之间的实时战斗,而是类似于氏族冲突的东西。

  • 我想做的是: 为了学习游戏编程,我使用专用服务器和UDP创建了一个回声设置。专用服务器在不同的城市(也就是不在我的本地网络中)。 在我的本地计算机上,我有一个udp客户端和服务器(两个不同的程序)。当我第一次启动python服务器时,windows防火墙立即询问我是否要添加异常。在允许我的python服务器联网之后,我仍然没有收到任何消息。(客户- 我的问题是: 游戏如何解决这个问题?我没有为我想

  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se