diff --git a/MLAPI/MLAPI.csproj b/MLAPI/MLAPI.csproj
index 8507873..8e56c79 100644
--- a/MLAPI/MLAPI.csproj
+++ b/MLAPI/MLAPI.csproj
@@ -78,6 +78,9 @@
+
+
+
diff --git a/MLAPI/NetworkingManagerComponents/Binary/BinaryHelpers.cs b/MLAPI/NetworkingManagerComponents/Binary/BinaryHelpers.cs
new file mode 100644
index 0000000..f9de861
--- /dev/null
+++ b/MLAPI/NetworkingManagerComponents/Binary/BinaryHelpers.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MLAPI.NetworkingManagerComponents.Binary
+{
+ public static class BinaryHelpers
+ {
+ // Swap endianness of a given integer
+ public static uint SwapEndian(uint value) => (uint)(((value >> 24) & (255 << 0)) | ((value >> 8) & (255 << 8)) | ((value << 8) & (255 << 16)) | ((value << 24) & (255 << 24)));
+ public static ulong SwapEndian(ulong value) =>
+ ((value >> 56) & 0xFF) |
+ ((value >> 40) & (0xFFUL << 8)) |
+ ((value >> 24) & (0xFFUL << 16)) |
+ ((value >> 8) & (0xFFUL << 24)) |
+ ((value << 56) & (0xFFUL << 56)) |
+ ((value << 40) & (0xFFUL << 48)) |
+ ((value << 24) & (0xFFUL << 40)) |
+ ((value << 8) & (0xFFUL << 32)) ;
+ }
+}
diff --git a/MLAPI/NetworkingManagerComponents/Binary/BitReader.cs b/MLAPI/NetworkingManagerComponents/Binary/BitReader.cs
new file mode 100644
index 0000000..f76dedb
--- /dev/null
+++ b/MLAPI/NetworkingManagerComponents/Binary/BitReader.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace MLAPI.NetworkingManagerComponents.Binary
+{
+ public class BitReader
+ {
+ private delegate T Getter();
+ private static readonly float[] holder_f = new float[1];
+ private static readonly double[] holder_d = new double[1];
+ private static readonly ulong[] holder_u = new ulong[1];
+ private static readonly uint[] holder_i = new uint[1];
+
+ private readonly byte[] readFrom;
+ private long bitCount = 0;
+ public BitReader(byte[] readFrom) => this.readFrom = readFrom;
+
+ public bool ReadBool()
+ {
+ bool result = (readFrom[bitCount / 8] & (byte)(1 << (int)(bitCount % 8))) != 0;
+ ++bitCount;
+ return result;
+ }
+
+ public float ReadFloat() => ReadFloating();
+ public double ReadDouble() => ReadFloating();
+ public byte ReadByte()
+ {
+ int shift = (int)(bitCount % 8);
+ int index = (int)(bitCount / 8);
+ byte lower_mask = (byte)(0xFF << shift);
+ byte upper_mask = (byte)~lower_mask;
+ byte result = (byte)(((readFrom[index] & lower_mask) >> shift) | (shift == 0 ? 0 : (readFrom[index + 1] & upper_mask) << (8 - shift)));
+ bitCount += 8;
+ return result;
+ }
+ public void SkipPadded() => bitCount += (8 - (bitCount % 8)) % 8;
+ public ushort ReadUShort() => (ushort)ReadULong();
+ public uint ReadUInt() => (uint)ReadULong();
+ public sbyte ReadSByte() => (sbyte)ZigZagDecode(ReadByte(), 1);
+ public short ReadShort() => (short)ZigZagDecode(ReadUShort(), 2);
+ public int ReadInt() => (int)ZigZagDecode(ReadUInt(), 4);
+ public long ReadLong() => ZigZagDecode(ReadULong(), 8);
+ public float[] ReadFloatArray(int known = -1) => ReadArray(ReadFloat, known);
+ public double[] ReadDoubleArray(int known = -1) => ReadArray(ReadDouble, known);
+ public byte[] ReadByteArray(int known = -1) => ReadArray(ReadByte, known);
+ public ushort[] ReadUShortArray(int known = -1) => ReadArray(ReadUShort, known);
+ public uint[] ReadUIntArray(int known = -1) => ReadArray(ReadUInt, known);
+ public ulong[] ReadULongArray(int known = -1) => ReadArray(ReadULong, known);
+ public sbyte[] ReadSByteArray(int known = -1) => ReadArray(ReadSByte, known);
+ public short[] ReadShortArray(int known = -1) => ReadArray(ReadShort, known);
+ public int[] ReadIntArray(int known = -1) => ReadArray(ReadInt, known);
+ public long[] ReadLongArray(int known = -1) => ReadArray(ReadLong, known);
+ public string ReadString() => Encoding.UTF8.GetString(ReadByteArray());
+
+ public ulong ReadULong()
+ {
+ ulong header = ReadByte();
+ if (header <= 240) return header;
+ if (header <= 248) return 240 + 256 * (header - 241) + ReadByte();
+ if (header == 249) return 2288 + 256UL * ReadByte() + ReadByte();
+ ulong res = ReadByte() | ((ulong)ReadByte() << 8) | ((ulong)ReadByte() << 16);
+ if(header > 250)
+ {
+ res |= (ulong) ReadByte() << 24;
+ if(header > 251)
+ {
+ res |= (ulong)ReadByte() << 32;
+ if(header > 252)
+ {
+ res |= (ulong)ReadByte() << 40;
+ if (header > 253)
+ {
+ res |= (ulong)ReadByte() << 48;
+ if (header > 254) res |= (ulong)ReadByte() << 56;
+ }
+ }
+ }
+ }
+ return res;
+ }
+ private T[] ReadArray(Getter g, int knownSize = -1)
+ {
+ T[] result = new T[knownSize > 0 ? (uint)knownSize : ReadUInt()];
+ for (ushort s = 0; s < result.Length; ++s)
+ result[s] = g();
+ return result;
+ }
+
+ private T ReadFloating()
+ {
+ int size = Marshal.SizeOf(typeof(T));
+ Array type_holder = size == 4 ? holder_f as Array : holder_d as Array;
+ Array result_holder = size == 4 ? holder_i as Array : holder_u as Array;
+ T result;
+ lock(result_holder)
+ lock (type_holder)
+ {
+ //for (int i = 0; i < size; ++i)
+ // holder.SetValue(ReadByte(), i);
+ if (size == 4) result_holder.SetValue(BinaryHelpers.SwapEndian(ReadUInt()), 0);
+ else result_holder.SetValue(BinaryHelpers.SwapEndian(ReadULong()), 0);
+ Buffer.BlockCopy(result_holder, 0, type_holder, 0, size);
+ result = (T)type_holder.GetValue(0);
+ }
+ return result;
+ }
+ private static long ZigZagDecode(ulong d, int bytes) => (long)(((d << (bytes * 8 - 1)) & 1) | (d >> 1));
+ }
+}
diff --git a/MLAPI/NetworkingManagerComponents/Binary/BitWriter.cs b/MLAPI/NetworkingManagerComponents/Binary/BitWriter.cs
new file mode 100644
index 0000000..5a6c46b
--- /dev/null
+++ b/MLAPI/NetworkingManagerComponents/Binary/BitWriter.cs
@@ -0,0 +1,404 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using UnityEngine;
+
+namespace MLAPI.NetworkingManagerComponents.Binary
+{
+ public sealed class BitWriter : IDisposable
+ {
+ private static readonly Queue> listPool = new Queue>();
+
+ private static readonly float[] holder_f = new float[1];
+ private static readonly double[] holder_d = new double[1];
+ private static readonly ulong[] holder_u = new ulong[1];
+ private static readonly uint[] holder_i = new uint[1];
+ private static readonly List supportedTypes = new List()
+ {
+ typeof(bool),
+ typeof(byte),
+ typeof(sbyte),
+ typeof(char),
+ typeof(short),
+ typeof(ushort),
+ typeof(int),
+ typeof(uint),
+ typeof(long),
+ typeof(ulong),
+ typeof(float),
+ typeof(double),
+ typeof(decimal)
+ };
+
+ private static readonly FieldInfo
+ dec_lo,
+ dec_mid,
+ dec_hi,
+ dec_flags;
+
+ static BitWriter()
+ {
+ dec_lo = typeof(decimal).GetField("lo", BindingFlags.NonPublic);
+ dec_mid = typeof(decimal).GetField("mid", BindingFlags.NonPublic);
+ dec_hi = typeof(decimal).GetField("hi", BindingFlags.NonPublic);
+ dec_flags = typeof(decimal).GetField("flags", BindingFlags.NonPublic);
+
+ for (int i = 0; i < 10; i++)
+ {
+ listPool.Enqueue(new List