local defaultRot = CFrame.Angles(0, 0, math.rad(90))
local uprightJointSpringStrength = 50
local uprightJointSpringDamper = 10
local function UpdateUprightForce()
local characterCurrent = RootPart.CFrame
local toGoal = defaultRot:ToObjectSpace(characterCurrent)
local rotAxis, rotRadians = toGoal:ToAxisAngle()
local rotDegrees = math.deg(rotRadians)
rotAxis = Vector3.new(rotAxis.X, rotAxis.Y, rotAxis.Z).Unit
local torque = (rotAxis * (rotRadians * uprightJointSpringStrength)) - (RootPart.AssemblyAngularVelocity * uprightJointSpringDamper)
RootPart:ApplyAngularImpulse(torque)
end

in Roblox there’s something called an AlignOrientation, use that instead

If you don’t want to use it, try

local defaultRot = CFrame.Angles(0, 0, math.rad(90))
local uprightJointSpringStrength = 50
local uprightJointSpringDamper = 10
local function UpdateUprightForce()
local characterCurrent = RootPart.CFrame
local toGoal = defaultRot:inverse() * characterCurrent -- Equivalent to UtilsMath.ShortestRotation(_uprightJointTargetRot, characterCurrent)
local rotAxis, rotRadians = toGoal:toAxisAngle()
local rotDegrees = math.deg(rotRadians)
rotAxis = Vector3.new(rotAxis.x, rotAxis.y, rotAxis.z).unit -- Adjusting for differences in vector notation
local torque = rotAxis * (rotDegrees * uprightJointSpringStrength) - RootPart.AssemblyAngularVelocity * uprightJointSpringDamper
RootPart:ApplyTorque(torque)
end

This is very wrong. Constraints are very optimized, programming physics will definitely be more taxxing and less optimized, especially if you don’t know what you’re doing. Use the constraints.