Character moving faster based on low FPS

Hello! I’m currently working on a snake movement system and came upon a weird problem with DeltaTime / FPS. If I don’t use DT (DeltaTime) the lower my FPS the slowest I move, but if I use DT the lower my FPS the fastest I move.

Weird right? All I want is to be able to move within the same speed no matter how high or how low my FPS is. Take a look at the following examples:

[Code] Before DeltaTime:

local moveSpeed = 24
local rotationDelay = 0.1
local EE_linear = Enum.EasingStyle.Linear

local timer = 0
local interval = 1/60

--[[CODE]]--
--[[MOVEMENT SYSTEM]]--
local function UpdateMovement(dt)
	-- Target pos and then tween to it
	local targetPosition = Vector3.new(mouse.Hit.X,char.PrimaryPart.Position.Y,mouse.Hit.Z)
	local rotateTween = tweenService:Create(char.PrimaryPart, TweenInfo.new(rotationDelay, EE_linear),
		{CFrame = CFrame.lookAt(char.PrimaryPart.Position, targetPosition)}):Play()

	-- PROBLEM IS PROB HERE, IT CONSTANTLY MOVES THE PLAYER TO LookVector
	--(The front path the char is facing) times the moveSpeed
	linear.VectorVelocity = char.PrimaryPart.CFrame.LookVector * moveSpeed 
end

[Video] Before DeltaTime:
robloxapp-20231211-1931394.wmv (3.4 MB)
"Btw roblox doesn’t record the FPS Statistics but It always gets to 30 less FPS when I turn max settings on "

You can notice there’s slight diference in the speed whenever my FPS goes low (U can’t notice by the video but its twice slower). Take a look at it after I multiply by DeltaTime.

[Code] After DeltaTime:

local moveSpeed = 1008 -- (48) * 24 So it's the same speed as before 
local rotationDelay = 0.1
local EE_linear = Enum.EasingStyle.Linear

local timer = 0
local interval = 1/60

--[[CODE]]--
--[[MOVEMENT SYSTEM]]--
local function UpdateMovement(dt)
	-- Target pos and then tween to it
	local targetPosition = Vector3.new(mouse.Hit.X,char.PrimaryPart.Position.Y,mouse.Hit.Z)
	local rotateTween = tweenService:Create(char.PrimaryPart, TweenInfo.new(rotationDelay, EE_linear),
		{CFrame = CFrame.lookAt(char.PrimaryPart.Position, targetPosition)}):Play()

	-- PROBLEM IS PROB HERE, IT CONSTANTLY MOVES THE PLAYER TO LookVector
	--(The front path the char is facing) times the moveSpeed
	linear.VectorVelocity = char.PrimaryPart.CFrame.LookVector * moveSpeed * dt -- ADDED DeltaTime
end

[Video] After DeltaTime:
“Again, It doesn’t show the FPS but the speed difference is extremely noticeable. Btw sorry about the video quality”
robloxapp-20231211-1851539.wmv (3.4 MB)

“If it is of any help here’s the script that moves the body and how the char is made”
Char:
imagem_2023-12-11_214520684

Body Code:

local Heartbeat = function(dt)
	timer += dt
	if timer >= interval  then
		for character, data in pairs(charData) do
			if (character.PrimaryPart.Position - data.position).Magnitude < .5 then return end

			local part = table.remove(data.parts, 1)
			if part ~= nil then
				table.insert(data.parts, part) 
				part.Position = data.position
				data.position = char.PrimaryPart.Position
			end			
		end
		timer = 0
	end
end

What I tried to do that didn’t work:
I tried making my own (dt) by using tick():

local lastUpdateTime = tick()

runService.RenderStepped:Connect(function()
    local currentTime = tick()
    local dt = currentTime - lastUpdateTime
    lastUpdateTime = currentTime

    UpdateMovement(dt)
end)

I tried to divide dt by magic numbers (LOL I had to try):

linear.VectorVelocity = char.PrimaryPart.CFrame.LookVector * moveSpeed * (dt / 2) -- or * / 3,4,5

I searched throught the forum but coudn’t find anything directly related to this in specific. Do you guys have any idea on why this is happening and how I could fix it?

1 Like

Could you make variable called like Distance or something and add dt*moveSpeed onto it and print it out every frame? Using your custom dt system, you should be impossible for that value to change over different times. I know this doesn’t help that much, but I would like to limit the problem a little more.

If u mean printing moveSpeed * dt here it is:


“Btw my dt and the engine dt is the same I tested”
“dt increases as my fps gets lower”
“moveSpeed is 1008 (same as 24 with no dt)”

There should not be a need to multiply by dt if you are using VectorVelocity the physics engine will solve it by itself.

Normally you only multiply by dt if you are using a CFrame method with a numerical integration method without the roblox physics engine.

Fancy words aside this just means manually simulating physics.

position = position + velocity * dt

Tysm for the reply. I’m gonna read your link as soon as I can. So if dt doesn’t works for this case where I ain’t using positions / CFrames but velocity, how can I make so it doesn’t get slower as my FPS drops?

“Cuz the main reason I tried to use dt was to make the movement stop from getting slower as my FPS decreased. Which turned out to make the opposite”

Tbh the code should be good as is. As long as VectorVelocity magnitude is the same (same speed) it wont get any slower, however it will become choppier and start teleporting larger distances between each frame.

Also I recommend this plugin to better test fps (kind of a hack since it forces studio to lag but works)

Thx for your replies. Even do the speed never changes it somehow really gets slower, which makes no sense since its speed is the same no matter the FPS. Based on your replies I had an idea of making some tests with an FPS measure and multiply the speed based on the FPS changes, even do it may consume some good ammount of data. If it works or not I will come back to this post and update it with new informations.

“Btw thanks for the Integration Basics by Glenn Fiedler”

“Just an update in case someone is facing the same problem”

After reading the post I realized that dt woudn’t solve my problem, so I had an idea of getting the player’s FPS and create a multiplier based on that. For an example if the FPS is 30 than the multiplier is 1.215, but if it’s 60 then it’s 1.

linear.VectorVelocity = char.PrimaryPart.CFrame.LookVector * moveSpeed * multiplier

Even do it’s not 100% precise it works fine. Btw here’s the post on how to get the player’s FPS:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.