I accidentally reinvented multiplayer | SRS Devlog 3

แชร์
ฝัง
  • เผยแพร่เมื่อ 5 ส.ค. 2024
  • This is my third devlog for Space Rock Survivors. This time, I get a little bit distracted by an "easy" problem, and end up rediscovering multiplayer code!
    Space Rock Survivors is a brand new roguelike that features authentic Vector CRT graphics. It generally follows the Vampire Survivors formula, but has a few neat twists of its own.
    This game is available on Itch in its current form:
    sdggames.itch.io/space-rock-s...
    Feel free to check out the game's source code:
    gitlab.com/sdggames/srs
    I also have a Discord server! / discord
    __________________________________________________
    00:00 Intro
    01:39 Attempt 1: GODOT, WHY???
    02:42 Randomness!
    04:14 Physics!
    04:36 Attempt 2: Try harder
    05:22 Throwing it all away
    05:57 If I call it done, is it done?
    06:44 Eureka!
    07:54 Final solution, meet the puppeteer!
    10:13 Conclusion
  • เกม

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

  • @htspencer9084
    @htspencer9084 6 วันที่ผ่านมา +1

    So its basically internal RPCs? Very interesting concept!
    A few things for people who are interested in this topic could look at:
    Command Game Design Pattern
    seeds in your random number generator
    These won't solve the core issue you were having, being that out of the box Godot 2D physics is not deterministic but they're great resources to make your game more replay friendly.
    Another thing you could do in your case, and I'm sure you're already doing this is perhaps storing the diffs between logging events, as opposed to the entire object each time. Also worth looking at curves/other generalisations to interpolate between longer logging moments, whilst also allowing for "tent-pole" events such as collisions to be logged in between.
    Also, I hope to all that is heavenly that you did the logging on a separate thread!

    • @SDGGames
      @SDGGames  5 วันที่ผ่านมา +1

      Thanks for the pointers. I'm probably going to keep this as a debugging feature for now, so performance doesn't matter (as I can run in Movie Maker mode which ignores framerate). I'll have to look into RPCs more, though. If I need to squeeze more out of the feature, there are definitely a lot of tweaks I can make. It's pretty poorly optimized right now, but it works well enough for the applications

    • @htspencer9084
      @htspencer9084 5 วันที่ผ่านมา

      @@SDGGames that's very valid, an OK enough solution now is far superior to a perfect solution never :)

  • @JacobTeach
    @JacobTeach 24 วันที่ผ่านมา +1

    It's funny because I've always made multiplayer games and that's the solution I would've thought of first. It shows that people with different backgrounds come to very different initial conclusions.

    • @SDGGames
      @SDGGames  24 วันที่ผ่านมา

      Yeah, the process of discovery is interesting. I haven't made a multiplayer game before, so I didn't have that tool in my toolbox yet. I believe that really old games did use captured inputs in their attract modes, which is why I started there.

  • @simco1534
    @simco1534 17 วันที่ผ่านมา

    It kinda sounds like you wanted clips of before and after, which screen capture would've done (and it seems like the original footage used, the cars are out of sync because randomness). But you wanted them to be the exact same so developed multiplayer lol.

    • @SDGGames
      @SDGGames  16 วันที่ผ่านมา +1

      Yup, pretty much 😅

  • @titaniumtomato7247
    @titaniumtomato7247 24 วันที่ผ่านมา

    Shame about the unpredictable physics, nice solution though!

  • @GonziHere
    @GonziHere 24 วันที่ผ่านมา +4

    What you are looking for is determimistic physics btw.

    • @SDGGames
      @SDGGames  24 วันที่ผ่านมา

      Fair enough! I think I would have spent more time making my own physics engine, though :)

    • @Hexcede
      @Hexcede 14 วันที่ผ่านมา

      @@SDGGames Another thing you could do for physics is just interpolate some samples of the position. Essentially your puppeteer code, but you only save the position/rotation every so often, and then you can linearly interpolate the state. This also applies to other values, so long as they are continuous values that are changing in small amounts over multiple frames like position and rotation. E.g. sudden changes in position, velocity, etc can break it and requires more samples at those points (when the instantaneous change happened).
      If something teleports, you obviously want that mechanic to be preserved, so deciding when you would interpolate something is definitely a factor to consider though it can be automatically determined in a number of ways such as testing if linearly interpolating the value would actually reproduce similar results during the recording stage (so you don't linearly interpolate stuff when it would produce visual discrepencies above some threshold) or simply manually specifying what things should be interpolated and which ones shouldn't.
      Things like the thruster animation can technically be ""interpolated"" too if you encode them as a continuous value, for example encoding the state of the thruster as a function of time (rather, you would be encoding the thruster animation in a way that allows you to interpolate time and derive the animation frame from the time). Obviously, this isn't necessary in this case because this is deterministic behaviour, plus it has a very low impact when it's not quite in sync, but, it does express how versatile interpolation can be for reproducing a lot of complicated game behaviours in a replay.

  • @cvabds
    @cvabds 22 วันที่ผ่านมา

    I bet you can't do that on templeOS haha, I will only subscribe to you if you like this and confirm that

    • @SDGGames
      @SDGGames  22 วันที่ผ่านมา

      I think templeOS support is the number 1 priority for Godot's development team right now...

  • @RightInfinity
    @RightInfinity 24 วันที่ผ่านมา

    Your first approach, recording inputs and fixed RNG, is essentially how Doom handles it's demos and multiplayer. Why it didn't work for you, I can only guess.

    • @SDGGames
      @SDGGames  24 วันที่ผ่านมา +1

      Yeah, I think it was a timing issue. The physics engine determines when events happen, which determines the order in which numbers are consumed. I think Doom was simpler in its physics, I'm trying to work with a physics engine that I didn't write.

  • @du0lol
    @du0lol 24 วันที่ผ่านมา

    Couldn't you just make a pseudorandom number generator like in Doom? That way you'd be able to keep track of every "random" number in your game, which is how demos work in Doom.

    • @SDGGames
      @SDGGames  24 วันที่ผ่านมา

      That was the first approach. The problem is that the physics aren't deterministic, so I can pull a number off of the generator a frame early or late compared to the recording. If two events happen "simultaneously," they will trade numbers on different replays, causing events to diverge.
      Doom had the benefit of an in-house physics engine that could be shaped to fit the RNG tools. I'm using Godot's default physics, which don't appear to work exactly the same way twice.

    • @du0lol
      @du0lol 23 วันที่ผ่านมา

      @@SDGGames oh, I guess it went over my head during the vídeo, then. I thought you'd start by setting a look-up table (like in Doom) to drive the random number generator, só that's why I thought you hadn't tried it. Thanks for clarifying though! Also, very cool idea.

    • @SDGGames
      @SDGGames  22 วันที่ผ่านมา +1

      @@du0lol Yeah, I was relying on fixed-seed randomness, so no need for a LUT. The numbers are generated as they are consumed, but the state guarantees that the numbers are the same each time. If I wanted, I could print them to a table, and see what the next number would be.