Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Netcode server and client delta times not synced?

Discussion in 'NetCode for ECS' started by WireWhiz, Jul 30, 2020.

  1. WireWhiz


    Apr 17, 2019
    Hey everyone, I've been trying to figure out why a movement system I've been building is supper laggy feeling and I'm 99% sure it's because of deltaTime. The default cube example in the getting started section of the netcode documentation just uses Time.DeltaTime so I thought this was the way to go. I assumed that the delta times would be corrected for the fact that the server runs prediction less times then the client.

    But I wrote some code that allowed me to see the difference between the client prediction and the server prediction of my controller and they were way off. Curious I wrote a simple script that just added delta time to a float every time the prediction was run and boy was I surprised, a ran it for a bit my server accurately counted 31.36 seconds while my client counted 392.93 seconds. That doesn't even make sense taking into account the fact that the server is running (I'm guessing) at a fixed 60 fps and my client is running at 90fps.

    Is there a premade way to get a normalized/fixed delta time that will work for both? Or will I have to write a simple timer function to get it?
  2. TRS6123


    May 16, 2015
    Generally any variable you want to apply prediction to should be synced between server and client. Prediction code is run more times on clients than the server.
  3. WireWhiz


    Apr 17, 2019
    I already have all the variables I need syncing through the server but to be able to accurately predict player movement I need a consistent delta time and for some reason the delta time on the client is wrong. Without this I would have terrible rubber banding.
  4. tertle


    Jan 25, 2011
    Unless you make your client use the same fixed update as server, why would the delta time between client/server be the same?

    Often server runs at some fixed update, 1/60, and client runs at highest update rate possible (say 1/144)
    Last edited: Jul 31, 2020
    Lukas_Kastern likes this.
  5. WireWhiz


    Apr 17, 2019
    I don't need it to be exactly the same, just close enough that it doesn't cause rubber banding when the server updates the player transform. What I'm currently trying to do is to use movement code similar to this: inside of a system running in the GhostPredictionSystemGroup. The game I'm building will have high movement speeds so it's important that the movement is responsive and has as little lag as possible. Currently, I'm storing the velocity in a component on my player and it is networked through the GhostAuthoringScript. The problem is that the movement code on the server and the player are spitting out vastly different results for the same input because of the deltaTime variable being off for whatever reason. I was able to come up with a way to get the true delta time for the system then divide it by the number of time the system was updated the last frame to get a useable value. It removed most of the rubber banding but there are still a few glitches.

    Is there a better way to go about what I am trying to do? I'm pretty sure that the movement system math is used in Titanfall and it doesn't have any problems with high-speed low lag gameplay.

    PS: Anyone know why the GhostPredictionSystemGroup runs around 12-15 times every frame on clients?
  6. Kelevra


    Dec 27, 2012
    @lightningelijah Hello! What quantization factor is used for your velocity, translation, rotation parameters?

    You had such a difference in the accumulated delta because of resimulation, the client is always resimulate from the last received tick. Not an ideal solution but it's all we have... usually it should be done only when an error occurs.
    Of course, you can implement your own rollback system :)

    Considering these two pieces of code if you are using Time.DeltaTime then everything should be ok... because it's constant during ghost prediction except for last tick.

    Code (CSharp):
    1. var previousTime = Time;
    2.                 var elapsedTime = previousTime.ElapsedTime;
    3.                 if (simulationSystemGroup.ServerTickFraction < 1)
    4.                 {
    5.                     --targetTick;
    6.                     elapsedTime -= simulationSystemGroup.ServerTickDeltaTime * simulationSystemGroup.ServerTickFraction;
    7.                 }
    9.                 for (uint i = oldestAppliedTick + 1; i != targetTick+1; ++i)
    10.                 {
    11.                     uint tickAge = targetTick - i;
    12.                     World.SetTime(new TimeData(elapsedTime - simulationSystemGroup.ServerTickDeltaTime*tickAge, simulationSystemGroup.ServerTickDeltaTime));
    13.                     PredictingTick = i;
    14.                     IsFinalPredictionTick = (i == serverTick);
    15.                     base.OnUpdate();
    16.                 }
    18.                 if (simulationSystemGroup.ServerTickFraction < 1)
    19.                 {
    20.                     PredictingTick = targetTick + 1;
    21.                     IsFinalPredictionTick = true;
    22.                     World.SetTime(new TimeData(previousTime.ElapsedTime, simulationSystemGroup.ServerTickDeltaTime *
    23.                                                                         simulationSystemGroup.ServerTickFraction));
    24.                     base.OnUpdate();
    25.                 }
    Code (CSharp):
    1. float fixedTimeStep = 1.0f / (float) tickRate.SimulationTickRate;
    2.             ServerTickDeltaTime = fixedTimeStep;
  7. WireWhiz


    Apr 17, 2019
    I got it working last night:

    It looks like I had two problems, first I didn't understand the rollback system so I was trying to fix my problems in the wrong way just making my problems worse and making myself look dumb online. Second I was using my current head position to place and set the height of my character controller, adding this to the input buffer so that it can be rolled back seems to have completely fixed the problems I was having. It's working so well in fact that I was able to turn the ping up to 270 and not notice anything different.
    Lukas_Kastern and florianhanke like this.