Search Unity

Player Health/Damage in Multiplayer Without Delays

Discussion in 'Multiplayer' started by _spacepig_, May 16, 2017.

  1. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    When you use a Cmd or an Rpc to damage/ kill a player it has a short delay when the player dies after you shoot him, I find very annoying. How can I fix this? right now I use a Command and an RPC to take away health. I know I can fix this delay when affecting the local player, but not when its no another player.


    help me...
     
  2. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Latency you cannot completley get rid of. Even in an optimal world where every internet connection runs on Fiber optics (Speed of light) There will be latency and delays over large distances.
     
  3. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    I know about latency, but I have played multiplayer games such as csgo and overwatch, and there are no delays. Of course its imposible to get rid of latency, but how could i make it not look like any delays on the client side. Thanks!

    There has to be away to hide latency because counter strike does it
     
  4. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Hiding latency is extremely difficult. You must perform all actions client side, then let the server know you performed an action, the server then needs to verify the action was allowed (which usually it is). However in the case the action is not allowed then the server needs to let the client know the action that the client thought it could perform was rejected.

    Example: Client attempts to cast the spell fireball. The client believes the action is allowed. Instantly the client begins performing fireball cast sound/animation w/o latency. In the meantime the client sends a message to the server telling it that it is casting fireball. If allowed then nothing happens. However, lets say that due to latency the character was stunned or something happened that doesn't allow the client to cast fireball. The server then sends a message to the client telling it to cancel the action. In this (rare) case the client sees the fireball begin casting, but then the server corrects it and it cancels it. You'll see this happen rarely on games like League of Legends.

    For a FPS it's a bit different. When you fire a bullet for instance the client side data around the firing is sent to the server. The server can then calculate if it's a hit. The shooter has no latency (i.e. crosshairs were on the target and I pulled the trigger so it's a hit)... but the target sees latency (I was hiding behind a wall and still getting shot!).

    For movement... all movement should be done client-side. If you want to put in cheat protections you can (this rubber-bands or snaps the client back to a position if they violate some rules... move too fast or through a wall etc.).

    What type of latency you are trying to hide?
     
    Deleted User likes this.
  5. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    Well, if you read the title... you see... its hiding the delay when damaging a player. I noticed on client side, I call a command and an rpc to take damage from the other players, but while doing this, comes with a delay. How could i do this client side. Also thanks for your paragraph it helped me understand latency more
     
  6. Deleted User

    Deleted User

    Guest

    You don't need to call an RPC from the other players, just simply change the SyncVar of Health on the server side it will synchronize automatically over the clients, Zullar gave you a pretty good explanation for resolving your issue.
     
  7. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    Could you give me an example of what you mean? I 'm a bit confused on how this fixes the delay when killing a player
     
  8. Deleted User

    Deleted User

    Guest

    Could you provide more information about how is a player dying? Is he just being destroyed or death animation playing or he switched to Ragdoll?
     
  9. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Latency for damage numbers would barely be noticeable. Are you concerned about the delay (50ms) or the fact that the damaged object no longer exists if it's destroyed and RPC's won't work?
     
  10. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    Just make it so that your client applies the damage just like the server, but that the server than checks if the client set it correctly (Or just set it from the server with a SyncVar/ClientRPC).
     
  11. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    Well it's not the really the damaging im concerned about, but pretend if i kill a player, that delay is actually quite noticeable.
     
  12. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    I am using a ragdoll that gets applied explosion force from a ray cast bullets that spawns a hit particle with explosion force. This then applies the ragdoll to get blown back REALLY HIGH which i kind of like. If there is a delay, the explosion is already played and the ragdoll just stumbles to the ground.
     
  13. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    Heres my Code:

    Code (csharp):
    1.  
    2.   [Command]
    3.     void CmdPlayerShot (string _playerID, int _damage)
    4.     {
    5.  
    6.         Debug.Log(_playerID + " has been shot!");
    7.  
    8.         Player _player = GameManager.GetPlayer(_playerID);
    9.      
    10.         _player.RpcTakeDamage(_damage);
    11.    
    12.     }
    13.  
    14.   [ClientRpc]
    15.     public void RpcTakeDamage (int _amount)
    16.     {
    17.      
    18.  
    19.         if (isDead)
    20.             return;
    21.  
    22.         currentHealth -= _amount;
    23.  
    24.    
    25.         if (currentHealth <= 0)
    26.         {
    27.             Die();
    28.  
    29.         }
    30.  
    31.      
    32.  
    33.     }
    34.  
    35.  
    36.  

    But this has a noticeable delay

    Also keep in mind that these are on two different scripts
     
  14. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I think it boils down to 2 options

    Option1: Accept there will be latency. Perform all damage calcs server side. If the target dies then let the client know (with latency).

    Option2: Perform all calculations on client as well as server. This avoid latency. So the object can die on the client before the server realizes it's dead. However, if the client ever guesses wrong then you need to reconcile the differences (which will probably be *really* difficult to program). Also opens you up to cheating (if you are concerned about that).

    I'd recommend #1. Option#2 I think would be very difficult to code (although major games do this... again like Leauge of Legends). I'd wouldn't go down this rabbits hole IMO... just accept there will be latency.
     
  15. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    1. You should not trust Command calls like that. Any cheater could just send fake command calls with every players name. It's also recomended to not use names, rather use their NetoworkIDentity.
    2. Damage is calculated on Client. So is the health not a syncVar?


    Edit:
    Also, how are you testing this latency? Realworld or do you simulate poor connections?
     
  16. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    How would you prevent this kind of cheating in a p2p environment?
     
  17. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Generally everything should be done server side to avoid cheating. For example the client can attempt to attack... and only the attempt command is sent to the server. Then the server determines if the attack is allowed... and how much damage is done.

    Only movement is performed client side. Cheating can happen here... so you could put in server side cheat checks if you really wanted.
     
  18. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Pretty much what Zullar said. If you are using raycasts, I would send a Command to server to fire. The server then checks last fire time aka firerate, checks ammo and other things. Then it performs the raycast. If it hits a player you would change their health syncvar (still from server in the command) and everyone would get that info.
     
  19. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    But in p2p the server is hosted by a client, so what's the point of server side auth. Because at that point the server can cheat everything.
     
  20. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    The point is:
    Only host can cheat.
    So if a host is being a prick and is cheating. People wont join his server.
    But if a client is cheating, noone can stop him unless you implement something like a kick system.
     
    Deleted User likes this.
  21. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    But for alot of games (and someone like me that isn't practical). For example if you have an automatic match making system, and you can just choose/leave to play with who you want to.


    I have thaught about a system where both the client and host verify the end result. l couldn't find alot about it on the forums/online wouldn't that work?

    Why only make the server verify the end result, let both the server and the client verify. Check if the results are equal, if not report back to the user and cancel the whole match.
     
  22. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    The problem is that it will almost never match up. If per say you are running and firing at the same time. On your end you are dead on. So you tell the server. FIRE!, It was a hit for me btw. The server does the same check. And before that check. The one you hit has just sent a movement update. Then who do you trust?
     
  23. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31

    Well ofcourse the client also sends his position to server, the server can then check if that position is within a viable range (To make sure the client isn't faking a position). The server then simulates the shot and verifies it.
     
  24. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Things will become complex very quick for very simple things. Just to reload your gun you would have to verify the request on different places. It's a mess.
     
  25. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    Why? It's exactly the same as having only server auth.

    You can't add server auth without also sending the location to the server. Otherwise you would miss everything acording to the server but from the clients view he hits everything.
     
  26. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    If I tell server to fire. I also in that request say that i hit you. I then send that Command. But before it arrives. You send a new Movement Update to the server. So on the server you are on a different position than when I sent my request. So now server simulates the shot. And it misses.
    Now what does it do? Use The best of those?

    But even this has the exact same issues as Server only. The one hosting can just tell it's own logic. It didn't hit for him. And not me either. Lets not register the hit.

    Client Authority = Everyone can cheat and modify.
    Server Authority = Only server can modify and potentialy cheat.
     
  27. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    Well the server simulates the shot with the given position, so it will not miss. Otherwise it would also have missed for the client. Exactly the same like Server Authority only: The client sends that he shoots and his position, the servers checks if the shot hit. With server auth only the client can also send a movement update and make the shot miss on the server, so the server has to go back in time a little bit.

    The one hosting can't tell his own logics, because the client also checks the results of the server. The servers send to the client that he shot someone at a certain position and the client checks that. If the shot does not hit there is either desync (fault of the game) or someone is cheating.

    Basically you are having Server authority, but then you also make the client check the server. This way both the client and the server can't cheat. There is no way the server could use his "own logic", the client would not agree and disconnect from the game.
     
  28. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Oh, that's even more vulnerable. What prevent client from lying about position?

    And if a client calls the server our for lying. What happends? All traffic goes through the server. So it can just say, "The client agreed with me" to everyone.
     
  29. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    W
    This isn't more vulnerable than normal Server Authority only? The client has to send a position and the server has to verify the shot, otherwise the client would always miss like you discribed in your own post (because the enemy moves on the server, client moves, etc.). This also happens with server authority ONLY. The server can ofcourse check if the position of the client is within a certain range of where it is now/was and to see if the position is legit. (This is what you also would do in a normal Server Auth ONLY situation, there is nothing special about this).

    The only difference with client auth and server auth combined, is that the client also checks the server. Maybe this isn't possible for everything, but let's take this example:

    INT BulletsLeft

    The server shoots and sends a message to the client, the client updates the int BulletsLeft to be one less, without verifying anything with the server. So both the client and server are tracking the INT BulletsLeft independently.

    Let's say the Int BulletsLeft reaches 0, but the host cheats and sets it back to 100. The host shoots and sends a message to the client. But the client will say: "Hey, you have no bullets left according to my int BulletsLeft, you are cheating!") and disconnects.

    Second: Well because every client should say that the server is lying, because they all get the same info.

    I'm not sure if this would work though, I can barely find anything online.
     
  30. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    Kinda sounds like you're talking about client-side prediction.

    The idea is that you go ahead and do things before the server has technically confirmed that this is authorized. This still means server authority, but it doesn't force the client to do anything if the action is permitted. This is zero latency for the client's local space. You can do some of the same for trying to predict other clients, but it is not trivial.

    Your example is pretty weird. The host would be the server, and in a server auth environment the clients will disregard their information and accept that the server is correct, so it doesn't really apply. If the server says Joe has 100 bullets, then Joe has 100 freaking bullets.
     
    TwoTen likes this.
  31. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    I'm not talking about client-side prediction but authorization. Why should the client discard the information if has the ability to check if it is correct to prevent the host from cheating?

    Why if the server says joe has 100 bullets just accept that has a fact. Wouldn't it be smart to make the client count the bullets themself, so it can see when there is a difference and identify that the host is cheating.
     
  32. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    All communication go through the server. The server can tell the clients anything it wants. If I get told I only have 10 bullets but according to my logic I have 11. There is nothing I can do but accept.
     
  33. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    Are you saying you basically want an architecture where one client is the server, but other clients also act as servers to verify information?

    At that point, there is no authority because no one can agree on anything if there is a discrepancy.
     
    TwoTen likes this.
  34. TheWesselGames

    TheWesselGames

    Joined:
    Aug 31, 2016
    Posts:
    31
    Well you could show the user an anti-cheat message and disconnect..
     
  35. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    What if a client and a server agree on something but a third client disagrees?. Will he just leave the game then just because he gets some other outcome due to pointing float or something like that.


    There is too much to concider for this to work.
     
  36. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I've seen client side prediction of counters in some games. For example in on game you can hold 3 traps. If you have 1 trap left and use it instantly the traps left counter goes to 0 (it does not check with server). The server then verifies that the trap was usable and decrements the counter server side. In the rare case that the trap was not usable on the server... but was usable on client (i.e. you got stunned but it didn't register on the client yet due to latency) the server *should* reconcile. However in this particular game the counter would de-sync between server and client because the reconciliation was buggy... so you'd be left with a counter of 0 on the client, and 1 on the server. Then when the trap counter recharged by 1 it would jump from 0 to 2 on the client, and 1 to 2 on the server.

    Similarly in the same game if you target an enemy and cast a spell then instantly without delay on the client (the audio plays and animation begins immediately w/o checking with server first). But it the meantime it checks if the action is allowed on the server. Normally it is. But in rare cases the target cannot be hit (i.e. you lose line of sight). The client thinks it has line of sight and allows you to begin casting, but due to latency the server does not have line of sight because characters moved slightly. The server then rejects the action and reconciles to the client. The client then cancels the audio and animation of the ability and takes it off cooldown because it was never used. This only happens in rare cases, but is pretty annoying because you *think* you are performing an ability briefly until it's rejected by the server.

    Point being client side prediction + reconciliation is very difficult. I wouldn't attempt this unless absolutely necessary. It's certainly not necessary for damage numbers.
     
  37. _spacepig_

    _spacepig_

    Joined:
    Jan 18, 2016
    Posts:
    151
    It's a co-op game, so I'm not worried about cheating. How could i do client side prediction for this, can you give me a code example?
     
  38. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Very common in TF2 when I was a kid. You fired, heard the sound, then died and did no damage cause to the server you are dead. This is the best way IMO.
    If you are not worried at all you could make it VERY client sided. You fire on the client. Hit something, calculate damage and just send a command with damage and netID.
     
  39. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    244
    This is a pretty interesting topic that I've been weighing for my own project. It looks really bad to see your attack hit, then the health drains later. Anything > 100ms delay is kind of gross.

    I think at a minimum, I will just show the health change on a health meter immediately. So mostly cosmetic. As soon as you get the next sync var update, it will reflect the server value.

    Actually killing the player is a whole other problem. If your game can get away with it, I suggest having some intermediate animation to play before you get the kill rpc from the server. For example if you just killed a robot, have sparks start to flare out of him before he explodes. The point here is that it's probably easier and less immersion breaking to turn the sparks off instead of resetting a ragdoll if the server suggests it wasn't a kill
     
  40. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    For no latency visual issues. Send the attack. Simulate the attack. Simulate damage and possibly the death on client. If Server disagrees, just revoke what you did. Very rare cases tho.

    So if I shoot an enemy with 20hp. I do 30 damage. I will first send the command call. And then I will actually kill him on my screen instantly and not wait for a RPC. That's the no latency way. But if something has happend in between of my last update of his health and my shot message arriving then corrections will have to be made. That's pretty rare tho.