Hello developers,
I made a speedrun for my obby game, it works but there is a problem if player is laggy or slow internet then the timer is also laggy along with him and its not being fair for other speed runners, as they don’t lag so their timer is correct and others are wrong, is there any way to fix this, the script is in a local script
show me your code that I can see some errors
2 Likes
RatiusRat
(Boopmaster)
May 29, 2021, 8:43am
#3
You should calculate in the server cause exploiters and use os.clock() as an accurate timer.
1 Like
F3NAI
(JosVyras)
May 29, 2021, 9:13am
#4
Use RemoteEvents for each timer - exploiters cannot change the time and laggy people will have the same time.
1 Like
How will the remote event know when to end speed run, i mean the server side script
the script:
local seconds = 0
local mins = 0
local starttimer = false
local canwork = true
local overallseconds = 0
local hours = 0
local target = 0
local currentstage = 1
local currentdifficulty = 1
game.ReplicatedStorage.UpdateStage.OnClientEvent:Connect(function(number)
if tonumber(number) == tonumber(target) then
starttimer = false
if target == 21 then
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("1").CFrame + Vector3.new(0,5,0)
elseif target == 40 then
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("21").CFrame + Vector3.new(0,5,0)
elseif target == 60 then
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("40").CFrame + Vector3.new(0,5,0)
end
script.Parent.Text = "Speedrun completed! Time: "..mins..":"..seconds
target = 0
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,true)
wait(2)
script.Parent.Visible = false
script.Parent.Parent.Parent.IsReplaying.Value = false
game.ReplicatedStorage.SaveSpeedRunEvent:FireServer(currentdifficulty,seconds)
end
end)
game.ReplicatedStorage.ToggleSpeedrunEvent.OnClientEvent:Connect(function(difficultynumber)
script.Parent.Visible = true
overallseconds = 0
seconds = 0
mins = 0
hours = 0
if difficultynumber == 1 then
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("1").CFrame + Vector3.new(0,5,0)
target = 21
currentdifficulty = 1
elseif difficultynumber == 2 then
currentdifficulty = 2
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("21").CFrame + Vector3.new(0,5,0)
target = 40
elseif difficultynumber == 3 then
currentdifficulty = 3
game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = game.Workspace.Checkpoint:FindFirstChild("40").CFrame + Vector3.new(0,5,0)
target = 60
end
script.Parent.Text = "You need to reach the next difficuty"
game.Players.LocalPlayer.Character.HumanoidRootPart.Anchored = true
wait(2)
script.Parent.Text = "You cannot chat during speed run"
wait(1.5)
script.Parent.Text = "Good luck!"
wait(1.5)
script.Parent.Text = "3"
wait(1)
script.Parent.Text = "2"
wait(1)
script.Parent.Text = "1"
wait(1)
script.Parent.Text = "Go!"
starttimer = true
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,false)
game.Players.LocalPlayer.Character.HumanoidRootPart.Anchored = false
script.Parent.Parent.Parent:FindFirstChild("IsReplaying").Value = true
end)
while wait(0.5) do
if starttimer == true then
if starttimer == true and target ~= 0 then
if seconds >= 59 then
seconds = 0
mins = mins + 1
overallseconds = overallseconds + 0.5
else
seconds = seconds + 0.5
overallseconds = overallseconds + 0.5
end
script.Parent.Text = hours..":"..mins..":"..seconds
end
end
end
here difficulties means each difficulty, as its a difficulty chart obby you can do any difficulty speedrun like speedrun easy difficulty.Like that
can you set os.time() as starting time and then calculate? or use tick()
You should not use wait(.5) as a clock. Use tick() or something accurate. Wait(seconds) is not guaranteed, as you have found out the hard way.
1 Like
yes now i used tick but uh how do i make the timer to seconds,mins and hours?
sample tick again at the end and subtract, that gives you seconds elapsed. divide that to get minutes or hours etc.
1 Like
like this i guess
the script:
while wait(0.5) do
if starttimer == true then
if starttimer == true and target ~= 0 then
overallseconds = tick() - startingtime
seconds = string.sub(tostring(overallseconds),#tostring(overallseconds) - 1,#tostring(overallseconds))
script.Parent.Text = hours..":"..mins..":"..seconds
end
end
end
is it correct? the script one or wrong
RatiusRat
(Boopmaster)
May 29, 2021, 9:44am
#13
You should fire a function when the player finishes instead of a loop.
1 Like
then how can u make a timer without loop
the format is this maybe
local Minutes = (Seconds - Seconds%60)/60
Seconds = Seconds - Minutes*60
local Hours = (Minutes - Minutes%60)/60
Minutes = Minutes - Hours*60
end)
RatiusRat
(Boopmaster)
May 29, 2021, 9:45am
#16
tick() does it for you it’s a universal timer.
1 Like
yes i mean like the player may lag but the starting time won’t change so the timer works according to starting time only right
I don’t think that is a good way to do it. I don’t think you need this while loop at all. You know when the race starts, you know when it ends, why do you need to loop and wait for this?
when the race starts: starttime = tick()
when the race is done: elapsedtime = tick() - starttime
then you can find hours, minutes, seconds based on the number of seconds you have in elapsedtime
1 Like
yes and the timer is elapsed time and thats why its looped
Right but you don’t need a loop to do that, you capture the start time, then subtract it from the end time.
Your loop could waste up to .5 seconds before it figures out starttimer == false
1 Like