Network compression: quantization

Originally posted to Shawn Hargreaves Blog on MSDN, Monday, December 24, 2007

Fewer bits take up less space than more bits.

If you have a number that you know will always be in the range 0-100, there is no need to send a 4 byte integer over the wire. Cast it to a byte first.

Sometimes you can reduce the necessary range by offsetting the value first. Lets say you need to send the height of a character, which is measured in centimeters. In this game, characters range from dwarves (100 cm) to giants (300 cm).

Can't cast that to a byte: our 300 cm giant would overflow.

But if we know we will never have a character shorter than 100 cm, we can offset the height range so it starts from zero:

    PacketWriter.Write((byte)(height - 100));

On the receiving end, just add 100 back on to the value before using it. No more overflow!

Other times you can reduce the range by scaling. For instance games often need to send angles, which are stored in radians as floating point values. In radians, a full circle ranges from 0 to pi*2. But what if we scaled this range so it would instead fit into 0-256? Then we could cast the angle to a single byte:

    PacketWriter.Write((byte)(rotation * 256 / MathHelper.TwoPi));

Again, just reverse the scaling on the receiving end before using the value. This quantization does lose a bit of precision, but it is usually worth it to compress a 4 byte float to quarter size.

Blog index   -   Back to my homepage