Page 1 of 1

Networking with Physic Engines and Smooth Movement

Posted: Sat Mar 28, 2009 1:23 am
by wITTus
So, this thing really drives me crazy, I got positional updates working with nice interpolation, but not yet for rotational movements. I don't even want lag prediction or other sophisticated techniques. All I demand is a bit of smooth movement for the moment with the only requirement of having the server to do all physic calculations. But I'm not yet satisfied with my solution.

For all these guys who already have done it: What was your final solution? :) Did you REALLY implemented such complicated network code like the source engine has?? Is a client which acts as dump rendering machine still a useful alternative? Do you use extrapolation? Did you use some nice library? Is it still necessary to invest so much work in it (thinking of fast internet connections today)? Should I send positional updates or velocity updates or both?

What were your experiences?
Please tell me the story about your network code.

Posted: Sat Mar 28, 2009 1:34 am
by vipergc
I have implemented these things by having the clients do their own positional and orientation calculations and then merely exchanging positions via a packet... this offloaded a burden from the server and kept packets to a minimum

Posted: Sat Mar 28, 2009 6:50 am
by CuteAlien
My solution isn't final yet and I've already put a lot of work into it. So yes, I think there still needs to be an unholy amount of work invested. Though nearly none of my work so far has gone into optimizing the amount of data send over the network. I care a lot about keeping that possibility open in my architecture (that did cost some time), but it's not my major concern as I basically know how to do that later on (switch to UDP, send only changes, maybe do bit-compression, client-side-prediction).

What really makes network hard for me is the increased complexity of the application itself. That objects have to be created on both sides makes class architecture very different from non-network games.

But I will have the optimizing also ahead of me and well, I think everything other games use is in the end also needed for my application. They use that because it's not smooth movement otherwise and people are getting used to smooth. There are ways around it - by using another game design. Basically - don't move your avatars directly but do it "The Sims" style. Click on targets and then let the Avatars walk to the target on their own. This avoids having to care about the latency problem that hard.

My current solution does the rotation for the local player locally and positions and rotations from other players is from the server. It's not too bad, but it's not yet smooth. Other players are ok, but own player will not get around client-side prediction in the long run. And yeah - this means unfortunately that I have to introduce physics on the client - I also hate that part, but I see currently no way around that.

Posted: Sat Mar 28, 2009 11:39 am
by Nox
I use a sync-based system (contrary to message-based system) which send messages to the server, the server does the changes, distribute the changes over the syncsystem. Every action gets a timestamp and the movement is completely polationbased. This system allows easy adding client prediction because the serverstate just overwrite the clientstate, so a clientchange in the wrong direction is no big deal. This causes some jumps if the prediction was wrong but this is a little price (better than 20 clients with 20 versions of 1 world).

Shortversion:
-not messagebase but syncbased system (means only server is allowed to create real objects and serverstate overwrites clientstate)
-clientprediction is allowed and easy to implement (only creation of real objects is forbitten)
-timestamped
-every movementalgo bases on polation

Posted: Fri May 29, 2009 2:15 am
by chaoswings
If you know that performing

action A + action B = C

You can reduce network traffic by transmitting only what is necessary. In the context of a game consider this:

The game knows where Player A and Player B are standing. Player A knocks back player B and sends him flying 3 units while Player A is moved back one unit.

In this case you only send the initial positions of both players along with the action that player A took. Each client then calculates damage and the new positions all on their own. You then skip the positional update for those players for that cycle since all the clients and the server already know their location.

If you can't cut corners in one area you have to cut them somewhere else.

If you want the results to appear random you can try clever tricks. For example, if the game is timestamped then use the timestamp + sum of the player levels in a formula to produce damage. It appears random to the player but it really isn't.

Also if a player hasn't moved don't send any positional data. As for the timestamp only use milliseconds and throw away the other units since they are unnecessary.

Posted: Fri May 29, 2009 10:08 am
by Katsankat
I tried something simple that works, with a thread for reception (I dont like threads, just a test). All it does is a recv(), then check the first 2 bytes of incoming data. If it is a '4L' it calls a players[4]->turn_left();
Server was written with the C language, using asynchronous I/O multiplexing. It is about 100 lines of code...
Could not do more simple, but it reacts nicely.

Posted: Fri May 29, 2009 12:02 pm
by xDan
I hacked something together once... it just spewed positions and velocities at 30 FPS. Along with each of those position/velocity packets, there was a unique id of the object, and a type identifier.

If a packet was not received in a frame, then the object would continue to move at the velocity last received. (and presumably would jump a little when its proper position was next received).

It was peer-to-peer, and if a peer received a packet with an id of an object that did not exist, it was auto-created. Objects could also have bound to them some variables like health etc.. Each peer owned and simulated their own objects.

It was incredibly simple, incredibly hackable, but the experience was a playable and fun one (I tested it with four people across the internet). For a hobby project I'd say it was good enough.

For a master server, I had a PHP script which was "pinged" each time a game was started. This simply kept a list of the most recent IP addresses, which could be downloaded to search for games. (you simply clicked "join" in the menu and a game would be found and automatically and joined, or alternatively you could specify the IP of one peer in the game you wanted to join).

Things like NAT were ignored though.

Posted: Wed Jul 01, 2009 7:05 am
by yamashi
If you know that performing

action A + action B = C

You can reduce network traffic by transmitting only what is necessary. In the context of a game consider this:
It's called naggle's algorithm and it's already there by default, but we usually like to deactivate it because it increases lag.
Use the flag TCP_NODELAY to remove it.

My actual server is about 25 000 lines but this includes the game logic with CUDA, the physic, the anti hack, the packet handling, the encryption...
It's kinda big but totally worth it, what's better than a server that can't crash because there is a fall back system for every error possible, unhackable well at least uncrashable :p . It's fast. easy to modify since everything is completly automatic, if I want to add an opcode I have to add 4 lines of code.

Code: Select all

__function[SMSG_NEWOPCODE] = &WorldSession::HandleNewOpcode;
and
void WorldSession::HandleNewOpcode(WorldPacket& packet)
{
_world.broadcast(CMSG_CHAT,ChatPacket("New Opcode received !"),TCP);
}[/code]

Networking is annoying if you are not making a framework based on the system API, if you keep the API you will struggle with the data, endianess... but if you make a easy to use framework which takes care of serialization, packet handling, client handling... it's really easy and you will be proud of your system ^^ .
So before doing actual networking make a framework, you will see how fast you will be going once you are done with your framework.
But again networking ain't something you can master after reading one tutorial, it takes a long time and a lot of practice/theory.

Posted: Wed Jul 01, 2009 7:57 am
by FuzzYspo0N