Unity Physics Based Networking

Hi,

I am currently developing an online competitive sports game. The game uses vehicles as players and features a lot of heavy physics for collisions and projectiles. It relies on accurate physics (bounces/pushing, moving environment and players) across all players in the game.

I have experience using Photon Cloud to great success previously but it is not suitable for this game due to requiring authoritative physics. Photon Server is sadly just a little too complex for my liking as this is a hobby project. So my question is: Is Bolt suitable for this type of game? I can find lots of information about Bolts setup, use of authoritative listen servers etc

Any experience using Bolt for this style of game would be great to hear about.

Thanks,

Static

Best Answers

Answers

  • Stanchion - could you please elaborate a tiny bit more?

    If my player was being controlled simply using translations (instead of using forces) and two players moved into each other, bouncing off in different directions but still moving themselves via controls. Your saying the movements would be networked correctly? Whereas if it was physics forced based controls they would not be handled correctly?

    Thanks

    Static
  • Sippolo
    Sippolo
    edited November 2015
    Edit: sorry I just noticed this thread was already answered. I have posted something related to this thread here hoping for an answer: http://forum.photonengine.com/discussion/comment/25785/#Comment_25785
  • "Physics should work fine as long as your player controller isnt physics based or rigidbody"

    Sorry to jump in here (please let me know if proper etiquette is to start a new thread) - but what if my player controller is physics based and a rigidbody?

    if (CFInput.GetKey(KeyCode.W)) {
    therigidbody.AddRelativeForce (Vector3.forward * (Level_Status.engine)); ... etc

    Since I am applying "thrust" to a vehicle of a certain weight, I can't just translate it.
  • You can use physics and basically do anything you want if you are client authoritative. Client authoritative is almost like doing a single player game.

    Server authoritative you can also use physics if you don't use client side prediction. It is not possible to use server authoritative movement with client side prediction with rigid bodies for a variety of reasons.

    If you don't use client side prediction but are server authoritative you will have connection dependent input lag. I wouldn't recommend this for games that are racing centric as it will feel bad to the players.

    I doubt there has ever been a server authoritative AAA racing game for good reason. I would just use client authoritative movement.
  • I see, so if I am following the local wi-fi co-op route with one device starting the server and everyone else joining the game (sitting on the couch or nearby) then it should be fine.

    Thanks for the clarification - I ask because in another post I was having client problems and then saw this.
  • Sippolo
    Sippolo
    edited February 2016


    I doubt there has ever been a server authoritative AAA racing game for good reason. I would just use client authoritative movement.

    To my knowledge Rocket League uses 100% authoritative server movements with client side prediction, and there's certainly physics in there.
    They either got predictable custom physics or do black magic.
    I think you just can't use Unity's built-in physics for server authoritative movements, you have to roll your own predictable/deterministic physics engine so you can exactly rewind/predict its state with a certain accuracy.

    Still that would be better than doing client authoritative movement as it fails hard when it comes to prevent cheating, doesn't it?

    This is a useful non-engine based blog series about fast paced multiplayer game development: gabrielgambetta.com/fast_paced_multiplayer.html
    Everyone should read this before utilizing any networking engine like Bolt or UNET, it's the basic knowledge you should acquire before pointing your finger at some likely non existent bug in these engines (and I was one of them, blaming Bolt for some lack of physics based networking capabilities...).

    EDIT: found an interesting AmA from RL developer talking about their physics based networking solution if anyone is interested: https://reddit.com/r/IAmA/comments/3re82v/were_psyonix_developers_of_rocket_league_ask_us/cwn9ba2
  • DirtyHippy
    DirtyHippy ✭✭
    edited February 2016
    Yes sure if you replace unity physics with your own deterministic physics implementation you can do that. I simply don't mention it because it is way, way outside the capabilities of most developers.

    And rocket league doesn't appear to be fully client predictive/server authoritative. From this reddit post: https://m.reddit.com/r/RocketLeague/comments/4291ey/is_cheating_rampant_on_this_game/

    It looks like they predict client movement, but the simulation still runs completely on the server. This line "If you experience a constant 200 ms ping in Rocket League, it generally manifests itself as a slightly slower response curve in your acceleration and turning. On your screen, you'll start accelerating at the same rate as anyone else, but because your action hits the server 200 milliseconds later, eventually your car will be corrected (albeit somewhat gradually) to the correct location."

    It looks like they let the client move immediately (just so input lag doesn't feel bad) and lerp the client back to the server's position. In a truly predictive environment the simulations would match up because they are running deterministic simulations.

    I'm surprised players dont notice this more and complain - I guess at 200ms rtt with some fake client prediction it doesn't feel bad. That is good news, because eventually I was going to try adding vehicles like this.
  • So I found another thread where they say something different. Honestly, I am not an expert on the underlying implementations here. But unless they have a deterministic simulation there is no way to roll back to a state correction and re-apply inputs in a way that guarantees the simulations remain in sync. So who knows to be honest. This question is more of a fholm question.
  • So I've been doing some more reading, because I am intrigued. Mainly I was looking for reports of players reporting teleports and other stuff which would imply violent corrections are occurring. This would imply to me they might actually be doing client side roll back without deterministic physics, which probably means they used non-deterministic rigid body physics and is what I expect would happen in some situations. I see lots of reports of teleports in their forums, but watching videos on high speed multi-car collisions (where I would expect the physics to diverge), I am not seeing anything overly bad. So who knows.
  • DirtyHippy
    DirtyHippy ✭✭
    edited February 2016
    [Ignore - duplicate post]
  • Even if you have a deterministic physics engine there is no guarantee it'll be deterministic across local processes let alone different machines. Because of floating point precision, rounding errors and such, there will always be some degree of error. So while it's important to try and minimize error in the first place (with a more deterministic physics simulation) it seems more important on how you handle errors. Unity is a huge pain when it comes to this (not because it isn't deterministic... even though that does contribute) but because it doesn't allow you to roll back frames. Time always steps forward and you can never roll back the simulation and test for collisions while not passing any time. It just simply doesn't let you do it. So a proper clientside prediction type model can never be 100%. But there's heaps of ways around it. I assume how they go about it in RocketLeague is that the ball is server owned, and when a player hits or interacts with the ball and force the apply gets predicted on the clients end and as the ball moves it simply lerps to where the server knows it to be exactly.
  • See this is the part I don't get. If the cars are rigid bodies, it is easily possible that the server could generate a radically different collision response for your car based on a tiny simulation difference, and on the server your car spins off in one direction and on your machine because of your prediction you spin off in another. No amount of lerping can make this feel good and at some point you have to just say screw it and snap them back anyway. Is this a wrong assertion?
  • There should be many more of these kind of discussions, I wish there would be experts coming out and contributing to this topic, oh well.

    Rolling your own physics is not THAT hard actually (there is a great course on that topic here by the way: https://udemy.com/gamephysics/ ), but indeed it adds lots more work to do for most developers.
    Of course it doesn't need to be 100% deterministic (don't even know if that'd be feasible), you could work around the errors, but I believe the fact that you can rewind a physics state is vital for physics based server authoritative multiplayer.

    See this is the part I don't get. If the cars are rigid bodies, it is easily possible that the server could generate a radically different collision response for your car based on a tiny simulation difference, and on the server your car spins off in one direction and on your machine because of your prediction you spin off in another. No amount of lerping can make this feel good and at some point you have to just say screw it and snap them back anyway. Is this a wrong assertion?

    Great question...I still don't get how a good client side prediction and server reconciliation is done when dealing with physics collisions.
  • See this is the part I don't get. If the cars are rigid bodies, it is easily possible that the server could generate a radically different collision response for your car based on a tiny simulation difference, and on the server your car spins off in one direction and on your machine because of your prediction you spin off in another. No amount of lerping can make this feel good and at some point you have to just say screw it and snap them back anyway. Is this a wrong assertion?

    The trick is to ensure then that the difference between the two simulated states can't grow too big.
    In a situation like that the server would have to say "Yo client, I'll be back in 5 seconds to check how you are". Wait too long, the difference grows exponentially and the snap back will be horribly inorganic and break the feel of the game. Close the gap down by checking results every few frames and overriding the players state and then replaying. This is exactly what bolt does, the only reason why this works on CharacterControllers and not rigidbodies is because the CharacterController component can move and check multiple collisions in a single frame (essentially allowing you to rewind and play the player) while, currently, rigidbodies can't do this.
  • Manmax75 said:

    See this is the part I don't get. If the cars are rigid bodies, it is easily possible that the server could generate a radically different collision response for your car based on a tiny simulation difference, and on the server your car spins off in one direction and on your machine because of your prediction you spin off in another. No amount of lerping can make this feel good and at some point you have to just say screw it and snap them back anyway. Is this a wrong assertion?

    The trick is to ensure then that the difference between the two simulated states can't grow too big.
    In a situation like that the server would have to say "Yo client, I'll be back in 5 seconds to check how you are". Wait too long, the difference grows exponentially and the snap back will be horribly inorganic and break the feel of the game. Close the gap down by checking results every few frames and overriding the players state and then replaying. This is exactly what bolt does, the only reason why this works on CharacterControllers and not rigidbodies is because the CharacterController component can move and check multiple collisions in a single frame (essentially allowing you to rewind and play the player) while, currently, rigidbodies can't do this.
    Yes, good point, in bolt the state would be reset often. But I'm not sure what this would solve. Since your car now likely has significant angular and rigid body velocities that are incorrect, even in a few milliseconds reaction, when the new state reset comes in, you will be reset back to a position, and replay your movement, presumably which don't work like a character controller but rather introduce forces to the rigid body, which would then add on top of the rigid body's current cumulative forces that acted on it from before (from your client side collision). You could sync over the server's rigid body metadata for that reset state action, so in essence "reset" the client state to the rigid body forces the server thinks it should be. Then you replay your movements, which re-add the forces to it. But rigid bodies only get evaluated for collisions in fixed update, so I am not sure how you can replay your movements and get accurate collision detection and response? Ugh. I definitely need to sit down with some paper and really understand how this stuff works.

  • Sippolo
    Sippolo
    edited February 2016
    This could be relevant to the discussion.
    Yesterday I played a bit of Rocket League, and noticed what happens during collisions with the ball.
    At some point there was a player's car hitting the ball, on my client I clearly saw the ball hit, then moving correctly towards the normal of the collision (away from the car), then few moments later the ball just lerped to its original trajectory again as if the collision never happened, because there wasn't any collision on the server side.
    All of this was very noticable and my ping was of 30ms, my client's physics simulation was clearly not in sync with the server and got corrected in few ms time, yet it didn't disrupt the game flow at all.
    There was a goal after that, and the replay showed the ball wasn't hit at all, I guess all replays just mirror the server side gameplays.
  • Manmax75 said:

    See this is the part I don't get. If the cars are rigid bodies, it is easily possible that the server could generate a radically different collision response for your car based on a tiny simulation difference, and on the server your car spins off in one direction and on your machine because of your prediction you spin off in another. No amount of lerping can make this feel good and at some point you have to just say screw it and snap them back anyway. Is this a wrong assertion?

    The trick is to ensure then that the difference between the two simulated states can't grow too big.
    In a situation like that the server would have to say "Yo client, I'll be back in 5 seconds to check how you are". Wait too long, the difference grows exponentially and the snap back will be horribly inorganic and break the feel of the game. Close the gap down by checking results every few frames and overriding the players state and then replaying. This is exactly what bolt does, the only reason why this works on CharacterControllers and not rigidbodies is because the CharacterController component can move and check multiple collisions in a single frame (essentially allowing you to rewind and play the player) while, currently, rigidbodies can't do this.
    Yes, good point, in bolt the state would be reset often. But I'm not sure what this would solve. Since your car now likely has significant angular and rigid body velocities that are incorrect, even in a few milliseconds reaction, when the new state reset comes in, you will be reset back to a position, and replay your movement, presumably which don't work like a character controller but rather introduce forces to the rigid body, which would then add on top of the rigid body's current cumulative forces that acted on it from before (from your client side collision). You could sync over the server's rigid body metadata for that reset state action, so in essence "reset" the client state to the rigid body forces the server thinks it should be. Then you replay your movements, which re-add the forces to it. But rigid bodies only get evaluated for collisions in fixed update, so I am not sure how you can replay your movements and get accurate collision detection and response? Ugh. I definitely need to sit down with some paper and really understand how this stuff works.

    I think that comes down to semantics though and how you actually make your controller under the hood. Unity supports changing a rigidbodies velocity per physics frame rather than having to add a cumulative force. Check this out : http://docs.unity3d.com/ScriptReference/ForceMode.VelocityChange.html
    Also zeroing out or directly setting the velocity and angular momentum works as well (although they advise against it in the wiki purely because in most normal cases it produces undesired results). But yeah, doing this won't really work well because you can't simulate a rigidbody multiple times a frame. Its useful to try and design around these flaws. Sometimes you can get around this by just resorting to a character controller and using a capsule collides. Obviously this limits your options a lot.
    Alternatively, there are a number of 3rd party physics solutions out there and they're not *too* hard to implement, sometimes they just come with the tradeoff of preformance, as you'd expect from using a plugin over an integrated solution. Unfortunately until unity does something about all this, there is not much that can be done. Perhaps return to the drawing board and really look at the mechanics of the game or project you're working on. Ask yourself questions like does it really need the authoritative movement, etc. It's worth noting that a lot of games don't use a full authoritative setup, and opt for a semi-authoritative setup.


  • I think that comes down to semantics though and how you actually make your controller under the hood. Unity supports changing a rigidbodies velocity per physics frame rather than having to add a cumulative force. Check this out : http://docs.unity3d.com/ScriptReference/ForceMode.VelocityChange.html
    Also zeroing out or directly setting the velocity and angular momentum works as well (although they advise against it in the wiki purely because in most normal cases it produces undesired results). But yeah, doing this won't really work well because you can't simulate a rigidbody multiple times a frame. Its useful to try and design around these flaws. Sometimes you can get around this by just resorting to a character controller and using a capsule collides. Obviously this limits your options a lot.
    Alternatively, there are a number of 3rd party physics solutions out there and they're not *too* hard to implement, sometimes they just come with the tradeoff of preformance, as you'd expect from using a plugin over an integrated solution. Unfortunately until unity does something about all this, there is not much that can be done. Perhaps return to the drawing board and really look at the mechanics of the game or project you're working on. Ask yourself questions like does it really need the authoritative movement, etc. It's worth noting that a lot of games don't use a full authoritative setup, and opt for a semi-authoritative setup.
    Oh, well, I'm using server auth/client prediction with a character controller and everything works fine. My interest was more academic. Interesting stuff!
  • I know that a lot of people frequently ask the Unity team about this and in late 2014 with the announce of Unity 5, Im fairly certain one of the devs said they were hoping to get the rewinding/resimulating of physics in one of the 5.x.x releases.