Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Clarifying questions regarding authorative servers and collision

Discussion in 'Multiplayer' started by Freaking-Pingo, Mar 19, 2017.

  1. Freaking-Pingo

    Freaking-Pingo

    Joined:
    Aug 1, 2012
    Posts:
    310
    Hi Uniteers,

    I have made quiet the research on network code but I still feel I have a few unanswered questions I need answered before I feel comfortable diving into developing a networked game using an authorative server.
    Imagine an ordinary FPS game such as counter-strike:
    • Is collision detection handled on server side in order to prevent players from moving out of bounds and run in between walls?
    • If collision detection is handled on server side would you run an Unity instance on a server in order to be able to do the necessary raycasts? If not, what is the alternative?
    • If you were to run an Unity instance on a server, how would you do that? Would you run the instance in batch mode?
     
  2. Whippets

    Whippets

    Joined:
    Feb 28, 2013
    Posts:
    1,775
    From what I've found out there are no right or wrong answers with multiplayer and networking, but this is what I do; I'm sure other people will offer their opinions too - all are valid.

    I use unity instance servers run batchmode/nographics as a background process/service; which handle collision detection (with colliders & casts), as well as npcs/mobs and their AI. Having said this, the map is also on the client to ensure everything works should packets get lost/delayed, and prediction/interpolation has to come into play.

    There's a school of thought that says: If 1% of players are cheaters, and they only cheat 1% of the time, you can spend so much effort ensuring no-one cheats that you slow the game down for everyone just to catch a 1 in 10,000 cheat.

    IIRC WoW only checks for cheating once in a while per player, with most checking done client-side.
     
    Freaking-Pingo likes this.
  3. Freaking-Pingo

    Freaking-Pingo

    Joined:
    Aug 1, 2012
    Posts:
    310
    This is great to know, as I was uncertain whether it was even possible to use a Unity application as a server instance.

    Good to know. I haven't managed to establish a feeling yet on when doing too much cheat prevention. I am aware that games can never be 100% bulletproof and thus require some sort of reviewing of games.

    @Whippets Thank you for your indsight.
     
  4. donnysobonny

    donnysobonny

    Joined:
    Jan 24, 2013
    Posts:
    220
    @Whippets response is definitely a good one, but to add to what has been said already.

    The old "there's only a few people that cheat, so why bother" concept is sometimes valid. The reason for this, as Whippets mentioned, is sometimes the work and cost involved to solve problems with cheating is too high. However, I definitely sit on the side of the fence that says to always prevent cheating, simply because:
    1. I am fairly methodological when it comes to building games/apps, I prefer to plan for things like optimization and cheat prevention right from the beginning. And I will stay in that planning stage for as long as I need to, before I know everything that I need to know. This means that I actually spend very little time implementing cheat prevention, because I've prepared for it. The whole "it can be too much work" comes from the scenario where you do little-to-no planning, and optimize/prevent cheating later on. Although that can be a viable strategy, it is definitely the cheap-and-nasty route.
    2. Cheating can be 100% prevented. Many will tell you otherwise but I would be happy to prove them wrong. Don't however confuse cheat prevention over malicious activity (such as DDOS attacks on your server) because these are things that cannot be 100% prevented. Cheat prevention however, can. So why not do it??
    Ultimately it comes down to how much time you want to spend on the game, and really whether you think the time will be worth it. I don't see my time as that valuable, so I'm happy to "waste" a lot of it, if I believe in what it is that I'm doing. You however might value your time more, and you may be unsure about how well your game is going to do. In which case it may not be worth spending the time implementing cheat prevention.

    Definitely don't go half way though. There's no point in only partially implementing cheat prevention, unless it's just to try and confuse potential cheaters... I would recommend either going balls-deep, or just doing the cheap-and-nasty. Both are viable, depending on your situation.


    To answer your question though, yeah that is exactly how you would do it. As Whippet mentioned, unity games/applications can be built to linux (which is the OS of choice for server computers) and can be run in headless/batchmode mode (no audio/rendering, massively lowering the cpu/ram usage). This means that you can build your server-side directly within unity, even in the same project that you build your client-side (even more useful!), and very efficiently run that on a dedicated server. Handling the physics/collisions on the server-side is a very good strategy so I would definitely recommend this approach to solve the problem of player objects going where they shouldn't.

    Hopefully this helps. Good luck!
     
  5. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    With UNET, the server would be an instance of the Unity game running, so you can do all the checks you want there.

    However, making only the server check for collisions is a bad idea, because the responsiveness of the movement on clients would take a huge hit (they'd have to wait for the server's response at every frame). Like others have said, there is no "definitive" solution to networking, but what you should aim to do in general is to have each client process their own movement, and have the server validate those movements and apply corrections if necessary.

    Now the question is; what does "validate" mean? Well, that's up to you. You could make the server-side logic process the movement of every character controller and see if it matches, or you could make the server only check if a character has moved for more than it is allowed to move over the last second or so, or you could check with zones/triggers if a player is in a place where it isn't allowed to be (like outside of the map, for instance), etc, etc....

    ...you decide just how "authoritative" you want your server to be
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    On the topic of how important preventing cheats is, a lot of that depends on the design of your game. A fun FPS game it is somewhat important, but if cheating remains low and players can easily switch servers to get away from cheaters, it isn't a huge problem.

    Change your FPS game to something like CS:GO competitive mode, where players are locked into a series of matches with the same opponents for 90 minutes, combined with a ranking system, and preventing cheaters becomes a lot more important.

    Create a game like the Eve Online MMO, where players invest lots of time (and possibly real money) into building up their ships, which they lose if they are destroyed by another player, and preventing cheats becomes one of the most important features of the game. A game like Eve would be quickly destroyed by even a small number of players getting away with cheats.
     
    Freaking-Pingo and donnysobonny like this.
  7. Freaking-Pingo

    Freaking-Pingo

    Joined:
    Aug 1, 2012
    Posts:
    310
    Interesting perspective. I am currently in a personal learning phase so I think I am inclined to try out the "balls-deep" approach and see how far it goes. I will properly at some point stumble upon bedrock but in that case I guess I have learned a thing or two and then I might try the cheat-nasty way.

    Just the information I was looking for. I was concerned to use a Unity instance as a server as I had a hunch that it would deem inefficient.

    I would get furious if I lost my Obelisk full of cargo to a cheating player. I think your making a good point. I am working aimlessly on my game, so at this point its difficult for me to select a level of anti-cheat. I guess this perspective may come in handy when having to do my next production.
     
  8. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    For example, I am developing a fast paced FPS game. Everyone does local collision detection for all clients when moving and colliding with walls.

    Projectile collisions, however, work a bit different in my case. I still detect the collisions on each client separately. Which means if a projectile hits a player/wall on a client, the FX will be played. However, only the server/master client collisions decide if the projectile hit the player and if health is reduced. This means that the projectile could hit a player on 1 client but not on the master client. This means that the FX on that client is still played, however no damage is done to the player.

    Another option, which I think I will try soon, is that clients do not check for collisions with walls/players. Only the master client will. Problem with this is that projectiles could start flying through walls on the clients before receiving a message from the server, that they collided.
     
  9. Freaking-Pingo

    Freaking-Pingo

    Joined:
    Aug 1, 2012
    Posts:
    310
    Wouldn't this make the game feel unresponsive and sluggish? E.g. I click the shoot button and I'll have to wait a roundabout before my action will lead to a result?
     
  10. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    If you used this for moving, then yes. With shooting, however...yes and no. There are games that wait for server response and games that don't.

    If you decide to wait for the response, then there is a bigger chance that the projectiles are less out of sync, since the only delay for EVERYONE is the pingtime with the server. It goes like this: player presses fire button locally, RPC is sent to server -> server sends an RPC to everyone, telling them to fire. So desync can occur only from this one rpc.

    If you decide not to wait for the response, then firstly, to prevent ammo cheats, every player should have the correct amount of ammunition received from the server already, telling them that they can fire. Secondly, you'd have to do a little bit of networking magic to make the projectile synced for everyone. Because now the projectile's position difference between the player who shot and other remotes are bigger than before. They are desynced also by the ping of the fired player to the server. So now everything is desynced by this amount: shooters ping to the server + server's ping to remotes.

    How to combat this? I think I have 2 solutions. Both are based on the time the projectile was fired and the time the fire command arrived at remotes.
    Based on that time difference, when the fire command arrives at remotes:
    1) set projectile's starting position to "initial start position (where player fired) + projectile speed * time difference". This will set the projectile's initial starting position to be the same with the client who fired the projectile.
    2) increase the projectile's speed at the beginning and reduce it later, so that after a certain amount of time (0.05 seconds for example), the projectile will be where it is on the client.

    If, however you are doing collision detection with players on the server. Then you might want to send the fire RPC to the server first, let that instantiate the projectile and then send the rpc to the remotes. And the new time difference, mentioned before, will be "arrival time on remotes - instantiation time on server". This means that, using one of the two methods I described above, your projectiles will be at the same location where they are on the server and not the client who fired the projectile.

    Currently i'm using solution 1. However, I will shortly test out solution 2.
     
    BenjaminJepsen likes this.
  11. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    For example, Overwatch predicts your projectiles immediately. If you press the fire button, the projectile is spawned and moved. This is all predicted. Then an RPC is sent to the server to instantiate the rocket on everybody else. Not sure how they exactly sync the position of the rocket though. Wether they move it into place (solution 1) or increase its speed (solution 2).

    Today, I tested Xonotic. And I purposely joined high ping server. In Xonotic, projectiles are not predicted immediately. If you have a ping of 200ms then after you press the fire button, you wait 200 ms for the projectile to be fired. However I'm not sure how does their collision detection work. It seems that projectile collisions are detected locally. Which means if, for example, a rocket hits a player, it immediately explodes. However, it seemed to me that it also immediately added the explosion force, knocking the other player away. Without waiting 200 ms.
     
    BenjaminJepsen likes this.