Jump to content
  • Advertisement
  • entries
    338
  • comments
    2045
  • views
    1169856

Networking code rewrite...true multiplayer physics

Sign in to follow this  
dgreen02

209 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
Sign in to follow this  


3 Comments


Recommended Comments

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.

Share this comment


Link to comment
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.

Share this comment


Link to comment
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*

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!