🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Multiplayer platformer - problems with smooth y-axis movement

Started by
1 comment, last by hplus0603 1 year, 6 months ago

Hi, just started working on fast paced 2d multiplayer browser game, I'm using JS/TS on presentation side and Go on server-side if that matters.

I've implemented client-side prediction (without server reconciliation so far - on localhost shouldn't be needed anyway I think) and entity interpolation for animating smoothly other players. On server-side I'm running game loop with 50/s rate, each tick I'm gathering all the inputs sent by clients (like "move left"), change velocity accordingly and at the end of the loop I'm iterating over all the players, applying the velocity to their positions and broadcasting it to all the players. Similarly on client-side I'm running game loop with same rate of 50/s, in the game loop I'm checking which keys are pressed down, basing on that information I'm changing player's velocity and sending information about pressed button to server, besides that there is second loop - which is running as fast as possible where players' sprites are moved accordingly to current velocity and multiplied by delta time, in this loop I'm also interpolating other players. When client receives its position from server I'm instantaneously changing its position to the received values (idk if that should be lerped).

Generally everything plays and looks very smoothly (if there was some actual network delay I suspect it wouldn't be so nice) but there's one problem - jumping/falling player. The way "gravity" was implemented is that each game loop tick adds some value (0.3) to the player's y-velocity, unless player is already grounded, the thing is if both client's loop and server's loop are set to 60/s jumping/falling down looks smooth (yet still not perfect) but the lesser tickrate the worse it looks, when tickrates aren't the same it looks catastrophically, because y-velocity isn't growing at the same rate. Am I doing something incorrectly? I don't want to be forced to use 60 Hz loops and I don't like the fact that both loops have to synced... I thought about server reconciliation, but I'm not sure that it would help in this case as gravity isn't really an input, so no idea how should I go around implementing it... Looking for any suggestions.

Advertisement

Simulation rate and display rate and network rate don't have to be the same value.

You can simulate at 1000 Hz (if the simulation is cheap,) display at 120 Hz (if the user has a high-frequency display,) and network at 20 Hz (if you're on low-quality networking or whatever.)

So, for this case, I highly recommend a higher simulation rate, where, each time you want to display a new frame, you step simulation until the simulation time has caught up to the display time. (This means your display time counter and your simulation time counter are separate, of course!)

A typical loop looks something like:

while (gameRunning()) {
  timeNow = displayTime();
  while (networkInput.length > 0) {
    dealWithNetworkInput(networkInput.shift());
  }
  while (timeTime < timeNow) {
    simulateOneStep();
    simTime += SimulationTimeStepSize;
  }
  displayOneFrame();
}
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement