[Updated] Free Sprint System

Greetings Developers,

To provide some context, I created this sprint system a few years ago when I was a beginner, and I’m now updating it to an improved version for you to enjoy! :heart:

For now, this resource include camera effects, GUI, and a stamina system.

Let me know if you would be interested in a more advanced version that could include footstep particles, custom character sounds and animations, improved camera effects, and more.


📌 Update Note 📌

22th February 2025
  • The overall code has been slightly optimized and improved.
  • Some minor issues have been fixed.
  • The scripts have been moved to StarterPlayerScripts.
  • The system is now modular.
  • A cooldown has been added before stamina regeneration starts.
  • WalkSpeed now changes using TweenService for a smoother transition.
  • Mouse lock is now automatically set to LeftControl whenever your sprint keybind is LeftShift.
  • The sprint no longer continue when your character is not moving.
  • The GUI has been slightly reworked.

📁 Try it now! 📁

https://create.roblox.com/store/asset/12165031331/Free-Sprint-System


59 Likes

Having Stamina as an integer value is easily exploitable; Just thought you might wanna know.

2 Likes

Yep that’s right, but making it in server is going to take too much ressources for the server and decrease game performances.
So you need to choose between a exploitable system or a laggy game.

5 Likes

It’s actually quite difficult as an exploiter to modify local values. So I’d suggest making something like:

local Stamina = 100

If an exploiter tried to access that, it would look like:

local v1 = 100

If my previous experience is correct.

5 Likes

you might want to explain what the code do, so when a beginner look at your codeblock they roughly understand the concept of it rather than copy and paste and not learning anything.

Exploiter cant change a variable data inside script

1 Like

I did this however the stamina bar goes out of frame and Im unsure how to fix it:
image

or you can just have

local Stamina = 100

instead of

local Stamina = script.IntValue.Value

Not exploitable and not laggy

2 Likes

The value inside the script is a bool, to check sprint activation, so don’t care if exploiter are changing it, it will just active or desactive the sprint.

it’s still better to use a local variable because values like shown in the script are still exploitable

Yep, that’s true.
Also this ressource is old, i made it long time ago and i still was a beginner ^^

As it is comming back, i’m probably going to update it

Updated it, let me know if i need to change something or if you got a question, thanks.

Yes, they can.
They can change anything inside any local script because their client has access to the code.

You still can store the “MaxStamina” and “Stamina” as player values in server side , then add a RemoteEvent:FireServer() inside the “Sprinting()” and “Regen” functions (do the repeat code inside the server side script with “onserverevent”) and run the BarResize with Stamina.Changed so the most important stats can’t be exploited.

local function Sprinting()
	RemoteEvent:FireServer()
end

local function Regen()
	RemoteEvent:FireServer()
end

local function BarResize()
	FrameGoal.Size = UDim2.fromScale(Stamina / MaxStamina, 1)
	FrameTween = TweenService:Create(script.Parent.Bar.Frame, Infos, FrameGoal)
	FrameTween:Play()
	script.Parent.Bar.Info.Text = Stamina.. "/" ..MaxStamina
end

Player.Stamina.Changed:Connect(function()
    BarResize()
end)
3 Likes

Yes but only read, not change inside it but they can write a similiar code too

No, they can change it too.
Client code is stored in RAM, so script executors can simply access it and edit properties.

An issue the stamina and FOV change when I press Shift even when I’m not moving

Use CanvasGroups, Any of it’s descendants can’t go out of the frame, read the documentation if you don’t know anything about CanvasGroups

2 Likes

I had to edit it a little bit to put this on my game, I added Regen CoolTime, Regen Increasement, Stamina Decreasement per .1 second to settings. I’ll leave it below but I’m kinda new to scripting so you may expect some issues.

-- Unofficial Sprinting System Update --
-- By: @qazxqwer21
-- Original(@Crygen54): https://devforum.roblox.com/t/updated-sprinting-system-stamina-gui-bar-camera-change/1215024
-- Added Regen CoolTime, Regen Increasement, Stamina Usage to settings

local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local PlayersStorage = game:GetService("Players")
local WorkspaceStorage = game:GetService("Workspace")

--// Variables //--
local Player = PlayersStorage.LocalPlayer
local Character = Player.Character
local Camera = WorkspaceStorage.CurrentCamera
local Humanoid = Character:WaitForChild("Humanoid" ,10)
local Infos = TweenInfo.new(0.25)
local FrameGoal = {}
local CameraGoal = {}
local FrameTween = {}
local CameraTween = {}

--// Settings //--
local CameraChangeEnabled = true
local Keybind = "LeftShift"
local MaxStamina = 100
local NormalWalkspeed = 16
local SprintWalkspeed = 25
local NormalCameraFOV = 70
local SprintCameraFOV = 80
local RegenCoolTime = 1
local RegenIncreasement = 2
local Decreasement = 1 --Stamina Usage per .1 second

--// Values //--
local Stamina = MaxStamina
local State = false
local Debounce = false
local WaitingTime = 0
--// Functions //--
local function BarResize()
	FrameGoal.Size = UDim2.fromScale(Stamina / MaxStamina, 1)
	FrameTween = TweenService:Create(script.Parent.Bar.Frame, Infos, FrameGoal)
	FrameTween:Play()
	script.Parent.Bar.Info.Text = Stamina.. "/" ..MaxStamina
end

local function Sprinting()
	if State == true and Humanoid and Stamina > 0 then
		Humanoid.WalkSpeed = SprintWalkspeed
		repeat
			wait(0.1)
			Stamina -= Decreasement
			BarResize()
		until
		Stamina <= 0 or State == false
		if Stamina <= 0 then
			Stamina = 0
			BarResize()
		end
		Humanoid.WalkSpeed = NormalWalkspeed
	end
end

local function Regen()
	if State == false and Stamina < MaxStamina then
		repeat
			wait(0.1)
			Stamina += RegenIncreasement
			BarResize()
		until
		Stamina >= MaxStamina or State == true
		if Stamina >= MaxStamina then
			Stamina = MaxStamina
			BarResize()
		end
	end
end

local function CameraChange()
	if State == true and CameraChangeEnabled == true then
		CameraGoal.FieldOfView = SprintCameraFOV
		CameraTween = TweenService:Create(Camera, Infos, CameraGoal)
		CameraTween:Play()
	elseif State == false and CameraChangeEnabled == true then
		CameraGoal.FieldOfView = NormalCameraFOV
		CameraTween = TweenService:Create(Camera, Infos, CameraGoal)
		CameraTween:Play()
	end
end



--// Connections //--
UserInputService.InputBegan:Connect(function(key, processed)
	if key.UserInputType == Enum.UserInputType.Keyboard then
		if key.KeyCode == Enum.KeyCode[Keybind] then
			State = true
			CameraChange()
			Sprinting()
		end
	end
end)

UserInputService.InputEnded:Connect(function(key, processed)
	if key.UserInputType == Enum.UserInputType.Keyboard then
		if key.KeyCode == Enum.KeyCode[Keybind] then
			State = false
			CameraChange()
			if Debounce == false then
				Debounce = true
				while not State do
					task.wait(.1)
					WaitingTime += 0.1
					if WaitingTime > RegenCoolTime then
						WaitingTime = 0
						Regen()
						break
					end
				end
				Debounce = false
			end
		end
	end
end)

You could have asked me for an update. :smile:
This resource was years old, so as you are expecting an improvement, I’ve created a new version. You can look back at the main post.

Feel free to provide feedback and suggestions, as well as reporting bugs if you find some.