Search Unity

Wall sliding prediction issues

Discussion in 'FPS.Sample Game' started by Zenity, Jan 20, 2019.

  1. Zenity

    Zenity

    Joined:
    Dec 19, 2013
    Posts:
    12
    One of the major issues of the sample right now appears to be some heavy prediction issues when sliding across walls (especially while jumping). It becomes very jerky, and I'm sure I'm not the first one who has noticed this. The issue does not happen in preview mode. I saw some code for prediction verification, but I am not sure yet if it doesn't catch this issue or I don't understand how to properly check for those errors.

    At first I thought I might have broken something during my experiments, but I reverted to the original state and the same issue still exists.

    Anyway, I'm looking into this now and trying to understand the relevant parts of code, but I figured I better ask here in case somebody already knows something about it or has looked into it. I'll make sure to share anything I find. One thing I noticed is that while walking on the ground, it only happens when the angle towards the wall is very shallow (< 45 degrees). Strangely this is not the case during air movement.

    Also, is there a way to simulate lag without external tools, similar to "net pktlag=xxx" in Unreal?
     
    Stexe likes this.
  2. Zenity

    Zenity

    Joined:
    Dec 19, 2013
    Posts:
    12
    Still looking into it, but it would be great to hear if others even see this issue, just to rule out completely that it's something on my end.

    Also being new to Unity, I only just realised that the actual slide move implementation happens in a native component (CharacterController). So I'm wondering if there are plans to create an implementation in C# using ECS at some point. Also I wonder if it would be feasible to do our own, or is there an important performance related reason for why it needs to be a native class?

    Right now I'm looking for the part in code where the predicted movement is actually rolled back when the server disagrees, can somebody point me in the right direction please?
     
  3. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    It gets rolledback every frame: Line 157
    Also take a look at: the ReplicatedEntity modul
     
    AggressiveMastery and Zenity like this.
  4. AggressiveMastery

    AggressiveMastery

    Joined:
    Nov 19, 2018
    Posts:
    206
    Hello Zenity,

    The updates to the clients from the server, come 15 times a second (because its 1990.) The client's do interpolation and rollback like you are talking with Spy about, to smoother that jerkyness out in 'perception' at the client side. Reality, at 15 updates a second, all the movement is jerky like the wall is. Corrections just happen less, when physics is not used (aka you are not hitting a wall, but typically running parallel to the ground.)

    My guess, is that when you jump and hit a wall, you are getting the 15 updates per second for the character on the wall, on where the physics are from the server (aka it snaps back every 15 updates, and looks jerky.)

    My second guess, is that the client is then interpolating you into the wall, then pulling you back out with each update.

    This is really easy to see on movable objects, as they don't have interpolation on the client. If you load the server in the editor, then watch on the clients connected to it. The server Rigidbody MOVEMENTS (NOT ANIMATIONS) should be smooth, non-jerky, and not clip into the wall. Where the client is not getting the actually physics calculations, clients ONLY recieve speed, direction, location, then trying to estimate where its going based on the past updates. aka, clients-app does not see walls, it only counts on the server to move things correct. They tries to guess off that, to smooth out the players view of the world(interpolations.)

    But walls, and floors should be the same to a ridgedbody, right? But you are heading forward into a wall, direction of movement. Where as the floor, is typically parallel to movement, so interpolations are more easily correct, as you did not add another force (a wall interaction) during the interpolation. . You might see this clipping when you jump up onto something, or interact with the environment... when you 'wall run' you are constantly interacting with the environment physics, so easily see the failed interpolations at the client end. As interpolations expect NO future interactions, since they cannot predict whats coming down from the server... aka the need for roll back :D

    Cheers
    Micah
     
  5. AggressiveMastery

    AggressiveMastery

    Joined:
    Nov 19, 2018
    Posts:
    206
    I was working on getting doors into the FPS sample tonight, and I felt/saw the clipping spoken about with my door.

    I increased the size of the door collider, so that the server side character model had less or no chance to clip through the door at all. That helped smooth out some of the chop for me, as it reduces the axis of snap! :)
     
  6. aaronl

    aaronl

    Joined:
    Aug 12, 2015
    Posts:
    2
    Are you saying there is no collision detection being performed on the client?
     
  7. AggressiveMastery

    AggressiveMastery

    Joined:
    Nov 19, 2018
    Posts:
    206
    No Authoritative collision is done on the client, the server re-syncs the client's predictions to what the server predicted. So the client doesn't NEED to do any collision, but anything the client does do, is a prediction, and will be corrected 15 times a second by the server with what the server decided DID happen.

    Since the server talks (updates/sends) to the client 15 updates a second, it only correct the client that it impacted the wall somewhere in those 15 updates per second. However, if you have collision on the client, it could be updating the client 15-60-120-240 times a second (based on whatever the code is.) The different between those predictions, when 'corrected' is what looks like snapping/desync.

    So if you have collision detection on the client, and it detects the collision before the server, the server update could clip the client into the wall, where the client predicted it did not go into the wall. When the server wins, the client renders the change, and you see a clip/desync from the true-up.

    Clients are really like your TV and Controller, all the stuff is happening back at broadcast HQ (server) and you are just looking at a picture of what happen on your client. You can do some stuff to make it look better, like interpolation, to smooth out the 15 updates a seconds to more.,..
     
  8. Zenity

    Zenity

    Joined:
    Dec 19, 2013
    Posts:
    12
    Where do you get 15hz from? The client update rate should be much higher, hopefully 60hz like the server tick rate. But even if it was 15, it wouldn't explain the drastic corrections I am seeing. This isn't normal so there must be some serious issue somewhere. Even if there was a prediction mismatch, at most it should be subtle disagreements about how far the player slid along the wall, not sending them backwards even. Although with a fixed timestamp there is no reason why there should be a disagreement to begin with especially on static objects.

    For now I've been busy with Unreal projects again, but I'm still following this and would love to figure this out. One thing I wanted to try was to run the game without prediction using both server and client authoritative movement, any major discrepancies should become obvious then. This wasn't as straightforward as I hoped though, and there are quite a few systems involved. So if somebody knows a good way to do this, please let me know!
     
  9. AggressiveMastery

    AggressiveMastery

    Joined:
    Nov 19, 2018
    Posts:
    206
    server to client updates are done 15 times per second, client to server updates are sent 60 times a second.

    Clients do client side perdition off movement, but not client side collisions...well they can, but the server will snap back the clients to the 15 updates per second prediction, causing the snapping seen. Even if they predict the same, you still get 15 sync states a second.

    I am sure, you can increase 15 updates to 60, and hence send 4 times as much data per second, then running into perhaps a 1/4th the size player count, because of the additional updates. But, I hope bandwidth inst a big deal, but the unity fokes said it was.

    I believe they mentioned it in this network deepdive talk, if it wasn't on the general video.
     
  10. Zenity

    Zenity

    Joined:
    Dec 19, 2013
    Posts:
    12
    The server ticks at 60hz, apparently server updates are sent at 20hz (timestamp 15:35 in the video). There is really no reason why this should cause any significant misprediction. Sliding on a wall in particular is a very predictable action.

    Also the client certainly does collision detection. It would be completely broken if it wouldn't do that, as you'd constantly walk into walls before the server snaps you back (with actual latency it would be unbearable). What's happening is the opposite anyway, you get pushed off the wall when you shouldn't. If anything something is wrong on the server side with the collision meshes, and I think the best way to find out if that's the case would be to try entirely server authoritative movement. Basically I want to figure out how to disable any local prediction and only update player position based on the server snapshots. So far I haven't been successful to set it up that way.

    Also I'm still looking for a way to simulate latency, that should provide some good answers as well.
     
  11. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    476
    @Zenity
    In the past I've used a Mac combined with their Hardware IO Tools... the Network Link Conditioner. Then routed traffic through the Mac. It was kind of janky, but it when it worked, it did the job. Seems like there should be a better way.