Abnormal latency with BodyMovers

I’ve been messing around with BodyMovers and made a character movement… thing.
But i noticed some delay and thought “it must be some latency issue”.

My code works like this:
Client [movement info] → Server [sanity check, actuation] → Client [base roblox replication]

So i made the server fire back and measured the latency with os.clock()
Output was in the 17-36ms range on the actual client. As expected. But then i tested it with the built-in server-client test environment. (Latency should be basically 0, and it was)

I recorded both windows and the delay between server and client was 300ms!

Setting NetworkOwner of the Part to the client makes it respond immediately on the client but then has a 300ms delay on the server, compared to the client.

So if it’s not ping, and NetworkOwner just moves the problem, then what?

Demo.rbxl (30.9 KB)

Small demo, only works with W, ignore my botched code.

You might want to keep it solely on the client or server for the best results instead of exchanging information/data between the client and server multiple times back and forth.

Movement data is client-to-server only.
The third step going back to the client is handled by the roblox client. I didn’t write custom code for replication, because it would be useless.

Temporary solution:
Send part information back manually
Example:

RunService = game:GetService("RunService")
Move = false
part = script.Parent

function Update()
	if Move then
		part.BodyVelocity.Velocity = Vector3.new(0,0,-10)
	else
		part.BodyVelocity.Velocity = Vector3.new(0,0,0)
	end
	return {part.Position, part.Orientation, part.AssemblyLinearVelocity, part.AssemblyAngularVelocity}
end

RunService.Stepped:Connect(Update)
part.RemoteEvent.OnServerEvent:Connect(function(plr, Value)
	Move = Value
	part.RemoteEvent:FireClient(plr, Update())
end)
RunService = game:GetService("RunService")
UserInputService = game:GetService("UserInputService")
part = workspace.Part

RunService.RenderStepped:Connect(function()
	part.RemoteEvent:FireServer(UserInputService:IsKeyDown(Enum.KeyCode.W))
	local RepliTable = workspace.Part.RemoteEvent.OnClientEvent:Wait()
	part.Position = RepliTable[1]
	part.Orientation = RepliTable[2]
	part.AssemblyLinearVelocity = RepliTable[3]
	part.AssemblyAngularVelocity = RepliTable[4]
end)

Demo.rbxl (31.0 KB)