[crossfire] Protocol & compression.
Mark Wedel
mwedel at sonic.net
Sat Mar 25 03:00:59 CST 2006
On the mailing list, irc, and elsewhere discussion came up about rather than
trying to be too clever about minimize bandwidth with things like animations to
just compress the data itself, as that keeps things simpler.
Alex ran some quick tests, getting ~40% compression rate on big map payloads.
However, that was client side, so I quickly hacked the server to do some
compression on map packets (map1a). This way, I could also time how long it
takes to do the compression (running on an athlon mp 2000 here).
General notes - small map packets are not worth compressing. The cut off to
be worth while is probably around 200 bytes.
For a big map transfer, in this case, leaving the scorn apartment building
with a 25x25 map in dm mode (so everything is visible), zlib compressed 3034
bytes to 1637 (47%) in 952 µsec. bz2 didn't do quite so good (1818) in 2113 µsec
The other case I quickly tested was standing at the far north end of scorn
(still in DM mode) to get a lot of ocean spaces. In this case, zlib compressed
806 bytes to 270 bytes (67%) in 505 µsec. bz2 compressed it to 245 in 408 µsec.
Note that 1000 µsec = 1 ms, and by default, there is 120 ms/game tick. So
spending a few milliseconds on compression doesn't seem to likely add much to
the load (get enough players it adds up, but then so does the overall bandwidth
compression).
I'm personally think zlib is better in this case, as it is faster, and for big
data, is smaller, and the interface is simpler.
For other reasons, I still think I'll add animation support to the map2
command. However, I think it also worthwhile to add something like:
S->C: compress <data>
Where data is the block of compressed data. The length of data can be
determined from the packet header (a shorter command, like comp or something
could be done).
<data> would get uncompressed on the client, and just contain normal protocol
commands that the client then processes. By abstracting at a higher level, it
allows us to compress any other protocol commands (think itemcmd for a large
inventory. Or it would involve more work, but a long list of drawinfos, like
from a shop listing).
Thoughts/comments? On the server, this is pretty simple to do (simplest would
be to add another parameter to send_with_handling on whether to compress the
data) (some data, like png images, aren't worth trying to compress).
For the client, it is more complicated, because you could have something like
'command; compressed data; command;' - right now, it justs uses a larger ring
buffer IIRC. We don't want to have to move all the data beyond our compressed
ata back - I suppose that since it is a ring buffer, we could backtrack the
buffer to insert the uncompressed data. Or use a few buffers.
More information about the crossfire
mailing list