Unique vehicle is jittering when moving (PLEASE HELP)

Hello. I am working on a game heavily reliant on Roblox’s physics, and I have a vehicle that will move kind of like a motorcycle, but also be able to teeter left and right as it gets impacted. I decided to use a massless part that is stuck in the plane of the floor as my “carrier” (yellow), and the rest of the vehicle+mass has a hinge constraint to the carrier with a root (green):

Because of this, there are no forces of friction, and I have to make custom correctional forces for drag and friction. I am using forces as the body movers, but the issue is whether I apply the force to the root or carrier (I tested both), I get a jitter when moving:

Is this because of the hinge constraint conflicting as it is being dragged? How would I fix this? Is there a smarter approach to this that keeps smooth gameplay but also has realistic, tuneable, and fun collisions?
Here are the relevant scripts incase they help:

local function zeroHorizontalSpeed(part)
	part.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
end

local function updateHorse(player, state)
	local horse = getHorse(player)
	local root = getRequired(horse, HorseConfig.RootPartName, "BasePart")
	local carrier = getRequired(horse, HorseConfig.CarrierPartName, "BasePart")
	local driveForce = getRequired(root, "HorseDriveForce", "VectorForce")
	local dragForce = getRequired(root, "HorseDragForce", "VectorForce")

	local drive = HorseConfig.Drive

	local localVelocity = -root.CFrame:VectorToObjectSpace(root.AssemblyLinearVelocity)
	local speed = math.abs(localVelocity.Z)
	local direction = 0

	if localVelocity.Z > 0 then
		direction = 1
	elseif localVelocity.Z < 0 then
		direction = -1
	end

	local forwardDragScalar = drive.ForwardAccelerationForce / (drive.MaxForwardSpeed * drive.MaxForwardSpeed)
	local reverseDragScalar = drive.ReverseAccelerationForce / (drive.MaxReverseSpeed * drive.MaxReverseSpeed)

	driveForce.Force = Vector3.zero
	dragForce.Force = Vector3.zero
	print(speed)
	if state.ForwardInput > 0 then
		driveForce.Force = Vector3.new(drive.ForwardAccelerationForce, 0, 0)

		if direction == 1 and speed > 0 then
			dragForce.Force = Vector3.new(-(forwardDragScalar * speed * speed), 0, 0)
		end

	elseif state.ForwardInput < 0 then
		driveForce.Force = Vector3.new(-drive.ReverseAccelerationForce, 0, 0)

		if direction == -1 and speed > 0 then
			dragForce.Force = Vector3.new(reverseDragScalar * speed * speed, 0, 0)
		end

	else
		if speed > drive.StopSnapSpeed then
			warn("Slowing")
			state.Stopped = false
			if direction == 1 then
				dragForce.Force = Vector3.new(-drive.CoastDamping, 0, 0)
			elseif direction == -1 then
				dragForce.Force = Vector3.new(drive.CoastDamping, 0, 0)
			end
		elseif not state.Stopped then
			warn("Stopped")
			state.Stopped = true
			zeroHorizontalSpeed(carrier)
			zeroHorizontalSpeed(root)
			driveForce.Force = Vector3.zero
			dragForce.Force = Vector3.zero
			zeroHorizontalSpeed(carrier)
			zeroHorizontalSpeed(root)
		end
	end
end
--Settings module script in RS
HorseConfig.Drive = {
	ForwardAccelerationForce = 8000,
	ReverseAccelerationForce = 4000,

	MaxForwardSpeed = 80,
	MaxReverseSpeed = 40,

	CoastDamping = 3000,
	StopSnapSpeed = 5,
}

Thanks!

2 Likes

It could be because the force is being applied on the server. Maybe move the code to the client and tell give it a try.

Would this still replicate properly? Also, isn’t this a security risk?

You can make the client handle the physics by using :SetNetworkOwner() and it should work fine without needing to be worried about security.

Right now physics are being handled by the player-- network owner is set to player for both components.

Keep in mind that the movement can appear laggy because the client is ONLY responsible for physics and not latency connected to input and can make controlling the hourse less responsive.

1 Like

Hey! The jitter is coming from this part:

You’re repeatedly forcing velocity to 0 using AssemblyLinearVelocity while also using forces

This fights the physics solver and causes jitter/desync.

What to fix

Remove hard velocity snapping

local function zeroHorizontalSpeed(part)
	part.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
end

This is the main problem don’t force velocity to 0 every frame.

Better approach

Let forces slow the vehicle naturally instead of snapping

Replace this section:

elseif not state.Stopped then
	state.Stopped = true
	zeroHorizontalSpeed(carrier)
	zeroHorizontalSpeed(root)

With:

elseif not state.Stopped then
	state.Stopped = true
	driveForce.Force = Vector3.zero
	dragForce.Force = Vector3.zero
end

Extra thing to check

Make sure network ownership is correct

root:SetNetworkOwner(player)

If the server owns it, you’ll also get jitter.

Docs:

https://create.roblox.com/docs/physics/mover-constraints
https://create.roblox.com/docs/reference/engine/classes/BasePart#AssemblyLinearVelocity

1 Like

Hi, thank you so much for your comment, but I decided to move away from rigid attachments and opted for a vehicular approach because attachments were very annoying. Thanks again!

1 Like