- Home /
Physics based multiplayer simulation game
Hi,
We are working on a multiplayer pool game heavily based on Unity physics and we managed it have a stable version of the single player gameplay.
For one week, we are working on the multiplayer version of it. Firstly I can say I am not a networking or physics expert but I know all the concepts of them, have 3 years background in game industry and have made a long research about it before I came to here.
Our current solution was the easy one which turnout to be not that easy. It is sending force direction and position from clients and calculating physics on both client/server and correcting the results (supposed to be too low) from the server at the end of the turn. To be able to make this work, we have made lots of investigation:
Firstly; simulation wasn't even same at the same computer with the same executable. To be able to correct it, we have to work on many Unity parameters and main ones are below:
"Rigidbody.useConeFriction = false" effected the results a lot. Same shot on balls gives at least 0.2 points of difference with it. After setting it to false, we started to have 0.001 points of differences.
"Rigidbody Collision detection = Discrete" also effected the results a lot. Setting it to "Discrete", from "Continuous" or "Continuous Dynamics" made it very much precise also.
"Rigidbody Interpolate = None". We couldn't be sure if this effected the results as much as first two but seems like shutting interpolation down made it a little better.
"Fixed timestep = 0.01". Running simulation in a smaller timestep made the results better but not that much difference between "0.02" and "0.01".
"Solver iteration count = 20". Similar to "fixed timestep", higher better but again doesn't give a huge difference. Not that much difference between 7 to 20 but still better.
Lastly adding the balls to server and client in the same order even effected the results. To have exactly same simulation, it think Unity should also hold the internal data structure in the same way for server and client binaries so we just tried to have exactly same scene for Client and Server and that also effected the results.
Final results with break shot for 15 + 1 balls: Client, two same shots, three balls position:
Ball_1: 7.647239, 1.791727, -7.450733 Ball_1: 7.647166, 1.791727, -7.450527
Ball_12: 3.079326, 1.791727, -3.05286 Ball_12: 3.080814, 1.791728, -3.052271
Ball_15: 7.133366, 1.791727, -11.65263 Ball_15: 7.133381, 1.791727, -11.6526
Server, two same shots, three balls position:
Ball_1: 7.649154, 1.791727, -7.458591 Ball_1: 7.649155, 1.791727, -7.458614
Ball_12: 3.076369, 1.791727, -3.062551 Ball_12: 3.076268, 1.791727, -3.063016
Ball_15: 7.1292, 1.791727, -11.64938 Ball_15: 7.129121, 1.791728, -11.64801
As you see the results are very close now but still even 0.01 differences make significant differences at some points (with a strong force or situation like in the client ball enters pocket but in the server it doesn't with a very small difference and such..).
I know the main problem here is physics random numbers and floating point arithmetic but I still believe there could be a workaround for this as it is a turn-based game at the end.
So my question here: Is it possible to make Unity physics deterministic and make it work with this approach?
Or:
Only way for this is state sync from server to clients which uses bandwidth around 6kB/s per player (16 balls, 12 bytes for position, 16 bytes for rotation, 10 bytes for header). Down side for this is; it will very expensive when we reach huge amount of players, also connection speed could effect this a lot.
Or: Writing our own stable physics for it. Down side for this is; production cost and optimization issues.
I hope someone could lead me to a possible solution for this.
Thanks in advance!!