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).
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...
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.
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.
window
is the default this
(globalThis
) and as such is not required. eg window.requestAnimationFrame
is identical to requestAnimationFrame
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With