Why Every Game Developer Should Use Command Buffers

Поділитися
Вставка
  • Опубліковано 8 січ 2025

КОМЕНТАРІ • 34

  • @LewisCampbellTech
    @LewisCampbellTech 2 години тому +1

    It's interesting how this pattern comes up in so many areas of programming. Nice look at Odin too.
    Minor criicism: I think your mic is much closer to your keyboard than your face. I'm a clicky keyboard user too, so I get it, but it's a bit of a strain to hear you over it.

  • @PaulSwansonIdAu
    @PaulSwansonIdAu 2 години тому +2

    Loved to see Odin in this example, great little language.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      Yeah, it's great for these kinds of things!

    • @PaulSwansonIdAu
      @PaulSwansonIdAu 2 години тому

      @DylanFalconer last time I wrote a command buffer was in C on an 8-bit embedded microcontroller, kind of just discovered it due to necessity, but definitely a nicer implementation here with Odin, the union array is pretty slick.

  • @notiashvili
    @notiashvili 10 годин тому +3

    With my games I have a global array `end_of_frame_tasks` which just collects callbacks and calls them at the end of the frame.
    The callbacks can perform arbitrary logic and their number usually doesn't exceed 100 tasks per frame, so it's not a perf issue.
    To do that in Odin, I guess I'd have to replicate a closure with a function pointer and a buffer with saved context for the function?

    • @ARKSYN
      @ARKSYN 10 годин тому

      You could expand this to be multi-stage and batch the cleanup tasks by the earliest point at which you could execute them. For example, if you're drawing two passes and don't need a resource from the first pass for the second, you could clean that up well before the frame ends.

  • @nukegundie
    @nukegundie 2 години тому +2

    Respect for using vim!

  • @ARKSYN
    @ARKSYN 10 годин тому +2

    Subscribed man, great simple explanation of command buffers, the grocery shopping metaphor was perfect. Maybe an expanded video on queuing commands and batching by priority for a more advanced expansion to this would be awesome. For the really advanced, multi-threaded update/render loops with asynchronous command buffers.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      Those are great suggestions, thanks! I'll touch on more advanced use-cases in the future for sure

  • @rockersgamestudio
    @rockersgamestudio 13 годин тому +2

    Thanks for the video!
    I _just_ wrote a naive debug draw buffer with raylib in C and was storing separate arrays for each type (cube, sphere, grid etc) - using unions will help! Though in C will need to track type...

    • @josephbrandenburg4373
      @josephbrandenburg4373 10 годин тому

      I have a hunch that you could use an array of void* pointers and an array that stores the type of each void*
      Not sure if that's stupid or not lol

    • @blarghblargh
      @blarghblargh 7 годин тому +2

      tagged unions let you figure out the type, then you just cast it.
      the advantage of a separate array for each type is that they're going to be more tightly packed, which will mean more items will fit in the CPU RAM cache at once, and you can handle just that type when looping over the items, which will speed up branch prediction.
      the advantage of a single array of a union type is that you just have the one array, which might be more convenient for your use case (for example if you're copying the data to some other layer, like the GPU, or have to serialize it to disk). but the cost is that your loops will have to dispatch to different bits of handler code for each item in the array, harming branch prediction, and there will be wasted space because each member of a union has the size of the largest union member, and has to add padding to compensate.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      If you are storing pointers, they could be pointing to anywhere - may or may not be an issue depending on fragmentation and array size. Probably not an issue for debug stuff. Not sure what you mean by storing the type of each void* as C doesn't have run time type information

  • @ParksandRecs-x2w
    @ParksandRecs-x2w 3 години тому +1

    I'm going to have to disagree with you there. Buffered commands make sense in some situations and not others. In games that are heavily dependent on server response/lag then buffered commands can desync what you are seeing and what your character is doing making the game almost unplayable. For games like tournament fighting games where moves need to be executed in a precise order in long chains i.e. Tekken, then they make sense.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      That's a different kind of buffered command, but may be implemented using what I show here

  • @Arnoldze
    @Arnoldze 14 годин тому +2

    great concise video. thanks, subscribed.

  • @chimeces
    @chimeces День тому +2

    I haven't looked but isn't this what raylib does internally too?

    • @NeZversSounds
      @NeZversSounds День тому

      What exactly?
      Raylib doesn't provide game loop, only reading inputs, play sounds you make it play and draw things you make it to draw.

    • @chimeces
      @chimeces День тому

      @NeZversSounds the batching that happens when you are calling draw functions with the same draw state, is kind of a command buffer of shapes

    • @lializ_666
      @lializ_666 18 годин тому

      I guess (without looking right now) that is probably just a queue c:
      Command queueing is kinda of different since you're reifying that struct so you can use it whenever.
      There's actually a lot of use cases and is super useful.

  • @Doice68-cu4qp
    @Doice68-cu4qp 17 годин тому +1

    What about doing all of the update and drawing between BeginDrawing and EndDrawing?

    • @DylanFalconer
      @DylanFalconer  2 години тому

      You can do that for simple games/apps. It falls apart when you want to create more complex game loops that have different update timings

  • @Temple_Cloud
    @Temple_Cloud День тому +3

    Nice to the point video.
    Great that it uses Odin and Raylib, make things clear (for me at least).
    Thanks!

  • @josephsmith5110
    @josephsmith5110 17 годин тому +3

    Great video, but I really thought the video was going to go into input buffering, a technique many fighting games employ.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      Someone else mentioned that, too. I didn't think of it, though I'd guess that most games with input buffering use a command buffer or something very similar for it

  • @nil0bject
    @nil0bject 3 години тому

    this is why we don't code like this any more

    • @DylanFalconer
      @DylanFalconer  2 години тому

      We stopped coding altogether

    • @nil0bject
      @nil0bject Годину тому

      @@DylanFalconer you might have, but natural born coders won't

  • @EnriqueSalceda-k4v
    @EnriqueSalceda-k4v 6 годин тому +1

    Everyone and should are red flags to me.
    Also would have been nice to know when and when not to use this.

    • @DylanFalconer
      @DylanFalconer  2 години тому

      You can read between the lines on that.
      I discussed when to use them at 00:06

  • @Scudmaster11
    @Scudmaster11 11 годин тому +6

    Edit out the keyboard thanks

    • @DylanFalconer
      @DylanFalconer  2 години тому

      Thanks, I'll see what I can do in the future