Heyhey,
Today I tried to update the Unity NGO package to version 1.6.0 but I encountered this error:
Overflow Exception
OverflowException: Writing past the end of the buffer
Unity.Netcode.FastBufferWriter.WriteBytesSafe (System.Byte* value, System.Int32 size, System.Int32 offset) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Serialization/FastBufferWriter.cs:732)
Unity.Netcode.FastBufferWriter.WriteUnmanagedSafe[T] (Unity.Collections.NativeList1[T] value) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Serialization/FastBufferWriter.cs:1001) Unity.Netcode.FastBufferWriter.WriteValueSafe[T] (Unity.Collections.NativeList
1[T] value, Unity.Netcode.FastBufferWriter+ForGeneric unused) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Serialization/FastBufferWriter.cs:1263)
Unity.Netcode.BufferSerializerWriter.SerializeValue[T] (Unity.Collections.NativeList1[T]& value, Unity.Netcode.FastBufferWriter+ForGeneric unused) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Serialization/BufferSerializerWriter.cs:41) Unity.Netcode.BufferSerializer
1[TReaderWriter].SerializeValue[T] (Unity.Collections.NativeList1[T]& value, Unity.Netcode.FastBufferWriter+ForGeneric unused) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Serialization/BufferSerializer.cs:143) LargeByteList.NetworkSerialize[T] (Unity.Netcode.BufferSerializer
1[TReaderWriter] serializer) (at Assets/Core/RTVR/Scripts/Netcode/DuplicateBugTester.cs:13)
This is only happening for NetworkVariable() but not for RPC calls.
After some investigation I think the problem lays with the Duplicate function in the ngopackage\Runtime\NetworkVariable\NetworkVariableSerialization.cs file. It does not allow the FastBufferWritter to scale beyond 256Bytes
public void Duplicate(in T value, ref T duplicatedValue)
{
using var writer = new FastBufferWriter(256, Allocator.Temp);
var refValue = value;
Write(writer, ref refValue);
using var reader = new FastBufferReader(writer, Allocator.None);
Read(reader, ref duplicatedValue);
}
Adding something like using var writer = new FastBufferWriter(256, Allocator.Temp, 65536);
seems to fix the issue, but those files are immutable of course.
This is the code to reproduce the error:
Source code
using System;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
[Serializable]
public class LargeByteList : INetworkSerializable
{
//being filled with 1024 bytes
const int targetByteCount = 1024;
public NativeList<byte> bytes = new NativeList<byte>(Allocator.Persistent);
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref bytes);
}
public void Fill()
{
for (int i = 0; i < targetByteCount; i++)
bytes.Add(1);
}
}
[Serializable]
public class LargeDecimalContainer : INetworkSerializable
{
//sizeof(decimal) = 24 Bytes
//18 * decimal => 288 Bytes
public decimal x1, x2, x3, x4, x5, x6;
public decimal y1, y2, y3, y4, y5, y6;
public decimal z1, z2, z3, z4, z5, z6;
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref x1);
serializer.SerializeValue(ref x2);
serializer.SerializeValue(ref x3);
serializer.SerializeValue(ref x4);
serializer.SerializeValue(ref x5);
serializer.SerializeValue(ref x6);
serializer.SerializeValue(ref y1);
serializer.SerializeValue(ref y2);
serializer.SerializeValue(ref y3);
serializer.SerializeValue(ref y4);
serializer.SerializeValue(ref y5);
serializer.SerializeValue(ref y6);
serializer.SerializeValue(ref z1);
serializer.SerializeValue(ref z2);
serializer.SerializeValue(ref z3);
serializer.SerializeValue(ref z4);
serializer.SerializeValue(ref z5);
serializer.SerializeValue(ref z6);
}
public void Fill()
{
const decimal value = decimal.MaxValue;
x1 = x2 = x3 = x4 = x5 = x6 = value;
y1 = y2 = y3 = y4 = y5 = y6 = value;
z1 = z2 = z3 = z4 = z5 = z6 = value;
}
}
class DuplicateBugTester : NetworkBehaviour
{
public NetworkVariable<LargeByteList> largeByteList = new NetworkVariable<LargeByteList>(new LargeByteList());
public NetworkVariable<LargeDecimalContainer> largeDecimalContainer = new NetworkVariable<LargeDecimalContainer>(new LargeDecimalContainer());
public override void OnNetworkSpawn()
{
largeByteList.Value.Fill();
largeDecimalContainer.Value.Fill();
}
}
Have a nice day