I am creating a speed run game that starts a timer on the player's screen once they touch a starting brick. The timer is saved as a stat in their leaderboard and if it is better than their fastest time, it will replace their fastest time with the timer. I have this script inside of a local script inside the player's GUI and I am using remote events to trigger the timer. I'm pretty new to scripting and I don't know the best ways of combatting exploiters. Is it fine that I coded it the way I did?
Local Script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("ShowTime")
local Clear = ReplicatedStorage:WaitForChild("ClearTimeran")
local Replace = ReplicatedStorage:WaitForChild("Replace")
local SpeedBrick = workspace.RunBlock
local EndBrick = workspace.EndBlock
local go = true
local db = false
SpeedBrick.Touched:Connect(function(hit)
local startplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
if startplayer ~= nil and startplayer == game:GetService("Players").LocalPlayer then
if db == false then
db = true
Clear:FireServer()
repeat
wait(0.1)
remoteEvent:FireServer()
---SHOWING ON GUI---
local player = script.Parent.Parent.Parent.Parent.Parent
local leaderstats = player:WaitForChild("leaderstats")
local stat = leaderstats:WaitForChild("runningtime")
local besttime = leaderstats:WaitForChild("time1")
script.Parent.Text = stat.Value
stat.Changed:Connect(function()
script.Parent.Text = stat.Value
end)
if stat.Value < besttime.Value then
local ColorNew = Color3.new(0.333333, 1, 0) --GREEN
script.Parent.TextColor3 = ColorNew
end
if stat.Value > besttime.Value and besttime.Value ~= 0 then
local ColorNew = Color3.new(1, 0, 0) --RED
script.Parent.TextColor3 = ColorNew
end
-------------------
EndBrick.Touched:Connect(function(hit)
local endplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
if endplayer ~= nil and endplayer == game:GetService("Players").LocalPlayer then
go = false
end
end)
until go == false
end
wait(0.5)
db = true
end
--Clearing timeran and replacing leveltime
if go == false then
local player = script.Parent.Parent.Parent.Parent.Parent
local leaderstats = player:WaitForChild("leaderstats")
local stat = leaderstats:WaitForChild("runningtime")
local leveltime = leaderstats:WaitForChild("time1")
if stat.Value < leveltime.Value then
Replace:FireServer(leveltime,stat)
script.Parent.Parent.BestTimeValue.Text = stat.Value
elseif leveltime.Value == 0 then
Replace:FireServer(leveltime,stat)
script.Parent.Parent.BestTimeValue.Text = stat.Value
end
end
end)
Server Script:
local remote = game:GetService("ReplicatedStorage")
local remoteEvent = remote:WaitForChild("ShowTime")
remoteEvent.OnServerEvent:Connect(function(player)
player.leaderstats.runningtime.Value = player.leaderstats.runningtime.Value + 0.1
end)
I know that putting sensitive information in local scripts is never the best option but is the way I coded it still safe from exploiters being able to tamper with their run timer?
Also, the game will give better rewards the faster they complete the speed run
Any help would be appreciated!

1 comment
Pro tip, in your SS line 5, you can use the operator "+=" which is a shorthand for "variable = variable + value" so you can just write "player.leaderstats.runningtime.Value += 0.1" instead of having to write out the entire path twice