Higher FPS causes unbalanced gameplay

Hey everyone, I have a script that is used for movement, bhopping and everything related to it.

local LocalPlayer = game:GetService("Players").LocalPlayer
local Character

-- Wait for the character to exist
repeat
	Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
until Character

local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local BodyVelocity = Instance.new("BodyVelocity")
BodyVelocity.Parent = HumanoidRootPart

local Humanoid = Character:WaitForChild("Humanoid")
local CurrentState = nil
local IsJumping = false
local JumpCooldown = 0
local JumpPower = 50
local MaxJumpCooldown = 10
local SpeedIncreaseRate = 0.25
local MaxSpeed = 125
local Grounded = false
local LastMoveDirection = Vector3.new(0, 0, 0)
local InitialWalkSpeed = Humanoid.WalkSpeed
local InitialSpeedIncreaseRate = SpeedIncreaseRate

local function UpdateVelocity()
	if CurrentState ~= Enum.HumanoidStateType.Freefall then
		BodyVelocity.MaxForce = Vector3.new(0, 0, 0)
		-- Only update the BodyVelocity's velocity if not jumping
		if not IsJumping then
			BodyVelocity.Velocity = HumanoidRootPart.Velocity
		end
		return
	end

	BodyVelocity.MaxForce = Vector3.new(5000, 0, 5000)
	if not IsJumping then
		BodyVelocity.Velocity = BodyVelocity.Velocity * 1
		IsJumping = true
	end

	local targetVelocity = Humanoid.MoveDirection * SpeedIncreaseRate * Humanoid.WalkSpeed / InitialWalkSpeed + HumanoidRootPart.Velocity
	BodyVelocity.Velocity = Vector3.new(math.clamp(targetVelocity.X, -MaxSpeed, MaxSpeed), targetVelocity.Y, math.clamp(targetVelocity.Z, -MaxSpeed, MaxSpeed))

	-- Check if the player suddenly stopped
	local currentMoveDirection = Humanoid.MoveDirection
	if currentMoveDirection.magnitude < 0.1 and LastMoveDirection.magnitude > 0.1 then
		-- Reset velocity if the player suddenly stopped
		BodyVelocity.Velocity = Vector3.new(0, BodyVelocity.Velocity.Y, 0)
	end
	LastMoveDirection = currentMoveDirection
end

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	UpdateVelocity()
	JumpCooldown = math.max(JumpCooldown - deltaTime, 0)
end)

Humanoid.UseJumpPower = true

game:GetService("UserInputService").JumpRequest:Connect(function()
	if JumpCooldown <= 0 then
		Humanoid.JumpPower = JumpPower
		JumpCooldown = MaxJumpCooldown
	end
end)

Humanoid.StateChanged:Connect(function(oldState, newState)
	CurrentState = newState
	if newState == Enum.HumanoidStateType.Landed then
		IsJumping = false
	end
end)

Humanoid.Died:Connect(function()
	BodyVelocity:Destroy()
end)

However, it works fine on 60 fps, but when my fps reaches over that amount, I usually play on 240 fps, and my velocity becomes super fast over time. It has been an issue for me for a good amount of time and I don’t know how to fix it. I’ve already added delta time, but that didn’t fix it.

You forgot to apply deltaTime to your targetVelocity argument in the UpdateVelocity function.

1 Like

What exactly are you trying to do with this line?

	if not IsJumping then
		BodyVelocity.Velocity = BodyVelocity.Velocity * 1 --this line
		IsJumping = true
	end

Anything multiplied by 1 is itself, so you can remove that whole line since it isn’t doing anything.

I have already tried these, but nothing has changed. Higher framerates still cause extreme velocity gains.

local targetVelocity = Humanoid.MoveDirection * SpeedIncreaseRate * Humanoid.WalkSpeed * deltaTime / InitialWalkSpeed + HumanoidRootPart.Velocity

or

local targetVelocity = Humanoid.MoveDirection * SpeedIncreaseRate * Humanoid.WalkSpeed / InitialWalkSpeed * deltaTime  + HumanoidRootPart.Velocity

I used to multiply that 1 with higher amount but that just increases my running speed over time.

For now, the script is looking like this and I have to test it more. I haven’t encountered any issues yet

local LocalPlayer = game:GetService("Players").LocalPlayer
local Character

-- Function to reset velocity
local function ResetVelocity()
	if Character and Character:FindFirstChild("HumanoidRootPart") then
		Character.HumanoidRootPart.Velocity = Vector3.new(0, 0, 0)
	end
end

-- Wait for the character to exist
repeat
	Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
until Character

local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local BodyVelocity = Instance.new("BodyVelocity")
BodyVelocity.Parent = HumanoidRootPart

local Humanoid = Character:WaitForChild("Humanoid")
local CurrentState = nil
local IsJumping = false
local JumpCooldown = 0
local JumpPower = 53
local MaxJumpCooldown = 10
local SpeedIncreaseRate = 0.5
local MaxSpeed = 200
local Grounded = false
local LastMoveDirection = Vector3.new(0, 0, 0)
local InitialWalkSpeed = Humanoid.WalkSpeed
local InitialSpeedIncreaseRate = SpeedIncreaseRate

local function UpdateVelocity(deltaTime)
	if CurrentState ~= Enum.HumanoidStateType.Freefall then
		BodyVelocity.MaxForce = Vector3.new(0, 0, 0)
		-- Only update the BodyVelocity's velocity if not jumping
		if not IsJumping then
			BodyVelocity.Velocity = HumanoidRootPart.Velocity
		end
		return
	end

	BodyVelocity.MaxForce = Vector3.new(2000, 0, 2000)

	local targetVelocity = Humanoid.MoveDirection * SpeedIncreaseRate * Humanoid.WalkSpeed / InitialWalkSpeed * deltaTime + HumanoidRootPart.Velocity
	BodyVelocity.Velocity = Vector3.new(math.clamp(targetVelocity.X, -MaxSpeed, MaxSpeed), targetVelocity.Y, math.clamp(targetVelocity.Z, -MaxSpeed, MaxSpeed))

	-- Check if the player suddenly stopped
	local currentMoveDirection = Humanoid.MoveDirection
	if currentMoveDirection.magnitude < 0.1 and LastMoveDirection.magnitude > 0.1 then
		-- Reset velocity if the player suddenly stopped
		BodyVelocity.Velocity = Vector3.new(0, BodyVelocity.Velocity.Y, 0)
	end
	LastMoveDirection = currentMoveDirection

	-- Update jump cooldown
	JumpCooldown = math.max(JumpCooldown - deltaTime, 0)
end

game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
	deltaTime = deltaTime * 60
	UpdateVelocity(deltaTime)
end)

Humanoid.UseJumpPower = true

game:GetService("UserInputService").JumpRequest:Connect(function()
	if JumpCooldown <= 0 then
		Humanoid.JumpPower = JumpPower
		JumpCooldown = MaxJumpCooldown
	end
end)

Humanoid.StateChanged:Connect(function(oldState, newState)
	CurrentState = newState
	if newState == Enum.HumanoidStateType.Landed then
		IsJumping = false
	end
end)

Humanoid.Died:Connect(ResetVelocity)

-- Connect to CharacterAdded to reset velocity when the character respawns
LocalPlayer.CharacterAdded:Connect(ResetVelocity)