Its a pretty good stamina script, by the way, it has some issues on it
- Memory Management Issues:
local tweenInfo = TweenInfo.new(0.3)
local sprintViewTween = { FieldOfView = sprintView }
- Creates new tween instances every frame in
UpdateSprintState
- Wastes memory by repeatedly creating identical tweens
- Can lead to memory leaks over time
- State Management Issues:
local Stamina = 100
local isSprinting = false
- Global-like variables scattered throughout
- No centralized state management
- Makes it harder to track state changes
- Could lead to race conditions
- Performance Issues:
TweenServ:Create(Camera, tweenInfo, sprintViewTween):Play()
PlayerHum.WalkSpeed = sprintSpeed
- Updates WalkSpeed even when it hasn’t changed
- Creates new tween instances unnecessarily
- No optimization for frequent operations
- Code Structure Issues:
local staminaRegen = 0.3
local staminaDrain = 0.5
local defaultSpeed = 16
local sprintSpeed = 25
- Scattered configuration values
- No clear separation between config and logic
- Hard to maintain and modify
- Missing Error Handling:
local PlayerHum = Player.Character:WaitForChild('Humanoid')
- No timeout on WaitForChild
- Could potentially hang indefinitely
- No error handling for missing character
- If the script is in
StarterCharacterScripts
(which I assume it is) it is simpler just to put script.Parent:WaitForChild(“Humanoid”,true)
- Function Design Issues:
local function UpdateSprintState()
- Large function doing multiple things
- Mixed responsibilities
- Hard to test and maintain
- No use of deltaTime for smooth updates
- Input Handling Issues:
local function HandleSprintInput(actionName, inputState, input)
- Unnecessary parameters on Function (
input
)
- No debounce protection
- Could lead to input spamming
- Resource Management:
local Camera = workspace.CurrentCamera
- No caching of frequently accessed objects
- Repeated service calls
- Could impact performance
- Update Logic Issues:
if isSprinting and PlayerHum.MoveDirection.Magnitude > 0 then
- Nested if statements make logic hard to follow
- No clear separation between state update and visual update
- Could lead to edge cases
- Constants Management:
local sprintView = 100
local defaultView = Camera.FieldOfView
- Magic numbers throughout code (if you dont know what is a
Magic number
click this)
- No clear configuration section
- Hard to modify game feel
- Initialization Issues:
- No clear initialization block
- Services and variables mixed together
- No cleanup handling
- Documentation Issues:
To fix these issues, you would need to:
- Implement proper state management
- Cache frequently used objects
- Pre-create tweens
- Add proper error handling
- Optimize performance-critical code
- Add proper documentation
- Organize code better
- Add configuration management
- Implement proper cleanup
btw here the code with the cooldown function and some optimization:
-- [[ SERVICES ]]
local ContActServ = game:GetService('ContextActionService')
local RunServ = game:GetService('RunService')
local TweenServ = game:GetService('TweenService')
-- [[ CONSTANTS ]]
local STAMINA_CONFIG = {
MAX = 100,
REGEN_RATE = 0.3,
DRAIN_RATE = 0.5,
COOLDOWN_DURATION = 2
}
local SPEED_CONFIG = {
DEFAULT = 16,
SPRINT = 25
}
local VIEW_CONFIG = {
DEFAULT = workspace.CurrentCamera.FieldOfView,
SPRINT = 100,
TWEEN_INFO = TweenInfo.new(0.3)
}
-- [[ STATE ]]
local State = {
stamina = STAMINA_CONFIG.MAX,
isSprinting = false,
cooldownRemaining = 0
}
-- [[ CACHE ]]
local camera = workspace.CurrentCamera
local humanoid = script.Parent:WaitForChild("Humanoid",true)
-- [[ VIEW TWEENS ]]
local viewTweens = {
sprint = TweenServ:Create(camera, VIEW_CONFIG.TWEEN_INFO, {
FieldOfView = VIEW_CONFIG.SPRINT
}),
default = TweenServ:Create(camera, VIEW_CONFIG.TWEEN_INFO, {
FieldOfView = VIEW_CONFIG.DEFAULT
})
}
-- [[ UTILITY FUNCTIONS ]]
local function updateSpeed(speed)
if humanoid.WalkSpeed ~= speed then
humanoid.WalkSpeed = speed
end
end
local function updateView(isSprinting)
local tween = isSprinting and viewTweens.sprint or viewTweens.default
tween:Play()
end
-- [[ CORE FUNCTIONS ]]
local function handleSprintInput(_, inputState)
local isStarting = inputState == Enum.UserInputState.Begin
if State.isSprinting ~= isStarting then
State.isSprinting = isStarting
if not isStarting and State.stamina < STAMINA_CONFIG.MAX then
State.cooldownRemaining = STAMINA_CONFIG.COOLDOWN_DURATION
end
end
end
local function updateStaminaState(deltaTime)
local isMoving = humanoid.MoveDirection.Magnitude > 0
local canSprint = State.stamina > 0 and isMoving
local isActiveSprint = State.isSprinting and canSprint
-- Update stamina based on state
if isActiveSprint then
State.stamina = math.max(0, State.stamina - STAMINA_CONFIG.DRAIN_RATE)
State.cooldownRemaining = 0
elseif State.cooldownRemaining > 0 then
State.cooldownRemaining = math.max(0, State.cooldownRemaining - deltaTime)
elseif State.stamina < STAMINA_CONFIG.MAX then
State.stamina = math.min(STAMINA_CONFIG.MAX, State.stamina + STAMINA_CONFIG.REGEN_RATE)
end
-- Update character state
updateSpeed(isActiveSprint and SPEED_CONFIG.SPRINT or SPEED_CONFIG.DEFAULT)
updateView(isActiveSprint)
print(
string.format(
"Stamina: %.1f | Cooldown: %.1f",
State.stamina,
State.cooldownRemaining
)
)
end
-- [[ SCRIPT/INIT ]]
ContActServ:BindAction('Sprinting', handleSprintInput, false, Enum.KeyCode.LeftShift)
RunServ.RenderStepped:Connect(updateStaminaState)
The optimized version I provided earlier addresses most of these issues, try to analyze the code and its structure, it may help you to minimize the mistakes you may make in the future.
(I feel it was excessive but I hope I helped you )