diff --git a/LiteEntitySystem/ClientEntityManager.cs b/LiteEntitySystem/ClientEntityManager.cs
index ad0db98..43c9432 100644
--- a/LiteEntitySystem/ClientEntityManager.cs
+++ b/LiteEntitySystem/ClientEntityManager.cs
@@ -157,10 +157,10 @@ private readonly struct SyncCallInfo
         {
             public readonly InternalEntity Entity;
             
-            private readonly OnSyncCallDelegate _onSync;
+            private readonly MethodCallDelegate _onSync;
             private readonly int _prevDataPos;
 
-            public SyncCallInfo(OnSyncCallDelegate onSync, InternalEntity entity, int prevDataPos)
+            public SyncCallInfo(MethodCallDelegate onSync, InternalEntity entity, int prevDataPos)
             {
                 _onSync = onSync;
                 Entity = entity;
diff --git a/LiteEntitySystem/Internal/EntityFieldInfo.cs b/LiteEntitySystem/Internal/EntityFieldInfo.cs
index e97798f..d516d5c 100644
--- a/LiteEntitySystem/Internal/EntityFieldInfo.cs
+++ b/LiteEntitySystem/Internal/EntityFieldInfo.cs
@@ -25,7 +25,7 @@ internal struct EntityFieldInfo
         public readonly bool IsPredicted;
         public OnSyncExecutionOrder OnSyncExecutionOrder;
         
-        public OnSyncCallDelegate OnSync;
+        public MethodCallDelegate OnSync;
         public int FixedOffset;
         public int PredictedOffset;
 
diff --git a/LiteEntitySystem/Internal/InternalBaseClass.cs b/LiteEntitySystem/Internal/InternalBaseClass.cs
index da45d92..3b0d9b0 100644
--- a/LiteEntitySystem/Internal/InternalBaseClass.cs
+++ b/LiteEntitySystem/Internal/InternalBaseClass.cs
@@ -1,22 +1,7 @@
-using System;
-using System.Runtime.CompilerServices;
-
 namespace LiteEntitySystem.Internal
 {
     public abstract class InternalBaseClass
     {
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        protected void ExecuteRPC(in RemoteCall rpc) => rpc.Call(this);
-        
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        protected void ExecuteRPC<T>(in RemoteCall<T> rpc, T value) where T : unmanaged => rpc.Call(this, value);
-        
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        protected void ExecuteRPC<T>(in RemoteCallSpan<T> rpc, ReadOnlySpan<T> value) where T : unmanaged => rpc.Call(this, value);
-        
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        protected void ExecuteRPC<T>(in RemoteCallSerializable<T> rpc, T value) where T : struct, ISpanSerializable => rpc.Call(this, value);
-        
         protected internal virtual void OnSyncRequested()
         {
             
diff --git a/LiteEntitySystem/Internal/InternalEntity.cs b/LiteEntitySystem/Internal/InternalEntity.cs
index 1c2b98c..3cc31d4 100644
--- a/LiteEntitySystem/Internal/InternalEntity.cs
+++ b/LiteEntitySystem/Internal/InternalEntity.cs
@@ -203,7 +203,7 @@ protected internal virtual void OnConstructed()
 
         internal void RegisterRpcInternal()
         {
-            ref var classData = ref EntityManager.ClassDataDict[ClassId];
+            ref var classData = ref EntityManager.ClassDataDict[ClassId];
             
             //setup field ids for BindOnChange and pass on server this for OnChangedEvent to StateSerializer
             var onChangeTarget = EntityManager.IsServer && !IsLocal ? this : null;
@@ -225,7 +225,7 @@ internal void RegisterRpcInternal()
             if(classData.RemoteCallsClient == null)
             {
                 rpcCahce = new List<RpcFieldInfo>();
-                var rpcRegistrator = new RPCRegistrator(rpcCahce);
+                var rpcRegistrator = new RPCRegistrator(rpcCahce, classData.Fields);
                 RegisterRPC(ref rpcRegistrator);
                 //Logger.Log($"RegisterRPCs for class: {classData.ClassId}");
             }
@@ -266,6 +266,59 @@ protected virtual void RegisterRPC(ref RPCRegistrator r)
         {
             r.BindOnChange(this, ref _isDestroyed, OnDestroyChange);
         }
+        
+        protected void ExecuteRPC(in RemoteCall rpc)
+        {
+            if (IsServer)
+            {
+                if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
+                    rpc.CachedAction(this);
+                ServerManager.AddRemoteCall(this, rpc.Id, rpc.Flags);
+            }
+            else if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && IsLocalControlled)
+                rpc.CachedAction(this);
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCall<T> rpc, T value) where T : unmanaged
+        {
+            if (IsServer)
+            {
+                if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
+                    rpc.CachedAction(this, value);
+                unsafe
+                {
+                    ServerManager.AddRemoteCall(this, new ReadOnlySpan<T>(&value, 1), rpc.Id, rpc.Flags);
+                }
+            }
+            else if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && IsLocalControlled)
+                rpc.CachedAction(this, value);
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCallSpan<T> rpc, ReadOnlySpan<T> value) where T : unmanaged
+        {
+            if (IsServer)
+            {
+                if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
+                    rpc.CachedAction(this, value);
+                ServerManager.AddRemoteCall(this, value, rpc.Id, rpc.Flags);
+            }
+            else if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && IsLocalControlled)
+                rpc.CachedAction(this, value);
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCallSerializable<T> rpc, T value) where T : struct, ISpanSerializable
+        {
+            if (IsServer)
+            {
+                if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
+                    rpc.CachedAction(this, value);
+                var writer = new SpanWriter(stackalloc byte[value.MaxSize]);
+                value.Serialize(ref writer);
+                ServerManager.AddRemoteCall<byte>(this, writer.RawData.Slice(0, writer.Position), rpc.Id, rpc.Flags);
+            }
+            else if (rpc.Flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && IsLocalControlled)
+                rpc.CachedAction(this, value);
+        }
 
         protected InternalEntity(EntityParams entityParams)
         {
diff --git a/LiteEntitySystem/RPCRegistrator.cs b/LiteEntitySystem/RPCRegistrator.cs
index 01dc932..31239cd 100644
--- a/LiteEntitySystem/RPCRegistrator.cs
+++ b/LiteEntitySystem/RPCRegistrator.cs
@@ -6,45 +6,71 @@
 namespace LiteEntitySystem
 {
     public delegate void SpanAction<T>(ReadOnlySpan<T> data);
-    public delegate void SpanAction<TCaller, T>(TCaller caller, ReadOnlySpan<T> data);
+    public delegate void SpanAction<in TCaller, T>(TCaller caller, ReadOnlySpan<T> data);
     internal delegate void MethodCallDelegate(object classPtr, ReadOnlySpan<byte> buffer);
-    internal delegate void OnSyncCallDelegate(object classPtr, ReadOnlySpan<byte> buffer);
     
     public readonly struct RemoteCall
     {
-        internal readonly Action<InternalBaseClass> CachedAction;
-        internal RemoteCall(Action<InternalBaseClass> action) => CachedAction = action;
-        internal void Call(InternalBaseClass self) => CachedAction?.Invoke(self);
         internal static MethodCallDelegate CreateMCD<TClass>(Action<TClass> methodToCall) => (classPtr, _) => methodToCall((TClass)classPtr);
+        
+        internal readonly Action<InternalEntity> CachedAction;
+        internal readonly ushort Id;
+        internal readonly ExecuteFlags Flags;
+        internal readonly bool Initialized;
+        
+        internal RemoteCall(Action<InternalEntity> action, ushort rpcId, ExecuteFlags flags)
+        {
+            CachedAction = action;
+            Id = rpcId;
+            Flags = flags;
+            Initialized = true;
+        }
     }
     
     public readonly struct RemoteCall<T> where T : unmanaged
     {
-        internal readonly Action<InternalBaseClass, T> CachedAction;
-        internal RemoteCall(Action<InternalBaseClass, T> action) => CachedAction = action;
-        internal void Call(InternalBaseClass self, T data) => CachedAction?.Invoke(self, data);
         internal static unsafe MethodCallDelegate CreateMCD<TClass>(Action<TClass, T> methodToCall) =>
             (classPtr, buffer) =>
             {
                 fixed (byte* data = buffer)
                     methodToCall((TClass)classPtr, *(T*)data);
             };
+        
+        internal readonly Action<InternalEntity, T> CachedAction;
+        internal readonly ushort Id;
+        internal readonly ExecuteFlags Flags;
+        internal readonly bool Initialized;
+        
+        internal RemoteCall(Action<InternalEntity, T> action, ushort rpcId, ExecuteFlags flags)
+        {
+            CachedAction = action;
+            Id = rpcId;
+            Flags = flags;
+            Initialized = true;
+        }
     }
     
     public readonly struct RemoteCallSpan<T> where T : unmanaged
     {
-        internal readonly SpanAction<InternalBaseClass, T> CachedAction;
-        internal RemoteCallSpan(SpanAction<InternalBaseClass, T> action) => CachedAction = action;
-        internal void Call(InternalBaseClass self, ReadOnlySpan<T> data) => CachedAction?.Invoke(self, data);
         internal static MethodCallDelegate CreateMCD<TClass>(SpanAction<TClass, T> methodToCall) =>
             (classPtr, buffer) => methodToCall((TClass)classPtr, MemoryMarshal.Cast<byte, T>(buffer));
+        
+        internal readonly SpanAction<InternalEntity, T> CachedAction;
+        internal readonly ushort Id;
+        internal readonly ExecuteFlags Flags;
+        internal readonly bool Initialized;
+
+        internal RemoteCallSpan(SpanAction<InternalEntity, T> action, ushort rpcId, ExecuteFlags flags)
+        {
+            CachedAction = action;
+            Id = rpcId;
+            Flags = flags;
+            Initialized = true;
+        }
     }
     
     public readonly struct RemoteCallSerializable<T> where T : struct, ISpanSerializable
     {
-        internal readonly Action<InternalBaseClass, T> CachedAction;
-        internal RemoteCallSerializable(Action<InternalBaseClass, T> action) => CachedAction = action;
-        internal void Call(InternalBaseClass self, T data) => CachedAction?.Invoke(self, data);
         internal static MethodCallDelegate CreateMCD<TClass>(Action<TClass, T> methodToCall) =>
             (classPtr, buffer) =>
             {
@@ -53,15 +79,30 @@ internal static MethodCallDelegate CreateMCD<TClass>(Action<TClass, T> methodToC
                 t.Deserialize(ref spanReader);
                 methodToCall((TClass)classPtr, t);
             };
+        
+        internal readonly Action<InternalEntity, T> CachedAction;
+        internal readonly ushort Id;
+        internal readonly ExecuteFlags Flags;
+        internal readonly bool Initialized;
+
+        internal RemoteCallSerializable(Action<InternalEntity, T> action, ushort rpcId, ExecuteFlags flags)
+        {
+            CachedAction = action;
+            Id = rpcId;
+            Flags = flags;
+            Initialized = true;
+        }
     }
 
     public readonly ref struct RPCRegistrator
     {
         private readonly List<RpcFieldInfo> _calls;
+        private readonly EntityFieldInfo[] _fields;
 
-        internal RPCRegistrator(List<RpcFieldInfo> remoteCallsList)
+        internal RPCRegistrator(List<RpcFieldInfo> remoteCallsList, EntityFieldInfo[] fields)
         {
             _calls = remoteCallsList;
+            _fields = fields;
         }
 
         internal static void CheckTarget(object ent, object target)
@@ -69,16 +110,19 @@ internal static void CheckTarget(object ent, object target)
             if (ent != target)
                 throw new Exception("You can call this only on this class methods");
         }
-        
-                /// <summary>
-        /// Bind notification of SyncVar changes to action (OnSync will be called after RPCs and OnConstructs)
+                
+        /// <summary>
+        /// Bind notification of SyncVar changes to action
         /// </summary>
-        /// <param name="self">Target entity for binding</param>
         /// <param name="syncVar">Variable to bind</param>
         /// <param name="onChangedAction">Action that will be called when variable changes by sync</param>
-        public void BindOnChange<T, TEntity>(TEntity self, ref SyncVar<T> syncVar, Action<T> onChangedAction) where T : unmanaged where TEntity : InternalEntity
+        /// <param name="executionOrder">order of execution</param>
+        public void BindOnChange<T, TEntity>(ref SyncVar<T> syncVar, Action<TEntity, T> onChangedAction, OnSyncExecutionOrder executionOrder = OnSyncExecutionOrder.AfterConstruct) where T : unmanaged where TEntity : InternalEntity
         {
-            BindOnChange(self, ref syncVar, onChangedAction, self.ClassData.Fields[syncVar.FieldId].OnSyncExecutionOrder);
+            ref var field = ref _fields[syncVar.FieldId];
+            field.OnSyncExecutionOrder = executionOrder;
+            var methodToCall = onChangedAction.Method.CreateDelegateHelper<Action<TEntity, T>>();
+            field.OnSync = RemoteCall<T>.CreateMCD(methodToCall);
         }
         
         /// <summary>
@@ -88,19 +132,15 @@ public void BindOnChange<T, TEntity>(TEntity self, ref SyncVar<T> syncVar, Actio
         /// <param name="syncVar">Variable to bind</param>
         /// <param name="onChangedAction">Action that will be called when variable changes by sync</param>
         /// <param name="executionOrder">order of execution</param>
-        public unsafe void BindOnChange<T, TEntity>(TEntity self, ref SyncVar<T> syncVar, Action<T> onChangedAction, OnSyncExecutionOrder executionOrder) where T : unmanaged where TEntity : InternalEntity
+        public void BindOnChange<T, TEntity>(TEntity self, ref SyncVar<T> syncVar, Action<T> onChangedAction, OnSyncExecutionOrder executionOrder = OnSyncExecutionOrder.AfterConstruct) where T : unmanaged where TEntity : InternalEntity
         {
             //if (self.EntityManager.IsServer)
             //    return;
             CheckTarget(self, onChangedAction.Target);
-            ref var field = ref self.ClassData.Fields[syncVar.FieldId];
+            ref var field = ref _fields[syncVar.FieldId];
             field.OnSyncExecutionOrder = executionOrder;
             var methodToCall = onChangedAction.Method.CreateDelegateHelper<Action<TEntity, T>>();
-            field.OnSync = (classPtr, buffer) =>
-            {
-                fixed (byte* data = buffer)
-                    methodToCall((TEntity)classPtr, *(T*)data);
-            };
+            field.OnSync = RemoteCall<T>.CreateMCD(methodToCall);
         }
         
         /// <summary>
@@ -165,22 +205,9 @@ public void CreateRPCAction<TEntity, T>(TEntity self, Action<T> methodToCall, re
         /// <param name="flags">RPC execution flags</param>
         public void CreateRPCAction<TEntity>(Action<TEntity> methodToCall, ref RemoteCall remoteCallHandle, ExecuteFlags flags) where TEntity : InternalEntity
         {
-            ushort rpcId = (ushort)_calls.Count;
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCall(e => methodToCall((TEntity)e), (ushort)_calls.Count, flags);
             _calls.Add(new RpcFieldInfo(RemoteCall.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCall(e =>
-            {
-                var te = (TEntity)e;
-                if (te.IsServer)
-                {
-                    if (flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
-                        methodToCall(te);
-                    te.ServerManager.AddRemoteCall(te, rpcId, flags);
-                }
-                else if (flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && te.IsLocalControlled)
-                    methodToCall(te);
-            });
         }
         
         /// <summary>
@@ -189,24 +216,11 @@ public void CreateRPCAction<TEntity>(Action<TEntity> methodToCall, ref RemoteCal
         /// <param name="methodToCall">RPC method to call</param>
         /// <param name="remoteCallHandle">output handle that should be used to call rpc</param>
         /// <param name="flags">RPC execution flags</param>
-        public unsafe void CreateRPCAction<TEntity, T>(Action<TEntity, T> methodToCall, ref RemoteCall<T> remoteCallHandle, ExecuteFlags flags) where T : unmanaged where TEntity : InternalEntity
+        public void CreateRPCAction<TEntity, T>(Action<TEntity, T> methodToCall, ref RemoteCall<T> remoteCallHandle, ExecuteFlags flags) where T : unmanaged where TEntity : InternalEntity
         {
-            ushort rpcId = (ushort)_calls.Count;
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCall<T>((e, v) => methodToCall((TEntity)e, v), (ushort)_calls.Count, flags);
             _calls.Add(new RpcFieldInfo(RemoteCall<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCall<T>((e,v) =>
-            {
-                var te = (TEntity)e;
-                if (te.IsServer)
-                {
-                    if (flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
-                        methodToCall(te, v);
-                    te.ServerManager.AddRemoteCall(te, new ReadOnlySpan<T>(&v, 1), rpcId, flags);
-                }
-                else if (flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && te.IsLocalControlled)
-                    methodToCall(te, v);
-            });
         }
 
         /// <summary>
@@ -217,22 +231,9 @@ public unsafe void CreateRPCAction<TEntity, T>(Action<TEntity, T> methodToCall,
         /// <param name="flags">RPC execution flags</param>
         public void CreateRPCAction<TEntity, T>(SpanAction<TEntity, T> methodToCall, ref RemoteCallSpan<T> remoteCallHandle, ExecuteFlags flags) where T : unmanaged where TEntity : InternalEntity
         {
-            ushort rpcId = (ushort)_calls.Count;
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCallSpan<T>((e,v) => methodToCall((TEntity)e, v), (ushort)_calls.Count, flags);
             _calls.Add(new RpcFieldInfo(RemoteCallSpan<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCallSpan<T>((e,v) =>
-            {
-                var te = (TEntity)e;
-                if (te.IsServer)
-                {
-                    if (flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
-                        methodToCall(te, v);
-                    te.ServerManager.AddRemoteCall(te, v, rpcId, flags);
-                }
-                else if (flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && te.IsLocalControlled)
-                    methodToCall(te, v);
-            });
         }
         
         /// <summary>
@@ -241,28 +242,14 @@ public void CreateRPCAction<TEntity, T>(SpanAction<TEntity, T> methodToCall, ref
         /// <param name="methodToCall">RPC method to call</param>
         /// <param name="remoteCallHandle">output handle that should be used to call rpc</param>
         /// <param name="flags">RPC execution flags</param>
-        public unsafe void CreateRPCAction<TEntity, T>(Action<TEntity, T> methodToCall, ref RemoteCallSerializable<T> remoteCallHandle, ExecuteFlags flags) 
+        public void CreateRPCAction<TEntity, T>(Action<TEntity, T> methodToCall, ref RemoteCallSerializable<T> remoteCallHandle, ExecuteFlags flags) 
             where T : struct, ISpanSerializable
             where TEntity : InternalEntity
         {
             ushort rpcId = (ushort)_calls.Count;
             _calls.Add(new RpcFieldInfo(RemoteCallSerializable<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCallSerializable<T>((e,v) =>
-            {
-                var te = (TEntity)e;
-                if (te.IsServer)
-                {
-                    if (flags.HasFlagFast(ExecuteFlags.ExecuteOnServer))
-                        methodToCall(te, v);
-                    var writer = new SpanWriter(stackalloc byte[v.MaxSize]);
-                    v.Serialize(ref writer);
-                    te.ServerManager.AddRemoteCall<byte>(te, writer.RawData.Slice(0, writer.Position), rpcId, flags);
-                }
-                else if (flags.HasFlagFast(ExecuteFlags.ExecuteOnPrediction) && te.IsLocalControlled)
-                    methodToCall(te, v);
-            });
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCallSerializable<T>((e,v) => methodToCall((TEntity)e, v), rpcId, flags);
         }
     }
 
@@ -307,60 +294,32 @@ public void CreateClientAction<TSyncField>(Action<TSyncField> methodToCall, ref
         {
             ushort rpcId = _internalRpcCounter++;
             _calls.Add(new RpcFieldInfo(_syncableOffset, RemoteCall.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCall(s =>
-            {
-                var sf = (SyncableField)s;
-                if(sf.IsServer)
-                    sf.ParentEntityInternal?.ServerManager.AddRemoteCall(sf.ParentEntityInternal, (ushort)(rpcId + sf.RPCOffset), sf.Flags);
-            });
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCall(null, rpcId, 0);
         }
 
-        public unsafe void CreateClientAction<TSyncField, T>(Action<TSyncField, T> methodToCall, ref RemoteCall<T> remoteCallHandle) where T : unmanaged where TSyncField : SyncableField
+        public void CreateClientAction<TSyncField, T>(Action<TSyncField, T> methodToCall, ref RemoteCall<T> remoteCallHandle) where T : unmanaged where TSyncField : SyncableField
         {
             ushort rpcId = _internalRpcCounter++;
             _calls.Add(new RpcFieldInfo(_syncableOffset, RemoteCall<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCall<T>((s, value) =>
-            {
-                var sf = (SyncableField)s;
-                if(sf.IsServer)
-                    sf.ParentEntityInternal?.ServerManager.AddRemoteCall(sf.ParentEntityInternal, new ReadOnlySpan<T>(&value, 1), (ushort)(rpcId + sf.RPCOffset), sf.Flags);
-            });
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCall<T>(null, rpcId, 0);
         }
         
         public void CreateClientAction<TSyncField, T>(SpanAction<TSyncField, T> methodToCall, ref RemoteCallSpan<T> remoteCallHandle) where T : unmanaged where TSyncField : SyncableField
         {
             ushort rpcId = _internalRpcCounter++;
             _calls.Add(new RpcFieldInfo(_syncableOffset, RemoteCallSpan<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCallSpan<T>((s, value) =>
-            {
-                var sf = (SyncableField)s;
-                if(sf.IsServer)
-                    sf.ParentEntityInternal?.ServerManager.AddRemoteCall(sf.ParentEntityInternal, value, (ushort)(rpcId + sf.RPCOffset), sf.Flags);
-            });
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCallSpan<T>(null, rpcId, 0);
         }
         
-        public unsafe void CreateClientAction<TSyncField, T>(Action<TSyncField, T> methodToCall, ref RemoteCallSerializable<T> remoteCallHandle) where T : struct, ISpanSerializable where TSyncField : SyncableField
+        public void CreateClientAction<TSyncField, T>(Action<TSyncField, T> methodToCall, ref RemoteCallSerializable<T> remoteCallHandle) where T : struct, ISpanSerializable where TSyncField : SyncableField
         {
             ushort rpcId = _internalRpcCounter++;
             _calls.Add(new RpcFieldInfo(_syncableOffset, RemoteCallSerializable<T>.CreateMCD(methodToCall)));
-            if (remoteCallHandle.CachedAction != null)
-                return;
-            remoteCallHandle = new RemoteCallSerializable<T>((s, value) =>
-            {
-                var sf = (SyncableField)s;
-                if (sf.IsServer)
-                {
-                    var writer = new SpanWriter(stackalloc byte[value.MaxSize]);
-                    value.Serialize(ref writer);
-                    sf.ParentEntityInternal?.ServerManager.AddRemoteCall<byte>(sf.ParentEntityInternal, writer.RawData.Slice(0, writer.Position), (ushort)(rpcId + sf.RPCOffset), sf.Flags);
-                }
-            });
+            if (!remoteCallHandle.Initialized)
+                remoteCallHandle = new RemoteCallSerializable<T>(null, rpcId, 0);
         }
     }
 }
\ No newline at end of file
diff --git a/LiteEntitySystem/ServerEntityManager.cs b/LiteEntitySystem/ServerEntityManager.cs
index 85ab36e..fc83360 100644
--- a/LiteEntitySystem/ServerEntityManager.cs
+++ b/LiteEntitySystem/ServerEntityManager.cs
@@ -614,7 +614,7 @@ protected override unsafe void OnLogicTick()
                             }
                             header->PacketType = InternalPackets.DiffSync;
                             //Logger.LogWarning($"P:{pidx} Sending diff part {*partCount}: {_tick}");
-                            player.Peer.SendUnreliable(new ReadOnlySpan<byte>(_packetBuffer, 0, maxPartSize));
+                            player.Peer.SendUnreliable(new ReadOnlySpan<byte>(packetBuffer, maxPartSize));
                             header->Part++;
 
                             //repeat in next packet
diff --git a/LiteEntitySystem/SyncableField.cs b/LiteEntitySystem/SyncableField.cs
index 99c596f..b1923f3 100644
--- a/LiteEntitySystem/SyncableField.cs
+++ b/LiteEntitySystem/SyncableField.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Runtime.CompilerServices;
 using LiteEntitySystem.Internal;
 
 namespace LiteEntitySystem
@@ -42,5 +44,36 @@ protected internal virtual void RegisterRPC(ref SyncableRPCRegistrator r)
         {
 
         }
+        
+        protected void ExecuteRPC(in RemoteCall rpc)
+        {
+            if(IsServer)
+                ParentEntityInternal?.ServerManager.AddRemoteCall(ParentEntityInternal, (ushort)(rpc.Id + RPCOffset), rpc.Flags);
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCall<T> rpc, T value) where T : unmanaged
+        {
+            unsafe
+            {
+                if(IsServer)
+                    ParentEntityInternal?.ServerManager.AddRemoteCall(ParentEntityInternal, new ReadOnlySpan<T>(&value, 1), (ushort)(rpc.Id + RPCOffset), Flags);
+            }
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCallSpan<T> rpc, ReadOnlySpan<T> value) where T : unmanaged
+        {
+            if(IsServer)
+                ParentEntityInternal?.ServerManager.AddRemoteCall(ParentEntityInternal, value, (ushort)(rpc.Id + RPCOffset), Flags);
+        }
+
+        protected void ExecuteRPC<T>(in RemoteCallSerializable<T> rpc, T value) where T : struct, ISpanSerializable
+        {
+            if (IsServer)
+            {
+                var writer = new SpanWriter(stackalloc byte[value.MaxSize]);
+                value.Serialize(ref writer);
+                ParentEntityInternal?.ServerManager.AddRemoteCall<byte>(ParentEntityInternal, writer.RawData.Slice(0, writer.Position), (ushort)(rpc.Id + RPCOffset), Flags);
+            }
+        }
     }
 }
\ No newline at end of file