Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript multiplayer game - requestAnimationFrame for game/physics logic?

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).

like image 389
Paul Avatar asked Sep 20 '19 09:09

Paul


1 Answers

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

like image 50
Blindman67 Avatar answered Sep 27 '22 22:09

Blindman67