Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am currently developing a little 2D sandbox game with multiplayer functionality in XNA 4.0 and the latest lidgren-lib for networking.

I found myself quickly at a point where sending a players position to the server and broadcasting the position of all players to the connected clients isn't enough anymore. So I started to make up a protocol for the game.

I haven't done this before, so I'm wondering weather there're any guidelines/tutorials/articles which guide one through this process. A good starting point for me was the protocol of Minecraft, but this isn't a guide or something but rather a well example which I can adopt at some points.

So, are there any guidelines/articles/tutorials for creating a network protocol for games?

share|improve this question

closed as not constructive by Byte56, bummzack, ClassicThunder, Anko, msell Apr 26 '13 at 6:26

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
Yes, those guidelines/articles/tutorials exist, however, listing them here wouldn't be constructive. Since one guideline/article/tutorial does not make a more correct answer than any other, your question will just generate a list of responses without a correct answer. Since we're a Q/A site, we like it when the questions have correct answers. See the FAQ about "which technology is better". –  Byte56 Apr 25 '13 at 14:07
    
I recommend popping into the chat with this question. Likely to get pointed to some guides relevant to your situation. –  ClassicThunder Apr 25 '13 at 14:59
    
@Byte56 can you link me some of this stuff, though? –  prc322 Apr 25 '13 at 17:07
    
@ClassicThunder I don't have a specfic problem/situation. My situation is that I'm new to the field and would like to learn from experienced people about. –  prc322 Apr 25 '13 at 17:07

1 Answer 1

I'm still somewhat new on this, and so I may of missed some things. However, I'll try help regardless.

How is simply sending a position "not enough anymore?" There will always be lag and nothing can be done about that.

A game network protocol is generally unique for every game because only the people making the game knows what needs to be sent and how often to send it. Note that there are a few game engines that send all object data, and as such require virtually no code for networking. This is usually a bad idea for all but the most simplest games due to the amount of data being sent, it quickly faces scaling problems. For example, you don't need to send individual particle data across a network, but such an engine may just do that depending on how the game is coded.

As such, it's rather difficult to make any such tutorial on this subject.

Since this is a sandbox game, let's assume that messages have to be guaranteed since latency isn't such a big issue and most messages need to arrive safely.

Let's have a look at what the minecraft protocol says about player position. http://mc.kev009.com/Protocol#Player_Position_.280x0B.29

The player position packet has PacketID, X, Y, and Z. The rest isn't important right at the moment. X,Y,Z are doubles, and PacketID is a Byte. So the Packet is bye + (double * 3). The client sends this to the server at specified intervals, and then the server sends this to the other clients. You may or may not wish to send an "Ok" packet back from the server to the original client.

That's really all there is to it at the basic level of a protocol. You don't want to send the position every frame as you'll flood your bandwidth. The number of updates really depends on the game.

There are more advanced techniques to dealing with lag, such as prediction. http://en.wikipedia.org/wiki/Client-side_prediction There are two kinds. First is the client doing actions without checking if it's valid by the server. Generally you want to do this for everything, because otherwise you'll have to wait for the server to respond before you jump or move. Not good. The second is predicting what other clients are doing. If someone is falling, it's pretty easy to predict what's going to happen - he'll keep falling until he lands on something or falls out of the game world. As such, you can predict his current position before the server can even give it to you and then update as needed.

    Vector3 Position2UpdatesAgo = new Vector3(0,0,0); //Packet received from server.
    Vector3 PositionLastUpdate = new Vector3(1,0,0); //Packet received from server.
    // We have not received the current position from the server, so
    // let's try predict where he will be and move him in our local client.
    Vector3 Position = PositionLastUpdate = Position2UpdatesAgo + (PositionLastUpdate - Position2UpdatesAgo);
    // Position = Vector3 { x = 2, y = 0, z = 0 }

You can further save bandwidth by only updating every so often and lerping http://en.wikipedia.org/wiki/Linear_interpolation between the updates. I believe XNA has a lerp function inbuilt. As such, you'd go something like this.

    Vector3 Position2UpdatesAgo = new Vector3(0,0,0); //Packet recieved from server.
    Vector3 PositionLastUpdate = new Vector3(1,0,0); //Packet recieved from server.

    int LastUpdateRecievedMS = 1000; // You'd want to use something like MS since game start/computer start.
    int PredictionTime = 250; // Let's say we predict 250ms into the future. Note that "250" isn't correct, it would be a time based of frameTime and ping.

    Vector3 FuturePosition = PositionLastUpdate = (Position2UpdatesAgo + (PositionLastUpdate - Position2UpdatesAgo) * PredictionTime;

    // We should check to see if CurrentTimeMS() > LastUpdateRecievedMS + PredictionTime. If so, we'll predict further into the future.
    // When we get a new update we'll update all these variables again, and the lerp will help deal with any "jittering" by smoothing out any rough bits,
    // assuming the prediction isn't too far off.
    Vector3 Position = Math.Lerp(PositionLastUpdate, FuturePosition, CurrentTimeMS() / (LastUpdateRecievedMS + PredictionTime);

There are likely to be other ways to deal with network optimization. Really though, you cannot update faster then your ping time and only within the limits of your upload and download speeds. Don't forget that the max throughput of a connection is Download/Ping and Upload/Ping. The data you can send will be less due to losses from header information, packets that arrive out of order, lost/dropped packets, incomplete packets, etc. We never really can update fast enough, but we can fool people into thinking that it's happening.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.