Friday, February 3, 2017

networking - How do we make online games deterministic?


I am trying to understand how networking in games work as I am trying to make an online game myself. I can't grasp how it is possible to synchronize the players, in order to make the game deterministic. I found an article saying this:



in order to ensure that the game plays out identically on all machines it is necessary to wait until all player’s commands for that turn are received before simulating that turn. This means that each player in the game has latency equal to the most lagged player.



This makes sense and I also came to the same conclusion after hours of drawing graphs with various scenarios. However, there are some games where one player can have 500ms delay, and another player could have 40ms delay. In this case, how is the game deterministic ?


Lets name players with 40ms, 500ms delay: Player40, Player500


Lets say that Player40, shoots Player500 with an instant laser shot at T1 = 0ms. Exactly 40ms after the Player40 actually clicked with his mouse to shoot (so T2 = 40ms), The "laser shooting event" registered on the server and returned "ok, you can execute laser shoot" to Player40. So, the shot is being applied on Player40's machine and on his screen he sees that he killed Player500, and the corpse is lying on (x1,y1,z1).


Meanwhile, what happened on Player500's machine, was that Player500 was running straight. A few moments later he sees a laser a few feet behind him, he dies even though the laser didn't hit him, and his corpse is lying on (x2,y2,z2).



Since this scenario never happens in some games, does this mean that those games are deterministic ? How is something like this possible, without forcing all players to get a delay equal to the delay of the most lagging player ?



Answer



It's actually the other way around. Games are made deterministic to be online.


The basic idea is to send commands rather than game state. If you have a function F(X) = Y and you need everyone's Y to be the same, you can send X instead of Y. The reason why this happens in the first place is because sometimes commands are more efficient than game states bandwidth-wise. In an RTS game, there can be 200+ units at one time so sending a command is better than replicating 50 positions, rotations, healths, etc.. There are several other benefits like 100% game state cheat proof and small replay sizes.


Unfortunately, deterministic games require deterministic simulations which floating-point numbers cannot do for you. This means Box2D, PhysX, and Bullet are all out of the window without clever floating-point tricks, but even with those low-level modifications, they can't be cross-platform deterministic.


Fortunately, you don't have to code your own physics engine or lockstep logic if you're using Unity. I'm working on a deterministic physics engine with lockstep multiplayer, all integrated with Unity3D. If you'd like to sign up for the Beta and give it a shot, here's the link: http://forum.unity3d.com/threads/dphysics-beta-cross-platform-deterministic-physics-engine.318827/.


Sorry for the shameless plug :). Anyways, if you're not using Unity, I'll give you a few details about a lockstep framework that'll be good to know anyways.


Lockstep games think in frames, basically an integer that goes up every time the game is simulated. On frame 100, everyone's simulation should be the exact same but everyone doesn't have to be on frame 100 at the same time which is how latency is handled but I'll get into that more soon.


Everyone receives the same data for every frame as well, and can't advance to the next frame if they haven't received the data for the frame. A client has to have a packet designated for frame 100 to run frame 100. Inside this packet are player commands.


i.e.: Units {1,2,3,30,127} -> Attack -> Unit 10 or Player 5 -> Mouse Input Rotate -> (30,20) then Player 5 -> Shoot.



From there, you can adjust the simulation rate to be faster or slower depending on how many packets in advance you have to simulate. While others' response times don't really matter to a player, his own does. If a player has 500ms latency, he'll simply get packets 500ms later than everyone else thus his game state will be 500ms behind. The main problem is that when this player sends a command, he won't be getting it back until 500ms later which means his actions won't be responded to for a noticeably long time. This is true for authoritative server setups as well. Lag masking methods can be used like pre-played animations, instant sounds, slow acceleration, or "fake" movement.


This is the core of DPhysics Lockstep. If you're not using Unity, you could take a peek at the code anyways to see an example implementation. The DPhysics implementation uses a server instead of P2P which means no desyncs or funky code and latency is determined by a single source instead of by the slowest players.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...