Javascript multiplayer game - requestAnimationFrame for game/physics logic?
Asked Answered
C

1

7

I'm developing a Javascript based multiplayer game. So far I have the basic server, client and networking ready.

I did have an issue where my player was moving faster on a 120Hz screen as opposed to a 60Hz screen. I've fixed this by multiplying the player's movementspeed by the deltatime of the 'requestAnimationFrame'.

However; would it be a better solution to separate the animations from the logic?

As in:

//Game loop; Do each 1/60th of a second
setInterval(gameTick, 1000/60);
function gameTick(){
  player.handleKeys();
  enemies.foreach( (enemy) => {
    enemy.update();
  });
}

//Draw loop; match to player screen refresh rate
window.requestAnimationFrame(gameLoop);
function gameLoop() {
    player.draw();
    enemies.foreach( (enemy) => {
    enemy.draw();
  });
  window.requestAnimationFrame(gameLoop);
}

While the difference may be "neglectable" I want to avoid players with 240Hz 'spamming' the server and have an advantage over other players.

Though on the other hand for a 240Hz monitor; only 1 in 4 frames your keyboard input will be handled, so it may not feel as smooth?

This reason I'm asking is that this will be a competetive game and should thus be balanced. But I've checked various sources on which the consensus seems to be to use requestAnimationFrame (even for the logic; not only the drawing), though I'm doubting this and would like to know which is correct (and/or used in professional competetive games).

Copland answered 20/9, 2019 at 9:41 Comment(4)
requestAnimationFrame tries to get 60fps on any machine, but what if it can't? What if you only get 20fps on a slow machine? You would probably have the same issue. This is an interesting question though!Bathymetry
@Bathymetry on my device; it tries to (and successfully does) achieve 144Hz; since this is the native refresh rate of the screen. I'm now thinking of using a interval for the physics/gamelogic and requestAnimationFrame (with delta time) for the draw loop. In this way fluctuations (or different screens) do only affect the animations but not the game logic (how often input is handled and sent to server). On 144Hz the animations (if done properly) will be smoother; but not faster as they incorporate the deltatime. Also then; if draw drops <60hz; the setinterval should still tick 60hz?Copland
setInterval is, again, not that reliable for actually timing something. Since its sharing the thread (which your requestAnimationFrame does as well), it could still be slowed down if the computer isn't fast enough to do everything you want in a single loop. My guess would be to actually try to create a web worker that your main thread continuously updates and that has its own - very light - interval in a separate thread that exchanges data with your user and your server in a more predictable way. But that is really a guess, I have no diirect experience building this.Bathymetry
I'm neighing towards the feeling that we're overthinking it, though interesting point regarding using web-workers that way I can possibly separate the load of drawing and physics.Copland
W
3

requestAnimationFrame (rAF) will only fire at maximum rate of 60fps. (exception Some much older versions of some browsers had flags to turn off VSync which did effect rAF)

Note

  • rAf, setTimeout or setInterval are not reliable and can drop frames for many reasons.

  • rAF will stop firing if the Tab or Window is hidden or (tab) not focused.

  • setInterval and setTimeout will be throttled if the Tab or Window is hidden or (tab) not focused.

  • rAF time argument does not represent the time of the (next displayed) frame, but rather the time that rAF callback is called.

    That means that...

    • the time between frames if calculated from rAF time argument will float and can not be reliably used as a delta time.
    • the time argument represents the time of the call, not the time of frame being presented to the display, and can be up to < 1/60 of a second earlier than the rendered content is presented to the display hardware.

Local networks

For multi player games the server should serve the time so that all players run on a common and reliable time stamp. Clients can project time forward from last time stamp to avoid freezing if network delays packets, but should revert back to synced (server time) time when received.

Large networks

Communications is distance dependent, even on a perfect point to point network if the client is on the other side of the world the best ping possible is 130ms (near 8 frames @60Hz) due to light travel time. This does not include packet switching and actual route length. Generally the ping time to most distant point on the globe is around 300ms.

This delay must be considered for professional games, and is why many multi player games provide local servers, and restrict players from some servers if to far away. 300ms gives closer players a significant advantage.

Realtime multi-player games using the browsers APIs to host clients will be problematic at best as the browser is an unreliable and inconsistent client host, mostly due to the huge range of devices the clients run on.

BTW

window is the default this (globalThis) and as such is not required. eg window.requestAnimationFrame is identical to requestAnimationFrame

Welborn answered 22/9, 2019 at 12:56 Comment(2)
Interesting points, though I must add rAF runs at 144Hz on my laptop which has an internal 144Hz display (I've added an FPS counter which is 1/delta). This and the combination of setInterval still doing 'something' when hidden/unfocused, makes it more applicable for the networking. I will still use rAF for drawing though. I've added FPS and Tick rate debug values to monitor both.Copland
Good point on ping also, I'd have to make a debug for that as well, as think of how a "lagger" will not have an unfair advantage (and kick too high pings). I agree it may not be the best client, but mainly because the client is highly untrustable, client code is always visible in browsers and commands can be injected with the debugging tools. I did have the idea of making the client only display and send key-commands, but then you would need some faking at client side to make it look smoother.Copland

© 2022 - 2024 — McMap. All rights reserved.