Skip to content

Instantly share code, notes, and snippets.

@liamcary
Created September 26, 2025 02:03
Show Gist options
  • Select an option

  • Save liamcary/afece801db8040e78eeda82001d67fb4 to your computer and use it in GitHub Desktop.

Select an option

Save liamcary/afece801db8040e78eeda82001d67fb4 to your computer and use it in GitHub Desktop.
Mirror NetworkBehaviour where SyncVars are Serialized/Deserialized before SyncObjects
using Mirror;
/// <summary>
/// A network behaviour that serializes SyncVars before SyncObjects (SyncList, SyncDictionary, etc), instead of the other way around.
/// This is handy if you want the client to receive a sync var before processing operations to a sync list.
/// </summary>
public class ReverseNetworkBehaviour : NetworkBehaviour
{
readonly SyncList<int> _exampleList1 = new(); // Serialized/Deserialized 3rd
readonly SyncList<int> _exampleList2 = new(); // Serialized/Deserialized 4th
[SyncVar] int _exampleVariable1; // Serialized/Deserialized 1st
[SyncVar] int _exampleVariable2; // Serialized/Deserialized 2nd
/// <summary>
/// Override serialization functions to serialize syncvars before syncobjects, so that we deserialize the physics frame/time data
/// before deserializing the position/velocity SyncLists
/// </summary>
public override void OnSerialize(NetworkWriter writer, bool initialState)
{
SerializeSyncVars(writer, initialState);
SerializeSyncObjectsCopy(writer, initialState);
}
/// <summary>
/// Override serialization functions to serialize syncvars before syncobjects, so that we deserialize the physics frame/time data
/// before deserializing the position/velocity SyncLists
/// </summary>
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
DeserializeSyncVars(reader, initialState);
DeserializeSyncObjectsCopy(reader, initialState);
}
/// <summary>
/// Copy of NetworkBehaviour.SerializeSyncObjects because it is private
/// </summary>
void SerializeSyncObjectsCopy(NetworkWriter writer, bool initialState)
{
if (initialState) {
SerializeObjectsAll(writer);
} else {
SerializeObjectsDelta(writer);
}
}
/// <summary>
/// Copy of NetworkBehaviour.DeserializeSyncObjects because it is private.
/// </summary>
void DeserializeSyncObjectsCopy(NetworkReader reader, bool initialState)
{
if (initialState) {
DeserializeObjectsAllCopy(reader);
} else {
DeserializeObjectsDeltaCopy(reader);
}
}
/// <summary>
/// Copy of NetworkBehaviour.DeserializeObjectsAll because it is internal
/// </summary>
void DeserializeObjectsAllCopy(NetworkReader reader)
{
for (int i = 0; i < syncObjects.Count; i++) {
SyncObject syncObject = syncObjects[i];
syncObject.OnDeserializeAll(reader);
}
}
/// <summary>
/// Copy of NetworkBehaviour.DeserializeObjectsDelta because it is internal
/// </summary>
void DeserializeObjectsDeltaCopy(NetworkReader reader)
{
ulong dirty = reader.ReadULong();
for (int i = 0; i < syncObjects.Count; i++) {
// check dirty mask at nth bit
SyncObject syncObject = syncObjects[i];
if ((dirty & (1UL << i)) != 0) {
syncObject.OnDeserializeDelta(reader);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment