Player Health/Damage in Multiplayer Without Delays

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…

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.

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

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?

1 Like

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

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.

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

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?

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?

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).

Well it’s not the really the damaging im concerned about, but pretend if i kill a player, that delay is actually quite noticeable.

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.

Heres my Code:

  [Command]
    void CmdPlayerShot (string _playerID, int _damage)
    {

        Debug.Log(_playerID + " has been shot!");

        Player _player = GameManager.GetPlayer(_playerID);
      
        _player.RpcTakeDamage(_damage);
    
    }

  [ClientRpc]
    public void RpcTakeDamage (int _amount)
    {
      

        if (isDead)
            return;

        currentHealth -= _amount;

    
        if (currentHealth <= 0)
        {
            Die();

        }

      

    }

But this has a noticeable delay

Also keep in mind that these are on two different scripts

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.

  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?

How would you prevent this kind of cheating in a p2p environment?

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.

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.

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.

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.

1 Like