Network compression: packed vectors

The Microsoft.Xna.Framework.Graphics.PackedVector namespace contains types that could be described as "quantization for lazy people". This functionality was originally designed for packing textures and vertex buffers into smaller GPU formats, but is equally useful for compressing network packets.

Consider this line from our Peer-to-Peer sample:


The tank position is a Vector2, which contains two floating point fields, each 32 bits in size. Using a HalfVector2 struct, we can convert the floats to 16 bit format, then send them both over the wire as a single 32 bit integer:

    HalfVector2 packedVector = new HalfVector2(localTank.Position);


This 16 bit half-float format has less range and precision than a regular 32 bit float, but is often good enough to get the job done, and a 50% compression ratio is nothing to sneeze at!

To read the data, change this line from the original sample:

    remoteTank.Position = packetReader.ReadVector2();


    HalfVector2 packedVector = new HalfVector2();

packedVector.PackedValue = packetReader.ReadUInt32();

remoteTank.Position = packedVector.ToVector2();

All the PackedVector types have their uses, but here are the ones you will encounter most often:

  • To pack a float
  • To pack a Vector3

Comments (1)

  1. Ian Murray says:

    Hey Shawn,

    It probably seems weird to get a post or comment on this nearly 4 years after it was posted but have you got any advice on saving or serializing halfvectors?

    I've tried using it to store a padstate and I get an error telling me it's "not marked as serializable"

    Is there another method of packing this kind of data down?

Skip to main content