Page 1 of 1

Network Game Programming

Posted: Wed May 25, 2011 4:18 pm
by Nitrodist
I've been asked to rewrite some networking code for a friend's project (it's called revert -- github link).

Right now it's set up to just serialize anything that's serializable and the deserialize on the other end. This is kind of annoying if you're only sending 1 float and it's 1+ KB in size.

Is there any resources out there on working with this kind of information efficiently? We're willing to use other libraries or re-invent the wheel here :P

Re: Network Game Programming

Posted: Wed May 25, 2011 4:22 pm
by Madman
Winsocks2 + binary structure?

Re: Network Game Programming

Posted: Wed May 25, 2011 9:25 pm
by SecretSquirrel
Nitrodist wrote:
I've been asked to rewrite some networking code for a friend's project (it's called revert -- github link).

Right now it's set up to just serialize anything that's serializable and the deserialize on the other end. This is kind of annoying if you're only sending 1 float and it's 1+ KB in size.

Is there any resources out there on working with this kind of information efficiently? We're willing to use other libraries or re-invent the wheel here :P


Yep, the arcane and horribly documented RPC XDR libraries contain what you need. They will pack and unpack binary data. They should also be relatively cross platform, if that matters. There is no reason a float should ever be 1KB+ in size. 20-30 bytes at the most and that's if you convert it to a string for transmission. Even if you stuck it inside an XML structure as a string representing a float, it shouldn't be more than 100bytes or so.

The key, and Madman made reference to it in a way, is that RPC expects structured data and both ends have to understand the structure.

--SS

Re: Network Game Programming

Posted: Wed May 25, 2011 10:14 pm
by bitvector
Nitrodist wrote:
Right now it's set up to just serialize anything that's serializable and the deserialize on the other end. This is kind of annoying if you're only sending 1 float and it's 1+ KB in size.

Is there any resources out there on working with this kind of information efficiently? We're willing to use other libraries or re-invent the wheel here :P

I like Protocol Buffers. After suffering through using sunrpcgen for years to generate XDR stubs, protobuf's clean generated interfaces are a breath of fresh air (and, before anyone calls me a shill, I used and liked it long before I was paid to use it). It's not perfect, but it's better than any other cross-language serialization tool I've used.

Re: Network Game Programming

Posted: Thu May 26, 2011 2:39 pm
by Nitrodist
bitvector wrote:
Nitrodist wrote:
Right now it's set up to just serialize anything that's serializable and the deserialize on the other end. This is kind of annoying if you're only sending 1 float and it's 1+ KB in size.

Is there any resources out there on working with this kind of information efficiently? We're willing to use other libraries or re-invent the wheel here :P

I like Protocol Buffers. After suffering through using sunrpcgen for years to generate XDR stubs, protobuf's clean generated interfaces are a breath of fresh air (and, before anyone calls me a shill, I used and liked it long before I was paid to use it). It's not perfect, but it's better than any other cross-language serialization tool I've used.


How are you paid to use it? Thanks for the link -- looks very useful.

Re: Network Game Programming

Posted: Thu May 26, 2011 3:13 pm
by UberGerbil
You probably know this already and were just exaggerating, but you'll never get any efficiency sending around single floats. The packet overhead alone will kill you. Sometimes elegance and simplicity has to yield to performance, and that may mean bunching up a lot of unrelated stuff in your payload to keep your wire efficiency high.

Re: Network Game Programming

Posted: Thu May 26, 2011 3:33 pm
by just brew it!
Just a few quick thoughts...

- I agree with UberGerbil, sending packets that small is extremely inefficient. Once you factor in the overhead of passing the packet through the network stack at both ends, you may find that cutting the size of the packet from 1K to (say) 20 bytes buys you squat in terms of overall efficiency. Generally you'll want to aggregate small data items together to reduce the per-packet overhead penalty.

- If there are parts of the protocol which require low latency, and other parts which require efficient operation to move large amounts of data, you will need to make intelligent decisions about when to aggregate things and when to flush them out to the network interface immediately.

- For applications which are extremely latency and/or time sensitive, but which can tolerate a certain amount of packet loss, you may wish to consider using UDP instead of TCP.

Re: Network Game Programming

Posted: Thu May 26, 2011 4:50 pm
by ChronoReverse
If this is for a game that requires timing of any sort then size efficiency isn't what you should be concerned about.

What you need to use is pipelining. Divide gametime into even timeslices and pack everything together for each. Then send the packs immediately without waiting for the previous pack to arrive at the destination (up to a preset number).


If the timing needs to be really tight (e.g., fighting games) then a form of asynchronous timing will have be implemented. Your input, the other side's inputs, what you see on the screen and what the other side sees on their screen are more loosely coupled. Take a look at GGPO for an implementation.

Re: Network Game Programming

Posted: Thu May 26, 2011 11:28 pm
by bitvector
just brew it! wrote:
Generally you'll want to aggregate small data items together to reduce the per-packet overhead penalty.

- If there are parts of the protocol which require low latency, and other parts which require efficient operation to move large amounts of data, you will need to make intelligent decisions about when to aggregate things and when to flush them out to the network interface immediately.

- For applications which are extremely latency and/or time sensitive, but which can tolerate a certain amount of packet loss, you may wish to consider using UDP instead of TCP.
So, an interesting point about your suggestion of aggregating small data items together and flushing them out: on most systems, the TCP implementation is often using something like Nagle's algorithm to do that underneath your application anyway. The socket option TCP_NODELAY is there to disable this for interactive applications. Of course, even with Nagle's algorithm disabled TCP is still not idea for low-latency games, but one could use both, keeping a TCP connection for when bulk reliable transfer is necessary and using UDP for continuous latency-critical signaling updates.

Nitrodist wrote:
How are you paid to use it? Thanks for the link -- looks very useful.
Well, I'm not really paid to use it specifically, but we use it extensively at Google.

Re: Network Game Programming

Posted: Fri May 27, 2011 7:08 am
by SecretSquirrel
UberGerbil wrote:
You probably know this already and were just exaggerating, but you'll never get any efficiency sending around single floats. The packet overhead alone will kill you. Sometimes elegance and simplicity has to yield to performance, and that may mean bunching up a lot of unrelated stuff in your payload to keep your wire efficiency high.


Specifically, the effective time to send 1 byte is the same as a 1000. As others have said, the overhead for the network stack far outweighs the actual transmission time. Keep your packets as close to a multiple of 1365 bytes for best efficiency. This of course assumes standard ethernet MTU of 1500 bytes and TCP packets.

--SS