Getting The Game Loop Right

แชร์
ฝัง
  • เผยแพร่เมื่อ 6 มิ.ย. 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
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 90

  • @boldizsarszabo
    @boldizsarszabo 2 วันที่ผ่านมา +1

    Thank you for this! Also thanks a bunch for listing all the reading material, I'm creating a simulator for a uni project and I would be lost without this

  • @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.

  • @manapotion1594
    @manapotion1594 3 ปีที่แล้ว +22

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

  • @LucasAlfare
    @LucasAlfare 2 ปีที่แล้ว +2

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

  • @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 !

  • @MjkL1337
    @MjkL1337 7 หลายเดือนก่อน +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 :)

  • @mikegombos8062
    @mikegombos8062 ปีที่แล้ว +1

    You have a great presentation style. Nice video

  • @tiloiam
    @tiloiam 3 ปีที่แล้ว +1

    Very nice presentation and useful information.

  • @TheAlison1456
    @TheAlison1456 หลายเดือนก่อน +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 4 หลายเดือนก่อน

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

  • @DrewsAbuse
    @DrewsAbuse 5 หลายเดือนก่อน +1

    Thank you, good stuff!

  • @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.

  • @im-anomalies
    @im-anomalies ปีที่แล้ว +1

    thanks, this is literally what i've searched for

  • @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.

  • @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.

  • @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

  • @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.

  • @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.

  • @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?

  • @rebornreaper194
    @rebornreaper194 ปีที่แล้ว +2

    Are step & T-slice not the same value?

  • @user-vw5ex4wf1e
    @user-vw5ex4wf1e 22 วันที่ผ่านมา +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  21 วันที่ผ่านมา

      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/

  • @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()?

  • @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... :)

  • @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 16 วันที่ผ่านมา

      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

  • @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

  • @tenzo7560
    @tenzo7560 ปีที่แล้ว

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

  • @stephenkamenar
    @stephenkamenar 7 หลายเดือนก่อน +1

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

  • @kiryls1207
    @kiryls1207 ปีที่แล้ว +1

    c'è bisogno di più italiani nella comunity inglese

  • @gsestream
    @gsestream 7 หลายเดือนก่อน

    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  7 หลายเดือนก่อน +1

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

    • @gsestream
      @gsestream 7 หลายเดือนก่อน

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

    • @gsestream
      @gsestream 7 หลายเดือนก่อน

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

    • @gsestream
      @gsestream 7 หลายเดือนก่อน

      background updates to various things@@vittorioromeo1

    • @gsestream
      @gsestream 7 หลายเดือนก่อน

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