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. Dismiss Notice

Question Fixed Timestep with dynamic frequency

Discussion in 'Scripting' started by sajjadrad, Dec 18, 2020.

  1. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    I need to run some functions in a fixed timestep but changeable frequency, for this I’m using the FixedUpdate function and as I know the fixed timestep can’t change dynamically but it’s changeable from project settings. I need this to speed up or speed down the calculations for exact syncing with the server clock depending on ping.

    InvokeRepeating doesn’t help me, because it’s not accurate enough.

    Is it a good practice to set Fixed Timestep to 0.001 (1 millisecond)? by this, I can do calculations in the desired steps.

    Example :


    Code (CSharp):
    1. private int frameNumber = 1;
    2. void FixedUpdate()
    3. {
    4.     if (frameNumber % 2 == 0) {
    5.         //Runs every 2 ms
    6.     }
    7.  
    8.     if (frameNumber % 20 == 0) {
    9.         //Runs every 20 ms
    10.     }
    11.  
    12.     frameNumber++;
    13. }

    I’m open to any other options.

    Thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    No. In fact if you do this and then take more than 1ms in your FixedUpdate() your game will instantly chug down to like 5fps movement.

    Let's back up a second. What exactly are you trying to do? Keeping this tight synchronization over a network for a game is generally never done. Motion prediction and estimation is generally used to keep the clients looking good while the authoritative server decides the game outcomes.
     
    SparrowGS and sajjadrad like this.
  3. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    Thanks for reply

    I want to run prediction in a fixed time step same as the authoritative server. The client clock is ahead of the server clock by half of the ping. So when ping is going high the client clock needs to be run a little faster to send user input faster, so the server could have user input to process in tick method.

    Even without a dynamic fixed timestep, I need to run the prediction loop at least in 20ms, as you know default fixed timestep is 50ms. Is 20ms (0.02) ok?
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    We colloquially say that a clock is "running fast" when it displays a time that is ahead of the current time, because that is often caused by the clock having run at a faster speed at some point in the past. But it is not the same as actually running at a faster speed. Maybe that clock was just set to the wrong time.

    You don't need the client to run faster than the server, you need the client to stay ahead of the server by some fixed amount. That's completely different, and there's no obvious reason that it should involve changing your update frequency in any way whatsoever.


    As background, it may also be useful to point out that using FixedUpdate doesn't somehow magically break you out of the main game loop. If you set your fixed update frequency to something faster than your frame rate, that just means that FixedUpdate will get called several times back-to-back (with zero waiting in between) at the appropriate time during each frame. Setting your fixed timestep to 3ms does NOT mean that FixedUpdate will actually run at 3ms intervals in real-time.
     
    sajjadrad and PraetorBlue like this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    indeed, and also almost certainly without network traffic between either.
     
  6. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    First of all, I apologize for using the wrong words. I mean the prediction loop for running faster not the clock.

    This fixed amount depends on the ping. when ping goes high, the prediction loop must be more ahead of the clock to send user inputs at the right time.

    I want to use this practice to handle ping and loss packages (time 29:10):


    The client clock synchronizes with the server by the first game state received and ping time. After that, the client must send ahead inputs depending on the ping. (when the ping goes high, the prediction loop must run faster to get more ahead of the clock and upside down to send the user inputs at the right time.)

    so the FixedUpdate is not a good idea, so how should I handle the prediction loop? As you know, the prediction loop must run in the exact time of the server loop to precise calculation.
     
    Last edited: Dec 19, 2020
  7. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    I'm not super familiar with action-game network-play prediction, but what you're describing doesn't sound plausible. If the game jumps around in time whenever the ping changes, the player is going to notice time distortions on their local machine, which (in an action-based game) seems quite likely worse than any problem it could possibly be solving (it'll screw up player timing as things around them move unpredictably faster and slower).

    Unless maybe you did it very slowly? But then you can only respond to long-term trends in ping, not quick changes.

    And even then, I still don't know why you'd change update frequency, that just doesn't address the issue. Maybe adjust Time.timeScale? (While keeping very careful track of how long you've left it adjusted and where that puts you relative to the server.)

    Also, I'm not sure how you're imagining actually controlling your physics in this game, but notice that prediction implies that you need to retroactively adjust the past when you receive an update and then recompute everything that happened between that update and the current prediction instantly. Which suggests to me that you probably can't safely use FixedUpdate to do any of the things people ordinarily use it for. I'm not even really sure you'll be able to use Unity's physics system at all, but this is rapidly moving beyond my experience, so I can't really do much other than wave a warning flag and say "here be dragons!"
     
  8. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    The client clock doesn't jump around time. the prediction loop runs ahead to send inputs ahead of the server clock to process in the tick.

    Look at this:

    (Screenshot from above video)

    Prediction is processing frame #15 of the client and sends it to the server, by half of the ping, input received by the server, so it can process input in frame #15 of the server.
    when the ping changes the prediction frame must go ahead or slow down (prediction, not client clock and game loop).

    I don't want to change timescale or FixedUpdate frequency. I only want to run some codes in an accurate period.
    The game loop runs in a fixed time, but the prediction loop sometimes needs to run faster or slower to sync with the ping.

    Is there another way to run a function in an accurate period? If FixedUpdate is the option, is it ok to set timestep to 0.02 (I need to sync the loop with server clock which runs in 20ms)?

    I'm sorry if my questions confused you.
     
  9. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    I think maybe using another thread with infinite loop and checking timestamp is a good idea to handle prediction loop.
     
  10. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    That's the core idea behind the main game loop. You go in a loop as fast as you practically can, and update the timer at each step based on how much real time has passed. Unity has already done this for you, and to take advantage of it, all you need to do is define a function called Update.
     
    Kurt-Dekker likes this.
  11. sajjadrad

    sajjadrad

    Joined:
    Jan 19, 2018
    Posts:
    8
    The update is called every frame, The client needs to sync with the authoritative server tick rate in real-time for the prediction calculations. if thread processing runs out of range (because of CPU usage for example), in the received snapshot it will be recalculated and reset the predictions.