Search Unity

Unet server-authoritative movement with client-side prediction and reconciliation

Discussion in 'UNet' started by GenaSG, Aug 24, 2015.

  1. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    I've updated to Unity 5.1.3f1and now I'm constantly getting
    UNet Client Disconnect Error: Timeout
    UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()

    error. Does anyone else have such error?
     
  2. TehGM

    TehGM

    Joined:
    Nov 15, 2013
    Posts:
    89
    About your error - not sure, my network development itself is frozen as I'll need functionality that comes in U5.2. Meantime working on other stuff that is also important, but doesn't require network gameplay itself.

    Anyway, I wanted to post thanks here. I've looked at your code earlier but was like "meh, I don't need it for now anyway". But now I decided that I better implement it before project gets too complex (well, it's already getting biggy, and it's barely starting).
    Ofc, I won't use it as plug-n-play. I'll read your code carefully, learn from it (I am quite experienced I'd say, but when I think of prediction, I get mixed feelings - hopefully it'll be easy to learn from your code). And I'll also scrap parts of your code removing features I don't need for my game design (this way it'll be easier to me to manage what I actually need in my game). And ofc, if I'll have anything to comment or help, I'll shout here.
    Anyway. Thanks again. That was the purpose of this post. :D
     
  3. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    You are welcome :)
    Cheers
     
  4. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Ha, new error.
    aissp: not update stats
    I've set channel 1 to Reliable Sequenced and set syncvar to use this channel.
     
  5. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Ok, so it looks like I've fixed the issue with timeout. State synchronisation doesn't work well with any reliable QoS. I've set channel 1 to Unreliable Sequenced and it stop crushing.
    I've pushed a patch to the repo.
    Cheers
     
    moco2k likes this.
  6. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Last edited: Sep 8, 2015
  7. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    I've tested with network simulation previously. It worked fine. But now I'm getting timeout if I use network simulation. So I can test it only for few minutes. Everything worked perfectly previously. I've managed to solve part of timeout with previous update. I also thought that existing network simulation timeout is related to frequent inputs update. So I've created a branch in which I'm testing incremental updates. But issue is still there. So it's not something directly related to my code but network simulation itself.
     
  8. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Ok. So I have a bad news and a good news.
    The good news is that I've debugged the issue with timeouts using external network tool to simulate latency. And it looks like my code is Ok.
    The bad news is that it looks like that internal unity network simulation has a bug.
     
    Last edited: Sep 9, 2015
  9. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Experimenting with networked pickups.
     
  10. Travis_Foo

    Travis_Foo

    Joined:
    Jun 26, 2015
    Posts:
    7
    Is the rest of the simulation fine? Or is it just a timeout issue.
     
  11. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    This is great work. I'm checking it out for possible use myself!
    It's amazing that something like this included as a standard asset.

    In your GetInputs method, for your sides and forward inputs, looks like you're using a 'RoundToLargest' method to get the input to 1 or -1. Have you looked at Input.GetAxisRaw? Think it does the exact same thing. Can remove your RoundToLargest method, cleaning things up a bit :).

    inputs.sides = Input.GetAxisRaw("Horizontal");
    inputs.forward = Input.GetAxisRaw("Vertical");

    I haven't tested yet, still reading through to see if I can understand what's going on, but I'm liking the separation of rotation/position/stand still, and use of bytes for minimal network traffic.
     
  12. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    It timeouts constantly. I can't tell you if everything works fine.
     
  13. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello and thanks :)
    I've just pushed a big update with pickups and item switching.
    The input part is changed in it you should take a look.
    And you're totally correct about Input.GetAxisRaw. I don't know I've missed it :)
    RoundToLargest is still there but I'll remove it eventually.
     
    moco2k likes this.
  14. rob_vld

    rob_vld

    Joined:
    Jul 9, 2013
    Posts:
    191
    @GenaSG

    So... where do you measure and correct for the network latency, or is this for LAN use only?
     
    Last edited: Sep 23, 2015
  15. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    I don't understand your question.
    If you're asking how am I simulating and controlling network latency.
    I use external tool for that. It's Network link conditioner for OSX.
    If you're asking how am I compensating latency in the code.
    Then it's all described in the blog post linked in the first post.
    In short. I don't need to know exact latency. I have timestamps for all synchronisation related functionality.
     
  16. omarmoh

    omarmoh

    Joined:
    Apr 18, 2014
    Posts:
    16
    hi, i downloaded the files and when i import them everything is missed up, all the prefabs have no scripts and nothing is working.
     
  17. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello.
    I'll check it.
     
  18. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello everyone.
    I've pushed new update with StateMachineBehaviour based aiming IK and missing models.
     
    codestage likes this.
  19. shamunity

    shamunity

    Joined:
    Sep 18, 2015
    Posts:
    22
    What a great thread - Got a question regarding this implementation:

    I have 16 player-controlled objects that use physics to be moved (rb.AddForce) and can 'bump' into each other (think of it as a bumper car simulation).

    What would be the best approach here, as players can still input movement while being affected by physics after a collision?
     
  20. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    This one could be tricky.
    It's impossible to rewind physics in unity so standard server-suthoritative model wouldn't work.
    I see two options.
    The first one.
    You'll need to create custom movement physics that can be rewind(based on input time value). I this case it would be possible to use fully authoritative server model.
    The second one.
    Is to simulate physics on the owner client and only send resulted position and rotation to the server which will propagate those values to the rest of the clients. In this case only owner client(isLocalPlayer) would calculate actual physics and all other actors would just receive and apply pre-calculated values. BUT it is way easier to cheat.

    Right now I'm experimenting with semi-authoritative server model. So it is possible that I would share it as well.
     
  21. shamunity

    shamunity

    Joined:
    Sep 18, 2015
    Posts:
    22
    Thank you so much for such a fast reply @GenaSG - much appreciated.
    I'm a bit surprised what I thought was a relatively simple game such as mine (bumper cars) would turn out to be so complicated to implement network wise.

    Does that mean that there are currently no 'out of the box' solution in the Unity ecosystem that say, make it easy to make a car racing game multiplayer and behave semi-realistically. I'm thinking for example two cars racing each other, first car bumps into the second one, the driver can still input movement to try to 'counter' the pushing.
     
  22. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    URW
    There is a NetworkTransform component as a built-in solution. But it doesn't work that well. Anyway it is the simplest to try out networked movement. It should work more or less ok for low latency usage(e.g. LAN play). But it sucks even with moderate latency(e.g. 60 ms).
     
  23. Graep

    Graep

    Joined:
    May 29, 2013
    Posts:
    7
    Hi Gena,

    I'd really like to take a look at your project but when I load it into Unity all the prefabs in the scenes are missing and all the scripts in the prefabs are also missing.

    I'm not sure if I'm not importing it correctly but some other places I've read that this issue may be caused by missing .meta files that don't seem to on github.
     
  24. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    I'll check it. Used to work.
     
  25. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Sorry, my bad.
    It used to work until I made a very stupid thing and added .meta files to the gitignore.
    Should work now. But there will be several error messages like missing key bindings and no scenes in build settings.
    P.S. I've pushed an updated with the fix.
     
    Last edited: Oct 18, 2015
  26. Graep

    Graep

    Joined:
    May 29, 2013
    Posts:
    7
    Thanks!
     
  27. daeuk

    daeuk

    Joined:
    Mar 3, 2013
    Posts:
    67
    how do i open the project... tried extracting the master and then opening it on unity and i dont see the assets...
    thoughts?
     
  28. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello
    Create empty project and extract the archive in to the Assets folder.
    Should work.
     
  29. Infinite_Monkeys

    Infinite_Monkeys

    Joined:
    Oct 29, 2015
    Posts:
    6
    Having trouble implementing a stripped-down version of this. I'm making a game that isn't fast-paced enough to require interpolation and (for now) only needs WASD input. The server will also always be dedicated rather than having a client as well. I've managed to get a player prefab to spawn when clients connect, and the player's input is being read into my input struct correctly. However, FixedUpdate() never seems to be called on the player's NetworkPawn (equivalent, I've renamed it) server-side, so the hasAuthority check is never passed and Move() is never called. I noticed that the example scene has a player object already in it (how does this work if you start a dedicated server, is it deleted?), so I tried placing one in my scene but that didn't help.

    Here is my code if anyone's willing to take a look. I haven't implemented the Results syncing that would allow clients to see the server-side positions of objects yet, but from what I understand my current code should move the player object on the server when the WASD keys are pressed in the corresponding client. If anyone knows why it's not working I'd appreciate some help :)
     
  30. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    It depends a bit on the game in question, but if we're talking your typical first or third person shooter the statement here is incorrect. Most modern fps/tps games send their player input in an unreliable fashion, sometimes with some redundancy.
     
  31. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Hello.
    Try to remove !server in the if statement of FixedUpdate.
     
  32. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    I would say that UDP used in all of them. But there is a reliable UDP implementation for crucible inputs like fire,ads, etc. I know that not all games do that. I know that CoD 4 doesn't. But MW3 does have some reliability added to shooting mechanics(e.g. "One in the chamber").
    But I see your point. If client's inputs send to the server frequently enough. I mean like in Source engine then it wouldn't be a big deal to lose one position related input.
     
  33. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Today, I've tried your latest code and I can confirm that it works very well. I think it's also a very good reference for learning implementation concepts of client side prediction and such.

    I have one suggestion: I think you could add a few more comments and explanations to the code to make it even more valuable as a learning resource, describing what is done and also why. Probably, it won't take you much time, but it will increase accessabillity for new UNET developers and it will make understanding the code easier.

    Thanks for this and keep up the good work.
     
    Last edited: Dec 7, 2015
    GenaSG likes this.
  34. MatiasJP

    MatiasJP

    Joined:
    Nov 4, 2013
    Posts:
    16
    This is just fantastic, I'm currently doing a moba like game and I found the prediction/reconciliation thing in the blog of gabriel but without code examples and 0 experience in networking I get confused quickly.
    I try some implementations myself but always the reconciliation screw my up. Then I found your post and it is magnificent man, it works like a charm.

    I found a few answer in this thread about a few implementations that I don't understand when I was reading your code, like the network compression and the use of differents channels/intervals.

    I have one question...

    1.- What happend if I move being the host and my _dataStep is less than my networkInterval? that result is never going to be sync and my dummy client will not have the same position as my server.

    Thanks a lot for share this source Gena it help me alot.
     
    Last edited: Dec 7, 2015
  35. Deleted User

    Deleted User

    Guest

  36. Torigas

    Torigas

    Joined:
    Jan 1, 2014
    Posts:
    63
    We got the solution to work in our project and it works nicely.
    Gotta keep in mind that this solution uses the character controller and not a rigid body controller. But that works fine.

    Is this still being developed? Especially the mouse look part was hard to understand with it being in the animator. =D
     
  37. omarmoh

    omarmoh

    Joined:
    Apr 18, 2014
    Posts:
    16
    I found it hard to understand everything in this project but i will just keep trying harder, but there is one thing i want, can you make one with a rigidbody player? an example would really help me alot, and it doesn't need to have guns and other stuff just a simple cube that uses addforce to move would do it. any help is greatly appreciated :D.
     
  38. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    EDIT - SOLVED. I don't have the slightest clue what I did wrong, but I scrapped all the code and rewrote it and now everything's working.

    EDIT - I figured out how to handle rotation for my game, but I'm having to send Vectors. For now it's fine. However, now I'm running into an issue where the ClientCallBack isn't firing. It executes for the host, but not for any connected clients. Here's the code, edited for suit my game. I'VE REMOVED THE CODE SINCE I FIXED IT. IT'S IN THE POST BELOW.
     
    Last edited: Dec 30, 2015
  39. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Now I'm just having ONE final issue, where the client is EXTREMELY jittery. It almost looks like there's an earthquake going on. The host/server is perfectly smooth, and seeing other clients move on your local machine is smooth. But when a client begins moving around, everything goes haywire (earthquake-like) on THEIR machine. Here's my variation of the NetworkMovement script. (I don't have a NetworkPawn at this time. I just attach my NetworkMovement directly to my Player Object for the time being.)

    EDIT - I identified the issue and it has nothing to do with the NetworkMovement.
     
    Last edited: Jan 17, 2016
  40. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Your totally right.
    I probably will. Just don't know when :p
     
    moco2k likes this.
  41. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    As far as I know network send interval is relevant to one object only.
     
  42. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    That wouldn't be a trivial task.
    I believe there would be issues with differences in physics calculations.
    I wouldn't recommend to use build in physics engine for that as is it wouldn't be controllable enough.
     
  43. OMGWare

    OMGWare

    Joined:
    Mar 4, 2014
    Posts:
    24
    This is awesome!
    Thank you for your effort, I just finished reading the fast paced series on the blog linked in the OP and was wondering if your code also includes the lag compensation part?

    I would also advice for commenting the code, this is a VERY valuable resource.
    Keep up the great work!
     
  44. ManBearPig969

    ManBearPig969

    Joined:
    Dec 10, 2015
    Posts:
    1
    I've started cleaning up a bunch of the code over the past few months, but I'm having some very strange problems with my avatar's head rotation... Can anyone give me a hand?

    broken-neck.jpg

    Source project: https://github.com/kamilion/UNETMovement

    unitypackage release: UNETMovement.unitypackage

    Scripts are in here, and I'm having trouble with the mouselook controller here and potentially the NetworkPawn here. I've only messed with the NetworkMovement a little bit, adding a few helpers at the bottom here.

    I've tried a few things like applying the pitch to the Z axis instead of the X axis in the mouselook animator; that got the head the right way up, but things are still badly broken.

    LPC_network\RudeDude.prefab exhibits the problem while Prefabs\PlayerObserverPawn.prefab does not.

    I opened the FBXs in 3DSMax, the LPC model looks fine while the SwatCharacter is not.

    soldier.png
    LPC.png
     
    Last edited: Feb 22, 2016
  45. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    It looks like wrong bone axis to me.
    Z-forward,Y-up,X-right
     
  46. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Thanks mate.
    There are some problems with this classical approach in Unity3d.
    For example. Player vaulted through a window. Animation played, collider parameter changed. But all those events haven't been saved. So reconciliation process will fail.
    I'm working on new approach that shouldn't have this kind of issue.
     
  47. GenaSG

    GenaSG

    Joined:
    Apr 19, 2014
    Posts:
    111
    Sorry guys for not commenting much on this thread. I have a LOT of work to do on my full time job. So just don't have anything to share with you.
     
  48. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    So, I've finally tweaked everything about this system to make it work for my project (with the exception of swimming and flying), and I'm working on animations. Since this system uses an authoritative server set up, obviously the server controls animations. The problem I'm having, is that since Inputs are sent Unreliable, using inputs to determine whether or not a character should be in a walk/run animation is unreliable. I've found that sometimes a packet was received out of order, and the player will still be in the running animation on the server, and on the client they'll not be running because the client isn't inputting movement.

    So has anyone come up with a reliable way to handle movement animations using this system? (Keep in mind I'm using the CharacterController (not a Rigidbody)).
     
  49. Avinash-pdy

    Avinash-pdy

    Joined:
    Mar 4, 2013
    Posts:
    28
    Hi, i pulled it from github. Thought it was a Unity project. But i had to create a project and drop it there. After that i start getting exception about input buttons. Can you please specify what all input buttons are needed to be added in read me or it will be best if you could push a working Unity project.
     
  50. _FLX

    _FLX

    Joined:
    Nov 10, 2015
    Posts:
    85
    Hi, I have an authoritative network and also use CharacterController. The tip is : 99% of times you don't need to sync animations, because it's not often that they have an impact on your gameplay.
    Animations should (this applies to most cases) be determined client-side, not using input but server state.
    To chose between Idle/Walk, don't use inputs, use the real velocity (that way your player will not walk facing a wall).
    For custom states like Shooting, Jumping... Just add these as booleans in your server state.
    This is working really fine.


    Hey, have a look in the ProjectSettings directory. You should be able to grab his inputs settings.