Getting The Game Loop Right

Поділитися
Вставка
  • Опубліковано 22 тра 2024
  • Writing a game from scratch? You're going to need a game loop! This video explores a few approaches, gradually increasing in complexity.
    Further reading (highly recommended!):
    - gafferongames.com/post/fix_yo...
    - dewitters.com/dewitters-gamel...
    - gameprogrammingpatterns.com/g...
    My website:
    - vittorioromeo.info
    Donations (thanks!):
    - paypal.me/romeovittorio
    - / vittorioromeo
    Check out my games:
    - openhexagon.org
    - vittorioromeo.info/quakevr
  • Наука та технологія

КОМЕНТАРІ • 89

  • @manapotion1594
    @manapotion1594 3 роки тому +22

    This is a great format. I'd love to see more videos like this one

  • @ChaoticTrack
    @ChaoticTrack 5 місяців тому +4

    [1:20]: Consider using a monotonic clock instead of the system time. Time synchronization (e.g., via the Network Time Protocol (NTP)) can make the system clock jump forward or backward at any point, and leap second smearing can change the length of each second to account for leap seconds.

  • @OmarChida
    @OmarChida 3 роки тому +5

    Great job! I definitely want to watch more videos like this

  • @lucasvdavid
    @lucasvdavid 3 роки тому +6

    Hope you’ll continue, I follow you since your talk on ECS and you do really great !

  • @LucasAlfare
    @LucasAlfare 2 роки тому +2

    Loved this deep explanation about loops! Keep going on it, man ^^

  • @mikegombos8062
    @mikegombos8062 Рік тому +1

    You have a great presentation style. Nice video

  • @tiloiam
    @tiloiam 3 роки тому +1

    Very nice presentation and useful information.

  • @MjkL1337
    @MjkL1337 6 місяців тому +2

    this is exactly what I needed. thank you so much!

  • @usamaalshughry4967
    @usamaalshughry4967 Рік тому +11

    Your sfml and modern c++ videos where what inspired me to start making video games, something that helped me cope with hard times. I am so happy that youtube suggested this video to me today, as informative, nicely demonstrated as always

    • @vittorioromeo1
      @vittorioromeo1  Рік тому +3

      It makes me really happy to hear that I had a positive impact on your life! Glad you enjoyed the video, and keep it up :)

  • @TheAlison1456
    @TheAlison1456 23 дні тому +1

    5:20 wow. This time rate thing is fascinating!!!
    6:10 I like this pseudocode.
    8:10 I liked the graphics. There was Exactly the necessary amount of graphics. No more, no less.
    I would've liked to see the tick rate thing and how that "solves" some of the aforementioned problems. Instead you just move on to the pseudocode and final statements.

  • @numv2
    @numv2 3 роки тому +2

    Excellent ! Thanks

  • @IkaraySG
    @IkaraySG 3 місяці тому

    I knew I recognized this clock. That gaffer article is super useful

  • @DrewsAbuse
    @DrewsAbuse 4 місяці тому +1

    Thank you, good stuff!

  • @OcteractSG
    @OcteractSG 2 роки тому +4

    This was very educational.
    I do have to wonder, though, about the draw function causing the loop to encounter mistimings. For example, suppose the game logic runs every 10 ms (i.e., t-slice = 10ms) and it takes 5ms for the draw function to execute. If the draw function is called when the accumulator is at 7ms, the game logic will be 2ms late on the following iteration.
    It almost seems like the answer is to run the game logic in one thread and handle the graphics in another that only reads the game logic’s memory. Unfortunately that isn’t feasible on every CPU, and I’m not sure what other issues such a design would encounter.

  • @yDarkVoid22_
    @yDarkVoid22_ Рік тому +2

    I really liked the video, but I still have to learn more about game logic, so it i'd be really cool if i could find more videos like this. btw thank you for the explaining.

  • @douggale5962
    @douggale5962 Рік тому +1

    I am focusing on the keyboard and mouse being read at 240Hz, regardless of the framerate, and feeding a render thread to decouple it from rendering, without preventing input during long frames. Desktop environments give you a timestamp on each event of the input queue.

  • @im-anomalies
    @im-anomalies Рік тому +1

    thanks, this is literally what i've searched for

  • @navi0548
    @navi0548 2 роки тому +1

    love this.

  • @mradchemseddine9965
    @mradchemseddine9965 3 роки тому +6

    Great explanation as usual. Thanks. Now, some modern C++ implementation if you please

  • @JuanFarineliFumis
    @JuanFarineliFumis 6 місяців тому +2

    could you tell me how to learn more about this rendering interpolation that you said? i am looking but i cant find.
    im thinking in let my tick rate be more or less 60, but my refreshrate is 165 everything is very jittered

  • @rebornreaper194
    @rebornreaper194 Рік тому +2

    Are step & T-slice not the same value?

  • @JuanFarineliFumis
    @JuanFarineliFumis 6 місяців тому +1

    My game still with a very little speed changes when tick rate change.
    I mutipliyed inside of update movement += speed*Time step;
    and then in drawn i added movement to X of my square. (that is a INT)
    and now the movement is almost the same but isnt the same, higher the tick rate higher he accumulate speed and win the race between the two squares.
    i dont know if the difference is from long, double and int conversors, or if is related to my drawn and update been separeted one from other.
    The thing is, when my object get out of right side of screen i make it back to 0. And i think that because of the accuracy and because of the more constants updates when 165 ticks it got teleported before to 0 then the other one with 30 ticks, and then it starts to accumulate speed before than the 30 one, and most the time that passes more the difference become bigger.

  • @Apreche
    @Apreche 2 роки тому +4

    Terrific video. Presentation makes perfect sense.
    I have one question. Let's say someone has a low fps and therefore you have to call update five times in a single game loop. Wouldn't this make it so that frame-perfect inputs from the player are no longer possible? The way I understand it is if they press a button any any time during that particular loop, that button will register as being pressed for all five of those updates.
    Is there something I'm missing, and this isn't actually a problem? Or maybe it is a problem, but there's another solution? Thanks.

    • @vittorioromeo1
      @vittorioromeo1  2 роки тому +3

      Thank you, I am glad you liked the video.
      You are correct in saying that one possibility is having the input being registered as "held down" for the duration of all those five updates. An alternative would be registering it as such only for the first update. Nevertheless, you are right in saying that frame perfect inputs would not be possible with that system.
      First of all, is that even a problem? How low does the FPS have to be to have 5 updates per frame? It sounds like this is a edge case of a user with a very unpowered PC.
      If your game is designed around frame-perfect inputs and you want to support users with extremely low FPSs, then you can have a limit of updates per frame and slow down the game simulation when the limit is reached. That also has its own disadvantages.

  • @user-vw5ex4wf1e
    @user-vw5ex4wf1e 7 днів тому +1

    Hello, great video!
    However your first source seems odd to me when it mentions interpolating states using the leftover time in the accumulator.
    Say the accumulator holds 2.3 time units (which means your simulation is behind by that amount), and dt is 1.0, then the accumulator will be left with 0.3 units after 2 updates. Then there is an interpolation between currentState (state at the second update) with previousState (state at the first update) using a factor of alpha = 0.3, but the currentState is actually 0.3 units in the past (loop condition is accumulator >= dt ) not in the future so doing this interpolation makes no sense to me. Any info?

    • @vittorioromeo1
      @vittorioromeo1  7 днів тому

      This discussion on Reddit should help you understand why the interpolation can be useful:
      old.reddit.com/r/gamedev/comments/10bs23m/gaffer_on_games_fix_your_timestep_question/

  • @tobiasp.6717
    @tobiasp.6717 Рік тому

    When I apply that deltaTime, the problem is now the exact opposite, when I render many objects and my FPS is low, the objects seems to be very fast, while theyre quite slow, when having high FPS (fewer objects rendered). What might be the issue? Is that the effect of indeterminism you mentioned?

  • @thenieznany
    @thenieznany 3 роки тому +1

    nice! :3

  • @antoniocs8873
    @antoniocs8873 2 роки тому +2

    Thanks for this video. I think it's great and the animations look nice, but to be honest if it takes you a long time to do these, why not just do them in your previous format?
    Where you have various files with code and you just show one after the other? I really enjoyed those videos. The code was simple and easy to follow and so were the transitions between code files.
    Not taking anything from this video, it's really well done and everything flows nice but if you want to produce content I believe just using your previous format of c++ files would be more than enough (there would be no drop in quality in my opinion).

    • @vittorioromeo1
      @vittorioromeo1  2 роки тому +1

      Thank you for the feedback. I am glad you enjoyed the video.
      I think you do have a point -- the effort required to make a video like this might not be justified, if I can convey the same information with a simpler format.
      Nevertheless, I think it was an interesting experience, and a fully animated video like this one can be much better than a "traditional" one for visual learners. We'll see... :)

  • @anonymus496
    @anonymus496 3 роки тому

    Just for clarification this is all under the assumption, that update() is faster than draw()?
    Your points should still all be correct i think, and i don't think, that it will cause any problems besides the games fps beeing slow or slowing down until it's not playable anymore.
    And this should be easier to fix with (especially with a minimum) unknown hardware than draw()?

  • @leonardopo6202
    @leonardopo6202 Рік тому

    in the last example can someone please explain to me what the step variable is and how the update function si designed? thank you

    • @vittorioromeo1
      @vittorioromeo1  Рік тому

      The 'step' parameter of the 'update' function is the same as 'delta time' -- it works exactly in the same way. The only difference is that 'step' is always a fixed value decided by the developer, it doesn't change with the framerate of the game.
      You can imagine 'update' being a function that takes a floating point number (call it 'dt', 'deltatime', 'step', etc...) and then uses that number to scale the speed of transformations/logic in the game. E.g.
      void update(float step) { player.position = player.position + player.velocity * step; }

  • @MudHoleCreation
    @MudHoleCreation 2 роки тому

    Curious, do you have your "GetInput()" inside the while or before?

    • @vittorioromeo1
      @vittorioromeo1  2 роки тому +2

      In Open Hexagon, I call `getInput` outside of the update while loop, once per frame.

    • @sirsneakybeaky
      @sirsneakybeaky 2 дні тому

      My inital reaction was to put the game loop and draw in their own threads and while loops.
      Gameloop has a pointer to a memory block that holds the active input at is at a 20.
      But fps and input can run to narnia or what ever set.

  • @PurplePotatoBro
    @PurplePotatoBro 7 місяців тому +1

    i still dont understand but cool

  • @tenzo7560
    @tenzo7560 Рік тому

    i feel like I learned a lot but nothing at the same time lol

  • @6666BLACKSATAN
    @6666BLACKSATAN 11 місяців тому

    what is t_slice?

    • @JuanFarineliFumis
      @JuanFarineliFumis 6 місяців тому +1

      is the ammount of time that you want to pass between updates.
      for example if your timer (or method to measure time) is in miliseconds (ms) and you want to update 60 times per second so your t_slice will be 1000 miliseconds (1sec) divided by 60, and it will be 0016,6666...7
      this is slice, the amount of time that you slice to fit in your update frequency

  • @kiryls1207
    @kiryls1207 Рік тому +1

    c'è bisogno di più italiani nella comunity inglese

  • @stephenkamenar
    @stephenkamenar 6 місяців тому +1

    it's impossible to get a game loop right on windows.

  • @gsestream
    @gsestream 6 місяців тому

    this is wrong, both update and draw should be concurrent, in their own double buffering, not just the update->draw cycle, your design leads to single threaded mess, unreal

    • @vittorioromeo1
      @vittorioromeo1  6 місяців тому +1

      Not every game needs concurrent double-buffered update/draw separation. What you're suggesting adds a lot of often unnecessary complexity.

    • @gsestream
      @gsestream 6 місяців тому

      your "one universal truth" is not a truth, and you are very single threaded, mind you@@vittorioromeo1

    • @gsestream
      @gsestream 6 місяців тому

      you gonna be waiting for the graphics or updates to finish, so wasting cycles@@vittorioromeo1

    • @gsestream
      @gsestream 6 місяців тому

      background updates to various things@@vittorioromeo1

    • @gsestream
      @gsestream 6 місяців тому

      almost every engine does this, so what you suggest is regressing to old past that does not need to be there@@vittorioromeo1