2011-04-17 50 views
9

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

显而易见的问题是,这些更新需要花时间在服务器和客户端之间传输。如果客户有攻击敌人的行为,那么在更新返回到服务器时,服务器很可能已经进入了足够远的游戏状态,以至于敌人不再处于同一地点,并且超出范围。

为了解决这个问题,我一直试图想出一个好的解决方案。我看了下面的内容,并且帮助了一些,但不是完全的:Mutli Player Game synchronization。我已经得出结论,我可以传输其他信息,例如方向(或AI运动的目标位置)和速度等信息,而不仅仅传输当前的游戏状态。从这个角度来看,我需要在客户端“猜测”一些什么,通过将游戏状态推进到未来几毫秒来确定实际状态(如服务器所看到的)。

问题是确定进展状态的时间量,因为它取决于服务器和客户端之间的延迟时间,这可能会有很大的差异。此外,我是否应该将游戏状态改为当客户端查看它时的状态(即只考虑更新到达客户端的时间),还是应该进一步处理,以便在发送响应时回到服务器,到那时它将是正确的状态(考虑到旅途和往返旅程)。

有什么建议吗?

重申:

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

2)我是否应该将客户端状态进行得足够远以便计算整个往返时间,或者只是将数据从服务器传输到客户端所需的时间?

编辑:我想出迄今

因为我已经有很多包来回的客户端和服务器之间,我不希望添加到交通,如果我不得不这样做。目前,客户端发送状态更新数据包(UDP)到服务器约150毫秒(只有在发生变化时),然后由服务器接收和处理。目前,服务器不会对这些数据包发送任何响应。

首先,我会让客户试图估计他们的滞后时间。我会默认它为50到100毫秒。我建议大约每2秒(每个客户端)服务器将立即响应这些数据包之一,并以特殊的定时更新数据包的形式发回数据包索引。如果客户端接收到定时数据包,它将使用该索引来计算该数据包发送多久之前,然后使用数据包之间的时间作为新的滞后时间。

这应该保持客户合理的最新滞后,没有太多的多余的网络流量。

声音可以接受,还是有更好的方法?这仍然不回答问题二。

回答

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) 

这意味着较慢的网络上的玩家看到更先进的状态快速网络上的球员。 但是,这对他们来说没有任何好处,因为它需要更长的时间才能处理它们的反应。 当然,如果两个玩家坐在一起并使用不同的速度网络,它会变得很有趣。 但这是非常不可能的情景,不是吗?

整个程序存在问题: 您在未来进行外推,这可能会导致无意义的情况。他们中的一些人,比如潜入墙壁可以很容易地被阻止,但那些取决于玩家的交互不能。

也许你可以把你的想法倒挂: 取而代之的预测,试图评估球员当时的T3行动 - (T1-T0 + T3-T2)。如果你确定一个角色会以这种方式命中,则相应地降低其生命值。 这可能比原来的想法更容易和更现实,或者可能更糟,或者根本不适用。只是一个想法。


试想一下两位选手互相运行。 根据推断它们在右侧通过彼此。事实上,他们中的一个改变了方向,最后它们在左侧相互传递。

+0

“但这是非常不可能的情景,不是吗?”如果一台设备使用蜂窝连接而另一台使用wifi?只是一个想法。无论哪种方式,您都在说我会向用户展示游戏将在他们的响应回到服务器时的状态,对吗? – 2011-04-20 06:14:46

+0

*“蜂窝连接和WiFi”* - 通常,两者都会尝试使用更快的连接。他们可以试图以这种方式作弊,但它看起来有点过于复杂。这会是一种欺骗,但是在MMO中​​有更简单的作弊方式。 – maaartinus 2011-04-20 11:25:58

+0

是的,我正在说这个。现在我补充一点,你可以减少所有球员的时差。较少的外推可能意味着更少的问题;只是一个想法。 – maaartinus 2011-04-20 11:30:05

2

的一种方式有种问题是在客户端服务器上运行游戏模拟。

因此,不要模拟服务器上的世界,而是在客户端上进行。只需将客户端做的事情(例如“玩家击中怪物”)发送到服务器即可。服务器运行相同的模拟并检查事件。

如果它们不匹配(玩家作弊,滞后),它会向客户端发送否决权,并且该操作在服务器上不会被记录为成功。这意味着所有其他客户端都不会注意到它(服务器不会将操作转发给其他客户端)。

这应该是一个非常有效的方式来处理滞后,特别是如果你有很多PvM战斗(而不是PvP):由于怪物是一个模拟,没有关系,如果有一个长时间的滞后客户端和服务器。

这就是说:大多数网络速度非常快,以至于滞后应该在几毫秒的时间内。这意味着你“只是”必须使服务器速度足够快,以便它可以响应100毫秒,并且玩家不会注意到。

相关问题