# How can I create stable custom physics at lower frame rates?

I’m working on custom spring physics to simulate suspension for a car. The code is pretty straightforward, directly applying Newton’s 2nd law and Hooke’s law:

``````local RunService = game:GetService("RunService")

local Object = workspace.Body
local RestLength = 8 -- The length of the spring if no external forces were acting on it
local DesiredLength = 4

RunService.Heartbeat:Connect(function(dt)
local Weight = Object.Mass * workspace.Gravity * Vector3.new(0,1,0):Dot(Object.CFrame.UpVector)-- Effective G force
local SpringConstant = Weight/(RestLength - DesiredLength)/4 -- Solve mg - kx = 0, where x is the desired compression. Divide by 4 to distribute between wheels
local Dampening = SpringConstant * 0.3 --How much dampening force is applied proportional to the velocity of the spring

for i, force in pairs(Object:GetChildren()) do
if force:IsA("VectorForce") then
local attachment = force.Attachment0
local origin = attachment.WorldPosition
local downVector = -attachment.CFrame.UpVector

local params = RaycastParams.new() do
params.FilterDescendantsInstances = {Object}
end
local result = workspace:Raycast(origin, downVector * 10, params)

if result then
--Calculate the length of the spring along with how much it is compressed from equilibrium
local length = (result.Position - origin).Magnitude
local x = length - RestLength

-- F = -kx - bv
local f = -SpringConstant * x - Dampening * (x - force.dx.Value)/dt - 0.5 * Dampening * (x - force.d2x.Value)/dt

--Store the past length values to calculate instantaneous velocity of compression
force.d2x.Value = force.dx.Value
force.dx.Value = x

force.Force = Vector3.new(0,f,0)
else
force.Force = Vector3.new()
end
end
end
end)
``````

The script is run locally (I give network ownership of the block to the client) and
works just fine when I run it at a standard 60 fps:

However, things get ugly when I cap my frame rate to even 30 fps. The spring forces seem to overcompensate, and a lot of flinging happens:

I’ve tried removing the “/dt” in this line in an effort to make calculations more stable independent of framerate:
`local f = -SpringConstant * x - Dampening * (x - force.dx.Value)/dt - 0.5 * Dampening * (x - force.d2x.Value)/dt`
This helps, to an extent. The motion is stable at 30fps once I remove the /dt but the same flinging happens at 20 fps.

Maybe I’m being too meticulous here, but I want the suspension to work properly for lower-end devices. I’m not too familiar with what the “average” device running Roblox is like, but I’d hate to completely ruin the experience for players that get 20-30 frames per second. Is there something fundamentally wrong with my code here or is this just an inevitable result of the physics engine? Any help is appreciated

Hi, have you fixed this by any chance?

Similar problem here on my car scripts, any solutions found?

Use tick()

How it work: