Skip to content

Creating Structures & Messages

Creating Message Structures

Note

The library heavily (ab)uses generics for optimal code generation and maximum throughput.

First, a struct or class must be annotated by implementing the IMessage interface.

// Structures can specify their own custom serializer(s) and compressor(s).  
// IMessage<TStruct, TSerializer, TCompressor>
public struct Vector3 : IMessage<Vector3, SystemTextJsonSerializer<Vector3>, DummyCompressor>
{
    // IMessage
    public sbyte GetMessageType() => (sbyte)MessageType.Vector3;
    public SystemTextJsonSerializer<Vector3SystemTextJson> GetSerializer() => new();
    public DummyCompressor? GetCompressor() => null;

    // Example Data
    public float X { get; set; }
    public float Y { get; set; }
    public float Z { get; set; }
}

Each message must define the following methods:
- GetMessageType: Returns the unique message type. Valid values are between 0 and 127.
- GetSerializer: Returns an instance of the serializer used to serialize/deserialize the message.
- GetCompressor: Returns an instance of the compressor used to compress/decompress the message.

The type of serializer (TSerializer) and type of compressor (TCompressor) are defined in the IMessage interface; here they are SystemTextJsonSerializer and DummyCompressor specifically.

Return null for compressor if no compression is requested.

Pack Messages

To pack an instance (including serialization & compression), call the extension method Serialize() in Reloaded.Messaging.Messages.MessageWriterExtensions.

var sample = new Vector3(0.0f, 1.0f, 2.0f);
using var serialized = sample.Serialize(ref sample);

// Access message via `serialized.Span`.
// You can now e.g. send this message over the network.
Client.FirstPeer.Send(serialized.Span, DeliveryMethod.ReliableOrdered);

Danger

Serialization result must be disposed before serializing another instance due to internal pooling.
The return value ReusableSingletonMemoryStream can have at most 1 instance per thread.

Alternative lower level API: MessageWriter<TStruct, TSerializer, TCompressor>.

Unpack Messages

Info

Provided for completeness, this is usually automated for you.
Only low level API provided.

// Read message header.
HeaderReader.ReadHeader(message.Span, out var messageType, out var compressedSize, out var headerSize);

// Create deserializer & deserialize
// Generic arguments to MessageReader are same as ones to IMessage.
var deserialize  = new MessageReader<Vector3ReloadedMemoryDummyCompression, UnmanagedReloadedMemorySerializer<Vector3ReloadedMemoryDummyCompression>, NullCompressor>(in structure);
Vector3 deserialized = deserialize.Deserialize(message.Span.Slice(headerSize), compressedSize);