带有JavaScript后端和前端的多人游戏。什么是最佳做法?

时间:2010-06-22 12:50:27

标签: javascript node.js multiplayer

我正在考虑在Node.js中创建一个网络多人游戏。这意味着我将在后端和前端使用相同的语言。这将是实时的,每个“房间”最多约20人,所以我有一些想法:

  1. 如何弥补所有用户之间的延迟,以便每个人同时看到同样的事情?我正在考虑跟踪每个播放器的平均ping时间,找到最慢的播放器,并告知其他客户端每个播放器必须延迟的时间(以毫秒为单位),以便每个人都尽可能地同步。

  2. 我正在考虑在后端和前端运行游戏代码(因为它是两端的JavaScript)并且只是有一个纠错机制来与“真实游戏”同步后端。这样,游戏应该在前端顺利执行,并且在同步发生时只有很少的故障。这也可以最大限度地减少前端JavaScript黑客攻击,因为作弊者会同步到后端游戏。

  3. 我是否应该通过套接字(按键)接收玩家行为,通知所有其他玩家其他玩家的行为,同时在后端“玩”游戏,并向所有人发送同步信息游戏状态每隔一段时间同步一次?

  4. 你怎么看?我应该考虑或注意更多的东西吗?

    请发布有关多人游戏的文档或文章的任何想法或链接。


    编辑:这些很有用:

7 个答案:

答案 0 :(得分:27)

1 - 是不可能的。您无法准确知道邮件到达客户端需要多长时间,并且您所采取的任何度量都不一定适用于您发送的下一封邮件。你能做的最好的就是近似,但是你总是需要假设人们会在稍微不同的时间看到稍微不同的东西或相同的东西。我建议只是将当前状态发送给每个人并使用插值/外推来平滑游戏玩法,以便每个人在过去几毫秒看到游戏,玩家之间和时间之间的延迟都会发生变化。一般来说,这很少是一个大问题。如果你真的想要缓冲服务器上的一些过去状态,你可以在它们之间进行插值,并将不同的旧数据发送给不同的人,以试图同步他们看到的内容,但结合客户端模拟和传输时间的抖动'我仍会看到机器之间存在一些差异。

2 - 典型的方法是在服务器上运行模拟,并向客户端发送常规(小)状态更新。客户端通常运行自己的模拟,并有办法在自己的预测/内插状态和服务器发送它们的权威状态之间进行混合。除用户输入之外的所有决策都应该在服务器端进行。最终,你将它们融合在一起只是在光滑的外观和准确的状态之间进行权衡,因此这是你必须做出的美化决定。

3 - 您的客户通常应将按键转换为逻辑操作。您的服务器不关心密钥。将该逻辑操作发送到服务器,如果需要,可以将其广播给其他客户端。一般情况下,您不需要在此处执行任何操作 - 操作引起的任何相关更改通常只会更改游戏状态,因此会在该状态的正常广播中发送。

答案 1 :(得分:5)

我不会直接解决你的观点,因为其他答案做得很好。但是,我建议研究HTML5,WebSockets和Comet,它们有望显着提高实时性能。这些技术使您可以拥有长时间运行的HTTP请求,允许服务器将数据推送到客户端,而不是客户端轮询服务器。这可以大大加快速度。

以下是一些应该证明有用的资源:

答案 2 :(得分:1)

  1. 这个很难做到,我可以看到同步到“最慢”的很多问题。你可以放松一下,这样客户就可以“最终保持一致”吗?

  2. 听起来不错。

  3. 我会从前端向后端发送短动作事件,让后端修改游戏状态并将游戏状态修改事件发布回客户端,非常注意只向正确的订阅者发送必要的事件。此时,您可以丢弃任何似乎不匹配或看起来像假货/黑客的事件。

答案 3 :(得分:1)

最好的方法是只跟踪一个地方的所有对象,即服务器。每个人都会在一个旅行时间之后看到来自服务器的信息,而不是“实际发生”,人们的命令将需要一次旅行才能在服务器上注册。真的没有办法解决这个问题。对于某些应用而言,在不等待服务器响应的情况下立即模拟您自己的运动是可行的,但这无疑会导致时间编程的噩梦,人们通常会看到彼此“滞后”。碰撞检测几乎不可能。

这样做的最终结果是,当你输入命令直到你看到它们实际发生时会有一种迟缓,但希望人们会学会应对这种情况并尝试稍早输入命令来补偿。慢速连接快节奏的实时游戏是不可能的。

答案 4 :(得分:1)

如果您正在寻找一些示例代码可供学习,那么有一个 Pong done in ActionScript的在线多人游戏,客户端内插服务器端物理

Pong示例建立在Union platform上,可以免费提供最多1000个客户端连接。

Union有一个JavaScript客户端框架, OrbiterMicro (JavaScript Client)

您也可以在JavaScript中编写服务器端逻辑,请参阅 Creating Room Modules with JavaScript

(完全披露:我是Union的联合创始人。)

答案 5 :(得分:0)

一种典型的方法是不要试图强制所有客户端以锁定到服务器的相同帧速率运行......它只是变得丑陋。而是发送频繁更新,以便客户端在收到新更新时可以更新。

通常情况下,客户会预测短时间内的情况,然后通过服务器的更新进行更正。您也可以应用时间校正。例如,如果服务器告诉您“播放器2处于以速度V行进的P”,您可以尝试根据最近的ping来了解该消息的年龄,并更正从P到{的位置{1}}。

答案 6 :(得分:0)

我回答了另一个类似于此问题的问题,这些问题值得阅读,与最慢的客户端同步可能不是最佳解决方案,具体取决于游戏。

其他StackOverflow问题:Multiplayer game movement synchronization