Repository navigation
API: Custom Packets
Send your own serialized messages over the ONI Together networking layer.
Namespaces:
-
ONI_Together.Networking.Packets.Architecture→IPacket,IPacketSkipsRegistration -
ONI_Together.Networking→PacketSendMode -
ONI_Together_API.Networking→PacketRegistryAPI,PacketSenderAPI
public interface IPacket
{
void Serialize(BinaryWriter writer);
void Deserialize(BinaryReader reader);
void OnDispatched(); // called on the receiving side after Deserialize
}Packets are identified by a hash of their type, so the same packet type must be registered on every peer. A packet that implements IPacketSkipsRegistration is ignored by auto-registration.
public class ExamplePacket : IPacket, IPacketSkipsRegistration { /* ... */ }PacketRegistryAPI (in ONI_Together_API.Networking):
| Method | Description |
|---|---|
TryRegister(Type packetType, string nameOverride = null) |
Register a single packet type |
AutoRegisterAll(Assembly? assembly = null) |
Register every IPacket in an assembly (skips IPacketSkipsRegistration) |
Important: register no earlier than the
OnAllModsLoadedHarmony event, or the main mod type may not exist yet.Important:
AutoRegisterAll()defaults to the API assembly, not your mod. Always pass your own:PacketRegistryAPI.AutoRegisterAll(typeof(MyMod).Assembly);
A [Flags] enum mapping to the underlying transport:
| Value | Int | Meaning |
|---|---|---|
Unreliable |
0 | Not guaranteed, may arrive out of order. Good for frequent position/state. |
Immediate |
1 | Flush immediately, skip buffering. |
UnreliableImmediate |
2 | Unreliable + immediate. |
NoDelay |
4 | Drop if it can't be sent quickly (unreliable only). |
UnreliableNoDelay |
7 | Unreliable + immediate + no-delay. |
Reliable |
8 | Guaranteed and ordered. Good for events/state changes. |
ReliableImmediate |
9 | Reliable + immediate. |
| Method | Default send mode | Notes |
|---|---|---|
SendToAll(IPacket, ulong? exclude = null, PacketSendMode = Reliable) |
Reliable |
Broadcast to all connected players |
SendToAllClients(IPacket, PacketSendMode = Reliable) |
Reliable |
Host only |
SendToAllExcluding(IPacket, HashSet<ulong> excludedIds, PacketSendMode = Reliable) |
Reliable |
Broadcast except listed ids |
SendToPlayer(ulong steamId, IPacket, PacketSendMode = ReliableImmediate) |
ReliableImmediate |
To one player |
SendToHost(IPacket, PacketSendMode = ReliableImmediate) |
ReliableImmediate |
Client → host |
SendToAllOtherPeers(IPacket) |
(fixed) | Host → all clients; client → wrapped and relayed via host |
All senders no-op if the packet type isn't registered or the mod isn't loaded.
using System.IO;
using ONI_Together.Networking;
using ONI_Together.Networking.Packets.Architecture;
using ONI_Together_API;
using ONI_Together_API.Networking;
public class ExamplePacket : IPacket
{
private ulong _senderId;
private string _message;
public ExamplePacket(ulong senderId, string message)
{
_senderId = senderId;
_message = message;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(_senderId);
writer.Write(_message);
}
public void Deserialize(BinaryReader reader)
{
_senderId = reader.ReadUInt64();
_message = reader.ReadString();
}
public void OnDispatched()
{
UnityEngine.Debug.Log($"From {_senderId}: {_message}");
}
}
public static class MyModPackets
{
// Call from an OnAllModsLoaded Harmony postfix / UserMod2 setup.
public static void Register()
{
PacketRegistryAPI.AutoRegisterAll(typeof(MyModPackets).Assembly);
}
public static void SendHello()
{
if (SessionInfoAPI.IsClient) return; // host-only broadcast
var packet = new ExamplePacket(SessionInfoAPI.LocalUserID, "Hello ONI Together");
PacketSenderAPI.SendToAllClients(packet, PacketSendMode.Reliable);
}
}Packets should ideally be no larger then 1000 bytes otherwise you may encounter issues.
Mod development environment setup
ONI Together API