Help with First Person Shooter CFrame:Lerp() Recoil

Hello, I’m currently developing a realistic first person shooter on Roblox, and have come across an issue when testing it with friends.
I am using the CFrame:Lerp() method for many things in this system (using DeltaTime for each one to balance the lerp with different FPS), like arm sway, ADS etc, however the recoil lerp seems to have issues.

Lerp is used in the recoil system to quickly smoothen it both up when firing, and back to the original position, but is done a lot quicker on LOWER FPS.

The following line generates recoil while firing a weapon.

self.recoilIncrement = self.recoilIncrement:Lerp(CFrame.new(), math.clamp(dt * 25, 0, 1))

The following line smoothens the recoil to the weapon’s original position.

self.recoilOffset = (self.recoilOffset * self.recoilIncrement):Lerp(CFrame.new(), dt * 5)

I have tried looking up a few different ways online, but nothing seems to help.
Anyone know why this might be happening, and what I’m doing wrong?

self.recoilIncrement = self.recoilIncrement:Lerp(CFrame.new(), math.clamp(dt * 25, 0, 1))

The first line is called in the weapon’s fire function, which is called every time the player presses the fire key, then the second line is called in the game’s update function.

The recoilIncrement is a CFrame, which is saved globally as a CFrame to the weapon, and is added to the arm’s CFrame to make it recoil.

The dt is a DeltaTime value, which is used to make the lerp value (the last argument in each function call) balance with the FPS.
function weapon.Fire(self, dt)
–[[
The weapon’s fire function, which is called every time the player presses the fire key.
This handles projectile spawning, recoil, and other things related to firing a weapon.
]]–
local bullet = Instance.new(“Part”)
bullet.Name = “Bullet”
bullet.Size = Vector3.new(0.2, 0.2, 0.2)
bullet.Anchored = true
bullet.CanCollide = false
bullet.Locked = true
bullet.BrickColor = BrickColor.new(“Really black”)
bullet.Parent = workspace
bullet.CFrame = self.Muzzle.CFrame
bullet.Touched:Connect(function(part)
part:BreakJoints()
bullet:Destroy()
end)

local bulletVelocity = self.Muzzle.CFrame.lookVector * self.BulletSpeed
local bulletImpact = Instance.new("Part")
bulletImpact.Name = "Bullet"
bulletImpact.Size = Vector3.new(0.2, 0.2, 0.2)
bulletImpact.Anchored = true
bulletImpact.CanCollide = false
bulletImpact.Locked = true
bulletImpact.BrickColor = BrickColor.new("Really black")
bulletImpact.Parent = workspace
bulletImpact.CFrame = bullet.CFrame + bulletVelocity
bulletImpact.Touched:Connect(function(part)
    bulletImpact:Destroy()
    end)

local bulletTrail = Instance.new("Trail", bullet)
bulletTrail.Color = ColorSequence.new(Color3.new(0, 0, 0))
bulletTrail.Lifetime = 0.1
bulletTrail.LightInfluence = 0
bulletTrail.Texture = "rbxassetid://162871881"
bulletTrail.Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(0.5, 0.5), NumberSequenceKeypoint.new(1, 0)})
bulletTrail.Width = 0.15

local bulletRay = Ray.new(bullet.Position, bullet.Position + bulletVelocity)
local bulletRayHit, bulletRayPosition = workspace:FindPartOnRayWithWhitelist(bulletRay, {bullet})

if bulletRayHit and bulletRayHit.Parent ~= self.Parent then
    bulletImpact.CFrame = bulletRayPosition
    bullet.CFrame = bulletRayPosition
else
    bulletImpact.CFrame = bullet.CFrame + bulletVelocity
end

self.recoilIncrement = self.recoilIncrement + CFrame.Angles(math.rad(math.random(self.MinRecoilAngle, self.MaxRecoilAngle)), math.rad(math.random(self.MinRecoilAngle, self.MaxRecoilAngle)), 0)
self.recoilIncrement = self.recoilIncrement:Lerp(CFrame.new(), math.clamp(dt * 25, 0, 1))

end

function weapon.Update(self, dt, targetArmPart)
–[[
The weapon’s update function, which is called every frame.
This handles the weapon’s animations, like ADS and arm sway.
]]–
if self.ADS == true then
self.ADSProgress.Value = self.ADSProgress.Value + (dt * self.ADSSpeed)
else
self.ADSProgress.Value = self.ADSProgress.Value

This did not help my problem at all, and why have you included a lot of unformatted, unrelated code?

Both lines I provided are in a render step function.