Announcement

Collapse
No announcement yet.

Physics (Bullet) Client-side prediction

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Physics (Bullet) Client-side prediction

    Hey guys,
    for the last weeks I have been working on Client-Side-Prediction for our vehicles, and tried many techniques, but somehow, nothing really satiesfied us.
    We were looking for a solution that fulfills the following requirements:

    -Server Authoritve | Client does not determine his own position autonomously
    -No Input Latency | As a fast-paced racing multiplayer game, input latency is no option. When the player presses a key, he should see the results immeditaley
    -Synchronousity (Don't think I spelled that right, I apologize for my english) Although the Client has to predict his own future for the roundtriptime, all objects should be corrected to the same moment in time as fast as possible, to avoid confusion in aiming and driving mechanics, when ping changes occur

    As I mentioned, I tried dozens of techniques, but then realized, we need Rewind&Replay for Physics.
    And so I implemented it. Well, I currently am still implementing it, it required me to dig deep into the engine code, but the results look good so far, but far from being perfect yet (some errors in my implementation in the Replay, but the generall system is working).

    I was wondering if anyone else of you ever implemented something similar and if you want to share your experience. As soon as I have a result good enough to show, I will of course try to share my 'knowledge", if there is any interest.


    Edit:

    I switched to bullet physics, to read why and how the results are, and when you want a "short" explanation ("tutorial") on what I am doing for my client-side-prediction, check out page two.
    Last edited by MykonCodes; 11-22-2016, 05:43 AM.


    Freelancer for UE4 and more! www.mykoncodes.com

    #2


    Just a quick video I did showing my current progress. Note: The whole code is not optimized and properly synched yet, I just wanted to show that the generall physics fast-forward (rewind) is working


    Freelancer for UE4 and more! www.mykoncodes.com

    Comment


      #3
      [MENTION=552]Rama[/MENTION] has done one but hasn't shown any source code. I've dabbled a bit but syncing timestamps was a pig...

      Impressed with the stuff in the dev log btw. If people do get this figured out, I'd like to see some source. I've currently given up on syncing PhysX and decided to take Character Movement Components' approach. Not a fan of it though :/

      Comment


        #4
        Thanks. I did find some stuf of Rama, but his latest attempt for physics based platformer seemed to be client authoritive, without any physics rewind, if I am not wrong.
        I am still working on it, it still has major flaws where I need to determine where the inaccurarcys come from, but as soon as I have something acceptable working I will share my progress here


        Freelancer for UE4 and more! www.mykoncodes.com

        Comment


          #5
          I think his very latest version is server authoritative, but I can't be sure. Like you I need server-authoritative physics, since it's a competitive game and cheating would end up being all too easy.

          This is what I was doing to try and test my solution. It was so close, but I could never get the timestamps to sync - so the client would *try* to predict it's moves but the server would send a new one, and it would overwrite the wrong moves.



          What I have found however, is that the best way to hide the transition is to apply the positional update to the collision first, THEN interpolate the relative transform of the visual mesh to that position. That way collision is always handled in the most up-to-date form which results in less resyncing / error - and minimal rubber-banding for the player.

          Comment


            #6
            Thanks for the tip!! But what do you think exactly causes problems in your attempt? Not sure if I understood it right.


            Freelancer for UE4 and more! www.mykoncodes.com

            Comment


              #7
              To me it looked like you were applying forces on the Server to the object. In that case, thats not client-side-prediction. That only works for input that happened by the client, and is in fact just the prediction for the time it takes the players input to be send, processed and corrected back to the client, by the server. When a force is applied on the server side only, the client of course can't know when this force will get applied.

              And whhats your problem with syncing?


              Freelancer for UE4 and more! www.mykoncodes.com

              Comment


                #8


                Read the description


                Freelancer for UE4 and more! www.mykoncodes.com

                Comment


                  #9
                  Nope, the simulation ran both Client and Server side, and the client sent Input to the Server only.

                  The problem I had was that the Timestamps of the moves wouldn't stay in sync, so as the client moved forward, they'd receive a new / old update from the server with the wrong timestamp and it would therefore replace the wrong move in the client history, so it would then play subsequent moves incorrectly as well making the snapping even worse.

                  The above example was 50% packet loss, 500 ms latency I think.. been a long time since i work on that project though (mostly out of frustration

                  Comment


                    #10
                    I can't see how they would not stay in sync..
                    My technique is:

                    Save local time on client, then immediatley send request to the server, who then sends his local time back to the client immedtialtely.
                    When the time arrives on the client, the client again gets his local time and checks the time it took this response to arrive. Half of that time is the Ping.
                    You substract the ping from the server time to get the offset between the timers. Then you can convert your clients local time by adding this offset + ping (roundtriptime / 2).

                    So, when a server correction arrives, you check locally which history snapshot has the closest timestamp, on the synced time.


                    Freelancer for UE4 and more! www.mykoncodes.com

                    Comment


                      #11
                      That's exactly what I did, but over time they drift (especially with PktLagVariance). Only by very tiny amounts, but it was enough. Synchronizing time between two machines isn't a trivial task unfortunately, can't even rely on the windows clock.

                      I used the same system that Unreal Tournament did to effectively bounce a packet off of the server. Have to admit it's been ages since I've looked at it though.

                      Comment


                        #12
                        Well, the key is to update the ping frequently. Another technique is to send all the input tick-based to the server with a timestamp of the client, and the server send its data back, together with the latest received timestamp of what the client send, so then the client can sync 100% all the time.

                        A good solution might be a mix of the two, relying on normal sync most of the time but every few seconds, do the timestamp sync to get it back into perfect sync.


                        Freelancer for UE4 and more! www.mykoncodes.com

                        Comment


                          #13
                          Well if you've managed to do it, I'd love to see it I will have to go back to working on it sooner or later...

                          Comment


                            #14
                            Actually, I just made up the second technique while writing and have to test it myself yet, but at least I think that could work, but I will try it today or tomorrow and give you some feedback.

                            Can I ask how you did implement the actual physics recalculation?


                            Freelancer for UE4 and more! www.mykoncodes.com

                            Comment


                              #15
                              Okay, for the last two days I was trying to figure out why my Rewind&Replay doesnt work properly, then I noticed... it does. I print all the last positions of 1.) Local calculated position 2.) Server Send positions and 3.) Fast Forwarded Positions (the positions between the substeps also drawn in the next tick), so that I get three lines of movement basically. And I expected, that my Red Line (The FastForward Calculations) differ from the Black Line (Server Positions), but they didnt. They almost exactly match all the time, meaning, that the FastForwarding Calculations calculate the same as the server does, but in advance. Neat!

                              No so neat however is, that the problem was the "blue line". The Local calculations. And those differ EXTREMLY from what the server calculates, with EXACT the same code and same input. Driving a right-curve on the client totally differs on the client and the server, the client takes a shorter turn, or longer turn, sometimes the server spinns out, but the client doesnt... This gets nicely visible when I only run the FastForwarding every 3-5 seconds.

                              Client receives server correction, and calculates where it should be now. This is correct position now, after PING Milliseconds, the Black Dots (Server) align perfectly with the red dots (Fast Forwarded).
                              Now, the client moves right (right curve), and I would expect them to be SOMEWHAT similar. But often they are heavily different, even on perfectly plane underground.


                              BlackLines = ServerPos
                              BlueLiens = LocalPos

                              Turned of Rewind to demonstrate it better.

                              My question now is pretty vague, but what can cause this? Is Physx really THAT undeterministic, that even on plain underground with same conditions, a vehicle that only relys on input data and the underground (as far as dependencies go, that are not calculated by fixed mathematical rules, can behave SO differently? If so, I have to say, physx multipler is IMPOSSIBLE. It's simple impossible, if that is the case. There is no way, to interpolate that correctly, I dont even want to think about driving on unplanar underground then.

                              I hope someone can tell me that their physics run somewhat similar on server and client..

                              I mean, I thought maybe, I mess something up with the input and how it is send to the server, but no..
                              It's the basic system:

                              -Player presses key
                              -Client sends reliable RPC to server
                              -Both then execute the same function, delayed by PING milliseconds
                              Last edited by MykonCodes; 05-07-2016, 10:38 AM.


                              Freelancer for UE4 and more! www.mykoncodes.com

                              Comment

                              Working...
                              X