packet compression

Racer1Racer1 Join Date: 2002-11-22 Member: 9615Members
From the "curious developer" in me...
What kind of compression you are talking about? Will you use a standard compression for all packets? Or compress differently based on the type of packet? Will you use an off-the-shelf library, or have a bit of fun and design your own? Huffman coding is common for limited data sets, but it also can potentially be counter-productive when unusual data shows up. Will you dynamically update the compression model as you go, or choose more rigid (but less CPU intensive) method with a fixed dictionary?

Comments

  • Soylent_greenSoylent_green Join Date: 2002-12-20 Member: 11220Members, Reinforced - Shadow
    <!--quoteo(post=1799765:date=Sep 24 2010, 09:28 PM:name=Racer1)--><div class='quotetop'>QUOTE (Racer1 @ Sep 24 2010, 09:28 PM) <a href="index.php?act=findpost&pid=1799765"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Huffman coding is common for limited data sets, but it also can potentially be counter-productive when unusual data shows up.<!--QuoteEnd--></div><!--QuoteEEnd-->

    If you use any compression that acts over the whole packet and it turns out that an unusual packet becomes bigger when you compress it, you send it uncompressed. If you're very stingy it doesn't even have to cost one extra bit; there is probably somewhere to expropriate 1 bit without harm(say, use the most significant bit of the sequence number to denote whether or not compression was used).

    There is also lots of little tricks for data-specific lossy compression; like converting an angle from float to a 1-byte integer, which has a maximum error of 0.7 degrees(if it's just cosmetic, like the direction a player is facing, nobody is going to notice or care). If it's not cosmetic, such as a client telling the server which direction he is pointing his gun, you still might be able to get away with a 16-bit integer instead of a float; this gives you a maximum error of 10 arc seconds(corresponding to less than 0.5 mm error at 10 meter distance).
  • WavesonicsWavesonics Join Date: 2006-12-02 Member: 58833Members
    I used zlib on packets in this little <a href="http://darkrockstudios.com/public/project/networkdefense" target="_blank">networked tower defense game </a>I made. Now granted the data is probably quite a bit more repetitive than I expect NS2s data to be. But zlib was a huge win for me in terms of packet size and total bandwidth.

    However!

    In FPS games it's common to use the Quake III networking model. It's a 100% unreliable protocol. The entire thing uses UDP. You serialize the entire world state into a huge bit vector. For each client you have a copy of the last bit vector (aka: world state) that they received successfully. And you XOR these two together. Any bit that is unchanged between the two fields results in a 0. The result is a final bit vector where anything that was unchanged is all zeros, so you have tons and tons of zeros. Then! You use Run Length Encoding (RLE) to compress the final bit vector, which capitalizes on the fact that there are so many zeros.

    Once the RLE compression is done you generally have a very tiny bit of data representing only the changes between the two world states. This is send to the client where the RLE compression is expanded back into that bit vector with tons of zeros, and the client still has the last bit vector that they received successfully, so they again XOR the two, and the output is the FULL world state which you then use to update your game objects. And if the transmission fails, the server just moves on and sends the next world state, no need to try and resent lost packets.

    It's pretty damn spiffy :D

    Anyway, I'm fairly confident they are using at least some derivative of this, b/c of Max's current task:
    "Add support for reliable network messages"

    I bring this up, b/c in the Quake III model, the compression is part and parcel with the protocol, so no further compression is needed.
  • spellman23spellman23 NS1 Theorycraft Expert Join Date: 2007-05-17 Member: 60920Members
    Are most games still UDP? I would imagine that since there's more going on games may have swapped to TCP to ensure reliable delivery.
  • Soylent_greenSoylent_green Join Date: 2002-12-20 Member: 11220Members, Reinforced - Shadow
    edited September 2010
    <!--quoteo(post=1799822:date=Sep 25 2010, 04:07 PM:name=spellman23)--><div class='quotetop'>QUOTE (spellman23 @ Sep 25 2010, 04:07 PM) <a href="index.php?act=findpost&pid=1799822"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Are most games still UDP?<!--QuoteEnd--></div><!--QuoteEEnd-->

    Yes.

    <!--quoteo(post=1799822:date=Sep 25 2010, 04:07 PM:name=spellman23)--><div class='quotetop'>QUOTE (spellman23 @ Sep 25 2010, 04:07 PM) <a href="index.php?act=findpost&pid=1799822"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->I would imagine that since there's more going on games may have swapped to TCP to ensure reliable delivery.<!--QuoteEnd--></div><!--QuoteEEnd-->

    That's a non sequitur. If there's 'more going on' UDP is needed more than ever.

    TCP will wait seconds if it has to in order to ensure reliable delivery. It will send a packet, wait for an ACK, if no ACK is recieved or a resend is requested(e.g. because the checksum failed) it will try resending the same packet again and again until it recieves an ACK, only then will it move on to the next packet. This is a train wreck in any networked game that approximates real time.

    The correct behaviour in a real-time application is to keep pumping out packets without waiting for reply, never re-sending old and hopelessly outdated world states that were lost. That which has to be reliably sent comprises a small fraction of bandwidth(e.g. damage messages, player x killed player y), just resend that information in every packet until the client ACKs a packet that contains the reliable information.

    This performs much better than TCP even for reliable messages. If your latency is 100 ms round-trip a packet that fails checksum will cause the client to request a resend and it will take ~100 ms to recieve it; a lost packet will mean waiting even longer. If the server uses UDP and just keeps pumping out 50 packets per second the cost of a missing or malformed packet is an additional ~20 ms delay before you recieve the reliable message.

    If the server keeps pumping out 50 packets per second and two of them happen to arrive out of order(e.g. if the first packet takes 120 ms to arrive and the second packet takes 80 ms; such that the second packet arrives at the client before the first) that's no problem. All it means is that the client will recieve a world state that is a little more up to date, no big deal.
  • duvelduvel Join Date: 2004-02-09 Member: 26318Members, Constellation, Reinforced - Shadow
    tcp is totally useless for multiplayer games (except connecting), most
    logic protocol is udp and it will always be used for best online gaming results.
  • spellman23spellman23 NS1 Theorycraft Expert Join Date: 2007-05-17 Member: 60920Members
    M'kay. Was thinking that perhaps the super high priority to get good latency would override the accuracy checks in TCP, and I guess it does.
  • RooKRooK Join Date: 2003-10-15 Member: 21694Members, Constellation
    I can't help what Zoid (the creator of quakeworld) would have to add....

    Sounds like there are some pretty up to speed people adding to the conversation already, but how about the inventor of online gaming (basically).
  • scorpydudescorpydude Join Date: 2005-03-05 Member: 43603Members
    Soylent_green and Wavesonics, your awsome at explaining stuff! I loved reading and being able to understand whats going on in the background of things. That quake 3 example was great!

    Explain some more games programming stuff! Client side prediction, bsp tress (how games know what to drop and what not to), pathfinding :)

    I may be asking too much /sadface
  • PlasmaPlasma Join Date: 2003-04-26 Member: 15855Members, Constellation, Squad Five Blue
    Here's a nice article on prediction in Source games scorpy, <a href="http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking" target="_blank">http://developer.valvesoftware.com/wiki/So...ayer_Networking</a>
  • Racer1Racer1 Join Date: 2002-11-22 Member: 9615Members
    Very interesting read. Thanks for the primer. I hope to see some updates on this topic from the UW team in the coming weeks.
  • lwflwf Join Date: 2006-11-03 Member: 58311Members, Constellation
    edited September 2010
    Compression will always add some extra latency because the server and client will have to take extra steps to compress and decompress all data and so if it's beneficial or not depends on how fast we can compress/decompress and how badly it's needed.

    A server/client with fast CPUs but a slow link (such as your Internet connection) could reduce overall latencies and bandwidth requirements while a server/client with slow CPUs and a fast link (such as a LAN) would add latency but still save some bandwidth (although in that case it would serve no purpose). It would be necessary to choose a compression algorithm that aims to be very fast rather than compressing very well.

    Delta encoding, or "delta compression" (a bit confusing to call it compression IMO but I suppose it's true) as Valve calls it on their wiki above is probably always a sane thing to do though (even if you also use a traditional compression algorithm) because it's fast and can save a lot of bandwidth and CPU cycles since instead of sending a full snapshot in every update you only send/receive what has changed since the last one.
  • ctoon6ctoon6 Join Date: 2007-06-15 Member: 61256Members
    i don't think tcp is ever "really" needed. udp in practice is pretty much guaranteed. and even if you did loose a string of like 5 packets, you could still play the game perfectly fine.
  • JirikiJiriki retired ns1 player Join Date: 2003-01-04 Member: 11780Members, NS1 Playtester, Squad Five Silver
    edited September 2010
    Most games cannot even utilize two cores effectively as far as I know so basically you might be able do all this on a seperate thread but I hope it'll have a cvar.

    Or if you mean delta encoding, then yeah it feels kinda weird calling it compression. :l
  • Soylent_greenSoylent_green Join Date: 2002-12-20 Member: 11220Members, Reinforced - Shadow
    <!--quoteo(post=1800186:date=Sep 28 2010, 06:19 PM:name=ctoon6)--><div class='quotetop'>QUOTE (ctoon6 @ Sep 28 2010, 06:19 PM) <a href="index.php?act=findpost&pid=1800186"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->i don't think tcp is ever "really" needed. udp in practice is pretty much guaranteed. and even if you did loose a string of like 5 packets, you could still play the game perfectly fine.<!--QuoteEnd--></div><!--QuoteEEnd-->

    Look at it this way. TCP does not have access to special hardware or anything like that which could cause it to not lose packets. TCP and UDP are both built ontop of IP, with UDP being a much lower level of abstraction(and therefor more flexible).
  • Iced_EagleIced_Eagle Borg Engineer Join Date: 2003-03-02 Member: 14218Members
    <!--QuoteBegin-"maxs twitter"+--><div class='quotetop'>QUOTE ("maxs twitter")</div><div class='quotemain'><!--QuoteEBegin-->liblzf or fastlz look like they may be good options for compressing network traffic. Quake 3 used Huffman coding with a pre-determined tree<!--QuoteEnd--></div><!--QuoteEEnd-->

    <a href="http://twitter.com/#!/max_mcguire/status/25824902671" target="_blank">http://twitter.com/#!/max_mcguire/status/25824902671</a>
Sign In or Register to comment.