• 12
• 14
• 13
• 10
• 11
• entries
338
2047
• views
1162580

# Networking code rewrite...true multiplayer physics

188 views

I'm currently neck deep in re-writing all of the game's network code. Everything is now done server side. The only thing that gets sent from client -> server is the user's input/key presses...all the calculations are done on the server. The bare minimum required to render the scene is sent back to the clients. Before I was doing half the stuff client side, and it was a big mess.

This new system makes vehicle -> vehicle collisions possible, as well as physics on NPCs & player controlled characters. Real-time networked object physics will now be possible for the streetside objects as well.

Network bandwidth usage has been cut to < 7kb downstream each second which is a lot less than it was before, and the bandwidth required to upload the changes in the user's input is trivial, < 0.1kb a second. Frame rates should be a lot higher now on slower computers, since a lot of calculations have been moved to the server.

I had some reservations about getting this to work, but I am pleasantly suprised with the results so far. Some quick points of interest regarding the multiplayer physics -
- Physics calculations are done server side @ 150FPS [using the Newton Physics Library].
- Game update packets are send to clients 15-20 times a second. Actors, Vehicles, Objects are each sent in different packets, one per frame, containing all the changed information for that type of object.
- Take each 3x3 rotation matrix and convert it to a quaternion before sending across the network, saving you 5 floats per object.
- Have a tight ring around client characters which turns off physics for distant objects.
- Do an initial sweep of all physics objects...flagging each as 'needing to be sent', by comparing to the value last sent to that client.
- Save 'last sent' values for each client, don't just set the last sent values after each update.
- Break up vectors & quaternions into separate elements (ie: w,x,y,z) checking to see if each element has changed, and only sending the changed element verses the entire vector/quaternion.
- Use a 'delta value' to reduce frequency of sending values across the network...some pseudo code..
//Sync a quaternion element the easy way...if(Quaternion.w != LastSentQuaternion.w) { Send(Quaternion.w); LastSentQuaternion.w = Quaternion.w;}...//Now the better way...use a delta value to reduce bandwidth.//Higher delta values reduce bandwidth, lower values produce better results, but use more bandwidth.float QuaternionDelta = 0.001;if(fabs(Quaternion.w - LastSentQuaternion.w) > QuaternionDelta){ Send(Quaternion.w); LastSentQuaternion.w = Quaternion.w;}

By using 0.00001 as my delta value [for rotations and positions] things looked like they were local. In practice 0.001 tends to be a good balance...while 0.01 looked way too choppy.

I've also coded up a net-graph to help debug the networking. All packets received during a frame are displayed on a single line, each packet type is color coded. I display the last 150 frames in the netgraph.

In my tests on the server (with 2 clients and 30ms-50ms ping) the vehicle + actor physics synchronization worked flawlessly...being able to truly interact with other people online will add so much to the game. I must admit I based the system off the networking in the Source engine...I've implemented almost everything in this article [ Source Engine Multiplayer Networking. ] except for the client side prediction, which will come later, after I can get a better feel for the lag levels.

I will probably post a video in the next few days [grin]. I'm extremely excited with how good things are working out with the new netcode though...except it's going to take a day or two longer than I had hoped.

- Dan

Won't calculating physics on the server effect the response time for the user?

User hits key -> client sends command to server -> Server calculates move -> New position is sent to user -> User rerenders

Seems like it'd get frustrating as lag increases.

Yes, that's where the client-side prediction kicks in :-D but with my pings of ~50ms things look fine w/out any kind of prediction.

You perform the action, and if in the future the player is in a different position, you correct them.

If you've got a 200+ ping it's going to look bad when you're controlling your gangster. Though the RTS mode will still look fine regardless of the ping. Raknet has a 'fake lag' feature I'm going to use to fine tune the prediction code.

Awesome! I can't wait for a video. :)

Also, good choice on modeling after Source engine... With so many players using the netcode, you know the way they think about MP netcode works ;)

Hopefully this brings you one step closer to beta! *gasp*