Super high recoil on low FPS

For my recoil, I use a camera module used for a gun kit. As good as it is, the problem is that when players have low frame rate they have super high recoil making it unplayable. I have tried to use deltaTime to get around this but it still occurs.

This is the module used CameraModule.rbxm (2.2 KB)

How can I get around this?

3 Likes

Would you mind posting the relevant code? I cant download rn

CameraModule
local physics = require(script.PhysicsModule)

local cam = {}
cam.__index = cam


local cams = {}

local lTick = tick()

local function updatecam(v,dt)			
	local x,y,z = v.recoil.x.p(),v.recoil.y.p(),v.recoil.z.p()

	local n = dt * 100
	x,y,z = x*n,y*n,z*n

	v.current.CoordinateFrame = v.current.CoordinateFrame*CFrame.Angles(x,y,z)
end

function cam.new(setting)
	local nCam = {}
	nCam.current = workspace.CurrentCamera
	nCam.angles = {}
	nCam.angles.x = 0
	nCam.angles.y = 0
	nCam.angles.z = 0
	nCam.recoil = {}
	nCam.recoil.x = physics.spring.new{d=setting.RecoilDamper;s=setting.RecoilSpeed;}
	nCam.recoil.y = physics.spring.new{d=setting.RecoilDamper;s=setting.RecoilSpeed;}
	nCam.recoil.z = physics.spring.new{d=setting.RecoilDamper;s=setting.RecoilSpeed;}

	table.insert(cams,nCam)
	return setmetatable(nCam,cam)
end

function cam:accelerate(x,y,z)
	self.recoil.x.impulse(x)
	self.recoil.y.impulse(y)
	self.recoil.z.impulse(z)
end

function cam:accelerateXY(x,y)
	self.recoil.x.impulse(x)
	self.recoil.y.impulse(y)
end

function cam:disconnect()
	for i,v in pairs(cams) do
		if v == self then
			table.remove(cams,i)
			self = nil
			break
		end
	end
end

game:GetService("RunService"):BindToRenderStep("RecoilCam",2000,function(dt)
	local cDT = tick() - lTick

	for _,v in pairs(cams) do
		updatecam(v,cDT)
	end

	lTick = tick()
end)

return cam
PhysicsModule

local physics = {}

local tick = tick
local setmt	= setmetatable
local sin = math.sin
local cos = math.cos
local atan2	= math.atan2
local tan = math.tan
local e = 2.718281828459045
local os = os

physics.spring = {}

function physics.spring.new(data)
	local c0,c1
	local t0
	local d,s
	local target
	local cd
	if data then
		c0,c1=0,0
		t0=os.clock()
		d,s=data.d,data.s
		target=0
		cd=0
	else
		c0,c1=0,0
		t0=os.clock()
		d,s=1,1
		target=0
		cd=0
	end
	
	local function position()
		local t=os.clock()
		local sx=s*(t-t0)
		if d==1 then
			return (c0+c1*sx)/e^sx+target
		else
			return (c0*cos(cd*sx)+c1*sin(cd*sx))/e^(d*sx)+target
		end
	end
	
	local function velocity()
		local t=os.clock()
		local sx=s*(t-t0)
		if d==1 then
			return (c1*(s-sx)-c0)/e^sx
		else
			return s*((cd*c1-c0*d)*cos(cd*sx)-(cd*c0+c1*d)*sin(cd*sx))/e^(d*sx)
		end
	end
	
	return {
		target=function(newtarget,newd,news)
			news=news or s
			local p0,v0=position(),velocity()/news
			d=newd or d
			t0=os.clock()
			target=newtarget
			c0=p0-target
			if d==1 then
				c1=v0+c0
			else
				cd=(1-d*d)^0.5
				c1=(v0+c0*d)/cd
			end
			s=news
		end;
		
		impulse=function(v)
			local p0,v0=position(),(velocity()+v)/s
			t0=os.clock()
			c0=p0-target
			if d==1 then
				c1=v0+c0
			else
				cd=(1-d*d)^0.5
				c1=(v0+c0*d)/cd
			end
		end;	
		p=position;
		v=velocity;
	}
end

function physics.trajectory(sx,sy,sz,v,px,py,pz)
	local g=9.81*40
	local dx,dy,dz=px-sx,py-sy,pz-sz
	local d=(dx*dx+dz*dz)^0.5
	local th=atan2(v*v-(v*v*v*v-g*(g*d*d+2*dy*v*v))^0.5,g*d)
	return px,sy+d*tan(th),pz
end

return physics

2 Likes

Have you tried using the dt argument returned from renderstepped instead of cdt? Dt would likely be more reliable for your line that makes it proportional across fps’.

I found that it didn’t really make a difference. In the past before i had updated it it was the other way around, where ifyou had high fps (fps unlocker) you would have insane recoil.

I found nothing wrong with your direct FPS normalizer thingy, so its not that
Other potential causes would be not using the correct rate for the time given, the spring thing bugging out at higher recoil values to make up for the lack of rate, or just a placebo effect from the recoil being in higher “chunks” at lower framerates.

It might be helpful to specify the framerates at which this becomes an issue, or a video of the issue, however I cant guarantee Id be able to make any sense of it.

people who get less than 60, mostly <30. I really dont understand the math for the physics module so I have no idea how to deal with it.

1 Like

Maybe try bypassing the physics module and seeing what happens. In my testing I bypassed the physics module cause I have no idea how it works either, but you might want to test it in the full context of your game.

I think I have it: to get a proper ratio, try setting n to this:

local n = (1 / dt) * 60

By doing that, players with 60 fps will get 1x the recoil, players with 120 fps will get double the recoil, and players with 30 fps will get half the recoil. It is kind of strange however that the lower FPS client is seeing higher recoil, it would make more sense by being the other way around.

3 Likes