-
Notifications
You must be signed in to change notification settings - Fork 6
en SyncVar Network Sync
InnoVault provides an automatic network synchronization mechanism based on the
[SyncVar]attribute — just mark fields and they will be automatically serialized/deserialized in multiplayer.
| Component | Description |
|---|---|
[SyncVar] |
Attribute tag, marks fields or properties that need synchronization |
SyncVarManager |
Static manager, automatically discovers and serializes [SyncVar]-marked members via reflection |
Add the [SyncVar] attribute to any field or property in any class:
using InnoVault;
public class MyNPCOverride : NPCOverride
{
[SyncVar]
public int CustomHealth;
[SyncVar]
public float SpeedMultiplier;
[SyncVar]
public bool IsEnraged;
[SyncVar]
public Vector2 TargetPosition;
// Fields without [SyncVar] will not be synced
public int LocalOnlyData;
}SyncVarManager's Send / Receive methods automatically handle all marked fields:
// Send — writes all [SyncVar] fields to BinaryWriter
SyncVarManager.Send(myInstance, writer);
// Receive — reads from BinaryReader and sets all [SyncVar] fields
SyncVarManager.Receive(myInstance, reader);In the
NPCOverrideandActorsystems, SyncVar is already automatically integrated into the network sync flow — typically no manual calls are needed.
SyncVarManager supports the following types out of the box:
| Type | Write Method | Read Method |
|---|---|---|
int |
Write(int) |
ReadInt32() |
float |
Write(float) |
ReadSingle() |
bool |
Write(bool) |
ReadBoolean() |
string |
Write(string) |
ReadString() |
byte |
Write(byte) |
ReadByte() |
short |
Write(short) |
ReadInt16() |
long |
Write(long) |
ReadInt64() |
double |
Write(double) |
ReadDouble() |
Color |
Write(PackedValue) |
new Color { PackedValue } |
Vector2 |
WriteVector2() |
ReadVector2() |
Point16 |
WritePoint16() |
ReadPoint16() |
Point |
WritePoint() |
ReadPoint() |
Item |
ItemIO.Send() |
ItemIO.Receive() |
If you need to sync types beyond the built-in ones:
// Register in Mod.Load()
SyncVarManager.RegisterSyncType<MyStruct>(
(writer, value) => {
writer.Write(value.X);
writer.Write(value.Y);
writer.Write(value.Name);
},
reader => new MyStruct {
X = reader.ReadInt32(),
Y = reader.ReadInt32(),
Name = reader.ReadString()
}
);SyncVarManager guarantees deterministic serialization order:
- Inheritance chain from base to derived: Base class fields are serialized first
-
Same level sorted by name: Using
StringComparison.Ordinallexicographic order -
Both fields and properties are supported: Properties must have both
getandset
public class Base {
[SyncVar] public int Alpha; // Serialization order 1
[SyncVar] public int Beta; // Serialization order 2
}
public class Child : Base {
[SyncVar] public int Charlie; // Serialization order 3
[SyncVar] public int Delta; // Serialization order 4
}NPCOverride's OtherNetWorkSendHander automatically calls SyncVarManager.Send after writing custom data, and the receiver similarly calls SyncVarManager.Receive:
public class BossOverride : NPCOverride
{
public override int TargetID => NPCID.KingSlime;
[SyncVar]
public int Phase;
[SyncVar]
public float Rage;
public override bool AI() {
if (VaultUtils.isServer && Phase != GetCurrentPhase()) {
Phase = GetCurrentPhase();
NetOtherWorkSend = true; // Trigger sync, [SyncVar] fields automatically included
}
return true;
}
}The Actor base class has built-in [SyncVar]-marked common fields (Active, Width, Height, Rotation, Scale, Position, Velocity), and automatically syncs via SendSyncData / ReceiveSyncData:
public class MyActor : Actor
{
[SyncVar]
public int CustomState;
public override void AI() {
if (CustomState != newState) {
CustomState = newState;
NetUpdate = true; // Mark for sync
}
}
}TileProcessor's SendData / ReceiveData also integrates SyncVar:
public class MyTP : TileProcessor
{
[SyncVar]
public int StoredEnergy;
// SyncVar fields are automatically synced in SendData/ReceiveData
}[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SyncVarAttribute : Attribute { }| Method | Description |
|---|---|
RegisterSyncType<T>(writer, reader) |
Register serialization methods for a custom type |
GetSyncVars(Type) |
Get all [SyncVar] member list for a specified type (cached) |
Send(object, BinaryWriter) |
Write all [SyncVar] fields of an object to the stream |
Receive(object, BinaryReader) |
Read from the stream and set all [SyncVar] fields on an object |
-
Properties must be readable and writable: properties marked
[SyncVar]need bothgetandset - Registered types only: fields of unregistered types are silently skipped
- Reflection cache: the first access to a type collects member info via reflection; later calls use the cache
-
No collection types:
List,Dictionary, etc. require custom handling viaRegisterSyncType -
Local data unaffected: fields not marked
[SyncVar]are not included in network serialization
| Previous | Home | Next |
|---|---|---|
| Override System | Home | Actor Entity System |