具有 JavaScript 后端和前端的多人游戏。最佳实践是什么?

发布于 2024-09-06 10:30:29 字数 854 浏览 6 评论 0原文

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

  1. 如何补偿所有用户之间的延迟,以便每个人同时看到相同的内容?我正在考虑跟踪每个玩家的平均 ping 时间,找到最慢的玩家,并通知其他客户端他们必须延迟每个玩家的时间(以毫秒为单位),以便每个人都尽可能同步。

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

  3. 我是否应该通过套接字(按键)接收玩家操作,通知所有其他客户端其他玩家的操作,同时在后端“玩”游戏,并向每个人发送整个游戏状态的同步信息偶尔同步它们?

你怎么认为?还有其他我应该考虑或注意的事情吗?

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


编辑:这些很有用:

I'm thinking of creating a web multiplayer game in Node.js. This means I'll be using the same language in the backend and in the frontend. It would be in realtime and about 20 people max in each 'room', so I have a few thoughts:

  1. How do I compensate for the delay among all users so that everyone sees the same thing the same time? I'm thinking of tracking the average ping time of each player, find the slowest one, and inform the other clients of the time (in milliseconds) they have to be delayed each one so that everyone is as synchronised as possible.

  2. I'm thinking of running the game code in the backend as well as in the frontend (since it's JavaScript on both ends) and just have an error-correction mechanism to synchronize with the 'real game' in the backend. That way the game should perform smoothly on the frontend and with only few glitches when the synchronisation happens. Also that would minimize frontend JavaScript hacking since cheaters would be synchronised down to the backend game.

  3. Should I receive player actions through the socket (keypresses), inform all other clients of the other players' actions and in the mean time 'playing' the game in the backend and send synchronisation information to everyone of the entire game state every once in a while to synchronise them?

What do you think? Are there more stuff I should consider or pay attention to?

Please post any thoughts or links to documentation or articles regarding multiplayer gaming.


EDIT: These are useful:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只是在用心讲痛 2024-09-13 10:30:29

1 - 不可能。您不确切知道消息需要多长时间才能到达客户端,并且您进行的任何测量都不一定适用于您发送的下一条消息。你能做的最好的就是近似,但你总是需要假设人们会在略有不同的时间看到略有不同的事物或相同的事物。我建议将当前状态发送给每个人,并使用插值/外推来平滑游戏玩法,以便每个人都能看到过去几毫秒的游戏,延迟在玩家之间和随着时间的推移而变化。一般来说,这很少是一个大问题。如果您确实想在服务器上缓冲一些过去的状态,您可以在它们之间进行插值,并将不同的旧数据发送给不同的人,以尝试同步他们所看到的内容,但结合客户端模拟和传输时间的抖动,您可以不同机器之间仍然会看到一些差异。

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

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

1 - is impossible. You don't know exactly how long a message will take to arrive on a client and no measurement you take will necessarily be applicable to the next message you send. The best you can do is an approximation, but you always need to assume that people will see EITHER slightly different things OR the same things at slightly different times. I'd recommend just sending the current state to everybody and using interpolation/extrapolation to smooth out the gameplay, so that everybody sees the game a few milliseconds in the past, with the delay varying both between players and over time. In general this is rarely a big problem. If you really want to buffer up some past states on the server you can interpolate between them and send different old data to different people in an attempt to sync what they see, but combined with the client side simulation and the jitter in transmission times you'll still see some differences across machines.

2 - the typical way is to run the simulation on the server, and send regular (small) state updates to clients. Clients typically run their own simulations and have a way to blend between their own predicted/interpolated state and the authoritative state that the server is sending them. All decisions other than user input should be made server-side. Ultimately the way you blend these is just a tradeoff between a smooth appearance and an accurate state so it's a cosmetic decision you'll have to make.

3 - your client should typically translate a keypress to a logical action. Your server doesn't care about keys. Send that logical action to the server and it can broadcast it to other clients if they need it. Generally though you wouldn't need to do anything here - any relevant change caused by the action will typically just change the game state, and thus will get sent out in the normal broadcast of that state.

小梨窩很甜 2024-09-13 10:30:29
  1. 这很难做到,我发现同步到“最慢”存在很多问题。您能否放松这一点,以便客户能够“最终保持一致”?

  2. 听起来不错。

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

  1. This one is very hard to do, and I can see lots of problems with syncing to 'the slowest'. Can you loosen this up so the clients could be 'eventually consistent'?

  2. Sounds good.

  3. I would send short action events from front ends to backend, have the backend modify game state and publish game state modification events back to the clients, with much attention to only sending the necessary events out to the right subscribers. At this point you can discard any events that don't seem to match or that seem like fakes/hacks.

说好的呢 2024-09-13 10:30:29

最好的方法是在一个地方(即服务器)跟踪所有对象。每个人都会比“实际发生”晚一趟时间从服务器看到信息,并且人们的命令将需要一趟才能在服务器上注册。这确实没有办法解决。对于某些应用程序,无需等待服务器响应即可立即模拟您自己的运动,但这无疑会导致定时编程的噩梦,并且人们通常会看到彼此“滞后”。碰撞检测几乎是不可能的。

这样做的最终效果是,从您输入命令到看到它们实际发生,都会出现缓慢的情况,但希望人们能够学会应对这种情况,并尝试稍微提前输入命令以进行补偿。在连接速度较慢的情况下,快节奏的实时游戏是不可能的。

The best way is to keep track of all objects in only one place, namely the server. Everyone will see the information from the servers one travel time later than it "actually happens" and people's commands will take one travel to register on the server. There really is no way around this. For some applications it can be practical to simulate your own movement right away without waiting for a server response but this will undoubtedly lead to a nightmare with the timing programming and people will typically see each other "lagging around". Collision detection is all but impossible.

The net effect of this is that there will be a sluggishness from when you enter your commands until you see them actually happening but hopefully people will learn to cope with this and try to input their commands slightly earlier to compensate. With slow connections fast-paced realtime games is just impossible.

人心善变 2024-09-13 10:30:29

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

通常,客户端会在短时间内预测事情的进展情况,然后通过服务器的更新进行纠正。您也可以应用时间校正。例如,如果服务器告诉您“玩家 2 在 P 处以速度 V 行进”,您可以尝试根据最近的 ping 来了解该消息的存在时间,并根据 PP + x*D

One typical approach is not to try and force all clients to run at the same framerate locked to the server... it just gets ugly. Instead, send frequent updates so clients can update whenever they receive a new update.

Normally, a client will predict how things are going for short periods, then be corrected by an update from the server. You can apply time corrections too. For example, if the server tells you "player 2 is at P travelling at velocity V" you can make some attempt to know how old that message might be based on a recent ping, and correct the position from P to P + x*D.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文