NetworkReader/Writer

Usage

For example, this is how we serialize an int and a float3 position in a message:

using DOTSNET;

public struct TestMessage : NetworkMessage
{
    public int classIndex;
    public float3 position;
    
    public bool Serialize(ref NetworkWriter writer) =>
        writer.WriteInt(classIndex) &&
        writer.WriteFloat3(position);
        
    public bool Deserialize(ref NetworkReader reader) =>
        reader.ReadInt(out classIndex) &&
        reader.ReadFloat3(out position);
}

Reading and Writing is:

  • Atomic: WriteInt either writes all 4 bytes int, or none if there is not enough space. ReadInt either reads all 4 bytes int, or none if the buffer doesn’t have enough data.

  • Allocation Free: all reads and writes are allocation free for maximum performance.

  • Fast: the Bitpacker’s internal buffer writes are always word aligned. This makes unaligned writes (byte/ushort/etc.) as fast as aligned writes (uint, float, etc.).

Reference Passing

To avoid allocations, NetworkReader/Writer are value types (structs). When passing a reader/writer through functions, make sure to pass it as reference:

public bool Serialize(ref NetworkWriter writer) =>
    writer.WriteInt(level);

public bool Deserialize(ref NetworkReader reader) =>
    reader.ReadInt(out level);

If you don’t pass it as reference, then it will create a copy of the Writer/Reader, which would not modify the original writer/reader’s Position.

In other words, always pass NetworkReader/Writer as reference!

Burst

DOTSNET NetworkReader/Writers are burstable.

Additionally, DOTSNET provides fixed size Readers/Writers for use in IComponentData:

  • NetworkReader128

  • NetworkWriter128

Extending NetworkReader/Writer

You can extend NetworkReader/Writer with C#’s extension system:

public struct MyStruct
{
    public int level;
    public int experience;
}
using DOTSNET;    

public static class Extensions
{
    public static bool WriteMyStruct(ref this NetworkWriter writer, MyStruct value)
    {
        return writer.WriteInt(value.level) &&
               writer.WriteInt(value.experience);
    }
   
    public static bool ReadMyStruct(ref this NetworkReader reader, out MyStruct value)
    {
        value = new MyStruct();
        return reader.ReadInt(out value.level) &&
               reader.ReadInt(out value.experience);
    }
}

Last updated