Client Tween Lag

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to achieve a smooth ride on my flying vehicle.

  2. What is the issue? Include screenshots / videos if possible!
    I have a vehicle that moves in air by tweening. When a one player drives this vehicle, for others this vehicle moves really laggy.
    When the player just got into the vehicle, he drives normally for 1-2 seconds, and then the vehicle starts to extreme lagging for others.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I looked through a bunch of topics, but I don’t think I found my case.

local movement = {forward = 0, backward = 0, right = 0, left = 0}
local function movementBind(actionName, inputState, inputObject)
	if inputState == Enum.UserInputState.Begin then
		movement[actionName] = 1
	elseif inputState == Enum.UserInputState.End then
		movement[actionName] = 0
	end
	return Enum.ContextActionResult.Pass
end
game:GetService("ContextActionService"):BindAction("forward", movementBind, false, Enum.PlayerActions.CharacterForward)
game:GetService("ContextActionService"):BindAction("backward", movementBind, false, Enum.PlayerActions.CharacterBackward)
game:GetService("ContextActionService"):BindAction("left", movementBind, false, Enum.PlayerActions.CharacterLeft)
game:GetService("ContextActionService"):BindAction("right", movementBind, false, Enum.PlayerActions.CharacterRight)

OnMoveDirectionChanged = game:GetService("RunService").RenderStepped:Connect(function()
	local CameraCFrame = workspace.CurrentCamera.CFrame
	local direction = CameraCFrame.RightVector*(movement.right-movement.left)+CameraCFrame.LookVector*(movement.forward-movement.backward);
	if (direction:Dot(direction)>0) then
		direction = direction.unit;
	end

	Tween(script.Parent.Parent.BodyVelocity,1.5,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,{Velocity = direction*50})
end)

.
The script above is LocalScript and is located inside the vehicle’s part, which is affected by BodyVelocity.

The LocalScript itself is executed using the server script ( which is located inside VehicleSeat ) by using InvokeClient on RemoteFunction:

-- server script
script.Parent:GetPropertyChangedSignal("Occupant"):Connect(function()
	if script.Parent.Occupant and script.Parent.Occupant.Parent then
		local plr = game:GetService("Players"):GetPlayerFromCharacter(script.Parent.Occupant.Parent)
		if plr then
			script.Parent.RemoteFunction:InvokeClient(plr)
			-- LocalScript which tweens vehicle starts working
		end 
	end
end)

.
This is my second post about the same problem because I didn’t get an answer on my first post.

1 Like

I see that you are updating BodyVelocity every frame, which affects network usage and can be the cause of “lag” or jitter that you are noticing.

There isn’t any built-in direct solutions for handling fast-moving physics objects reliably over a network in Roblox. So, you will need to implement a custom interpolation, extrapolation, or reconciliation system.

If you want to have as smooth an experience as possible for all players, I would recommend running the movement logic on the server:

  1. When a player starts driving the vehicle, send a remote request to the server to start moving the vehicle.
  2. Run the tween (or more generally, movement) logic on the server, updating the vehicle’s BodyVelocity (or any other relevant physics properties) accordingly.
  3. Continue to update the vehicle’s movement according to player input - either by having the player send updates of their input to the server, or by having the server poll the player’s input.
  4. When the player stops driving the vehicle, send a remote request to the server to stop moving the vehicle.

This can potentially eliminate the issue of the lag, as the server is what’s controlling the movement and thus all players will see the vehicle’s movement in sync.

Of course, there might be some input lag for the driver, but this depends on their connection to the server.

I highly recommended to study the link below, and redesign your code in similar vein:

Another possible quick and dirty solution is setting network ownership:

yourVehicle:SetNetworkOwner(nil)

This will “force” everyone to see the updates from the server. It may work, but it’s not the best solution. It still can cause minor lags, because physics are throttled by server (30 updates per second), but it might be enough for your project and save you from learning and implementing more advanced solutions.

Please note, that you need to handle setting the network owner back to the player when he is driving the vehicle, otherwise the vehicle would react sluggishly to user’s input.

One of the most advanced solutions would be implementing Cubic Interpolation algorithm for extrapolating vehicle’s movement on clients based on few newest server updates.

However, this topic would be way too big for single discussion here. I highly recommend to study interpolation techniques and apply one to your projects if you’re comfortable with the math involved.

1 Like

Thank you for your answer. Maybe I’ll try some of the above.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.