Custom DataStream

Learn how to serialize and sync custom data types over the network using custom DataStreams.

ObjectNet provides the facility to send and receive simple and complex structured over-network ( see DataStream).

In multiplayer games, you often need to send custom data over the network—like a player’s stats, a damage hit, or a full status effect. Instead of sending each field manually every time, Custom DataStream (serialization) lets you group that data into a class and send it with a single line.

ObjectNet makes this easy with custom DataStreams.


Why Use Custom DataStream?

Let’s say you have a Damage class with two values:

public class Damage {
    public int amount;
    public Vector3 direction;
    
    //constroctor
    public Damage(int amount, Vector3 direction) {
        this.amount = amount;
        this.direction = direction;
    }
}

Without serialization, you’d need to write each value manually every time:

writer.Write<int>(damage.amount);
writer.Write<Vector3>(damage.direction);

That’s repetitive and error-prone. Instead: Serialize Once, Reuse Everywhere

With a custom DataStream, you can send the full object like this:

writer.Write<Damage>(damage);

And read it just as easily:

Damage damage = reader.Read<Damage>();

How to Create a Custom DataStream

1. Create the Data Handler

To teach ObjectNet how to read/write your class, create a new class that inherits from DataHandler<T>:

public class DamageStream : DataHandler<Damage> {
    
    public override int Write(Damage data, ref byte[] buffer, ref int offset) {        
        int result  = base.Write(data.amount, ref buffer, ref offset, typeof(int));
            result += base.Write(data.direction, ref buffer, ref offset, typeof(Vector3));
        return result;
    }

    public override Damage Read(byte[] buffer, ref int offset) {
        int  amount = Read<int>(buffer, ref offset);
        Vector3 dir = Read<Vector3>(buffer, ref offset);
        return new Damage(amount, dir);
    }
}

The order of reading must exactly match the order of writing.


2. Register Your Stream

Register your handler once (e.g. at startup):

DataStream.RegisterGlobalStream<Damage, DamageStream>();

This tells ObjectNet:

“Whenever I send or receive a Damage object, use the DamageStream class to handle it.”

Last updated