internal void ApplyPrediction(FrameSyncInput input, InputFrame i1, InputFrame i2)
        {
            //copy i1 to i2
            SWBytes.CopyFull(i1.bytes, i2.bytes);

            //let input reset
            //important to reset triggers
            input.InputJustCopied(i2.bytes);

            byte inputSize = input.Size;

            if (bytes.DataLength > 0)
            {
                byte playerCount = bytes.PopByte();

                for (int i = 0; i < playerCount; i++)
                {
                    byte            playerID = bytes.PopByte();
                    FrameSyncPlayer player   = input.GetPlayer(playerID);
                    byte            offset   = player.InputOffset;
                    SWBytes.Copy(bytes, i2.bytes, bytes.ReadIndex, offset, inputSize);
                    bytes.SkipRead(inputSize);
                }
            }

            //reset read index
            bytes.SetReadIndex(0);

            //prepare bitarray
            input.InputDeltaJustApplied(i2.bytes);
        }
        internal void Apply(FrameSyncInput input, InputFrame i1, InputFrame i2)
        {
            //copy i1 to i2
            SWBytes.CopyFull(i1.bytes, i2.bytes);

            //let input reset
            //important to reset triggers
            input.InputJustCopied(i2.bytes);

            //apply delta for each player
            byte inputSize = input.Size;

            SWConsole.Crit($"ApplyDelta delta frameNumber={frameNumber} {bytes.FullString()}");

            while (bytes.DataLength > 0)
            {
                byte            playerID = bytes.PopByte();
                FrameSyncPlayer player   = input.GetPlayer(playerID);
                if (player == null)
                {
                    SWConsole.Error($"InputFrameDelta Apply: player not found {playerID}");
                }
                byte offset = player.InputOffset;
                SWBytes.Copy(bytes, i2.bytes, bytes.ReadIndex, offset, inputSize);
                bytes.SkipRead(inputSize);
            }

            //reset read index
            bytes.SetReadIndex(0);

            //prepare bitarray
            input.InputDeltaJustApplied(i2.bytes);
        }
 internal void Copy(InputFrame other)
 {
     other.FrameNumber = FrameNumber;
     SWBytes.CopyFull(bytes, other.bytes);
 }