服务器端输入


9

当前在我的游戏中,客户端不过是渲染器。当输入状态更改时,客户端将数据包发送到服务器,并像对待输入一样处理播放器,但是服务器保留最终决定权。

除了一个大问题:掉落边缘,这通常效果很好。基本上,如果玩家正朝着一条边走,比如说一个悬崖,并且在走出边缘之前就停下来了,有时是一秒钟之后,他将被传送到边缘之外。这是因为在服务器处理信息后发送了“我停止按W”数据包。

这是一个滞后图,可以帮助您理解我的意思:http : //i.imgur.com/Prr8K.png

我可以每帧发送一个“ W Pressed”数据包供服务器处理,但这似乎是带宽成本很高的解决方案。

任何帮助表示赞赏!

Answers:


5

当服务器对职位有最终决定权时,它应该通过验证和合理检查客户端作为输入和职位发送的内容来做到这一点。我之所以这样说,是因为您正在做的事情是立即移动播放器,并且在您的代码中创建的期望是客户才是真正的位置。

您认为它通常运行良好,但事实并非如此。旁注:您说您的客户端不过是一个渲染器,然后立即为其提供本地控制以在没有服务器消息的情况下四处移动。不能同时使用两种方法,要么等待服务器告诉您移动,要么对位置进行一些控制,然后使用服务器来验证作弊行为。

我注意到您的回复达到一秒钟吗?这是500毫秒的延迟,对于任何类型的动作游戏而言,这都是可笑的。尝试找出这种转变为什么要花这么长时间的原因,可能是命令队列备份(从不及时处理到带宽泛滥,甚至是导致许多数据包丢失的恶魔)。

我认为应该发生的是

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

这里最棘手的部分是,如果客户收到有关自身的消息,则它通常应该忽略它,除非该消息是诸如“无效的举动,改为转到XYZ”之类的消息。如果该消息是给其他客户的,您正在获取有关该消息的信息,那么您就必须及时推断出转发信息,这样看起来就可以了。


客户根本不发送职位;它只是预测/插值。这就是为什么当它认为它处于边缘时会掉落边缘的原因。另外,我看不到我说的滞后时间是1秒,它更像是8毫秒(本地测试)到100毫秒(通过互联网)。我说玩家稍后会退缩,因为我会定期发送全位置更新。我是否正确理解我应该发送客户认为应该的位置以及所按的键,并且服务器应验证是否有可能?
Thomas

“有时过一会儿,他会被传送出去”,这暗示着巨大的延误,这正是我有时间的地方。对于响应式动作游戏,是的,客户端播放,服务器及时播放,让客户端知道它是否做了非法的事情。您会注意到,在在线多人游戏中,您通常会看到其他人转移位置(这些人来自服务器),而您自己的位置很少因直接服务器修正而改变。其他人看到转移位置,等等...
Patrick Hughes 2012年

难道这还不会导致播放器掉到服务器边缘吗?除非我每帧发送一个数据包,否则服务器仍可能认为播放器正在移动约32毫秒。(我仅每三帧发送一次数据包)。还是您建议我根本不模拟服务器上的输入,而只是检查位置是否在所按输入的范围之内?
Thomas

由于服务器仅纠正客户端报告的无效移动,因此,除非客户端本身直接驶过边缘,否则它永远不会发出“您从悬崖上掉下来”的信息。在此反馈循环中,是服务器将其自身更正为客户对世界的看法及其在世界中的位置。运动会感觉清脆并且对玩家有反应。与世界对象交互之类的其他动作将涉及等待服务器告诉客户端刚刚发生的事情,单击一个框并等待响应,但是我们这里只是在谈论移动。
Patrick Hughes 2012年

这听起来很像我目前正在做的事情;将位置发送给服务器,并让服务器验证玩家是否可以移动到该位置。不过,这似乎是一种更具启发性的方法,而且我认为,由服务器决定周期不是很有效。每个数据包都发送时间戳会起作用吗?我认为这将消除这个问题。我相信Halo和使用Source引擎的游戏都可以使用它。
托马斯

0

我了解您的问题是:

当我开始按下“转发”按钮时,服务器会收到一个数据包,而当我最后松开“转发”按钮时,服务器将得到另一个数据包。因此,服务器上的实际移动在实际游戏中相对于玩家在客户端所表达的内容来说“太迟了”大约100毫秒开始和结束。因此,如果玩家想移动10秒,他可能最终会移动10.x秒,而不是x >= 1在线。

这是一个糟糕的设计策略,因为它无法按照游戏者的意图表达游戏者在游戏世界中的意愿,从而造成相当差的用户体验。

我建议的解决方案是(尽可能多地)发送一个数据包,该数据包指示玩家执行了多少步以及朝哪个方向。如果服务器通过了正确性检查,则服务器将使用新的玩家位置更新游戏世界。因此,玩家可以高精度移动,避免掉落高架。

另一种方法是记住玩家在过去一秒内的位置,并回溯到释放按钮的时间来更正位置。听起来像是会产生过去的橡皮筋效果。(仅出于其他原因)

因此,基本上,您将需要发送一个数据包,其中包含按下了哪个按钮,按下按钮的实际游戏时间是多少,然后再发送,释放了哪个按钮以及确切的时间。


正如我对帕特里克(Patrick)所说,我认为解决方案将更像是一种启发式方法。服务器不是“ The Man”服务器,而是检查客户端数据的有效性。当然,这将需要留出一定的余地,以使滞后或其他网络问题不会产生误报。
Thomas
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.