How to update Leaderstats with a number value for best time (obby speed run help)

  1. **What do you want to achieve?
    To update the leaderstats best value with a number value

  2. What is the issue?
    The leaderstats wont update it displays 0 when a value is set

  3. What solutions have you tried so far?
    Looking on the dev.hub y.t and google

The scripts are to make a speed run style obbly. This would be timed for the full run. and players best time displayed on the leaderstats. so they have a target to beat.(I have a working stopwatch Gui)

I am planing to implement an ordered data store global leaderboard to display the best (lowest time)
I am really not sure how to achieve this correctly. One step at a time though.

I know that getting the players ‘best’ (lowest time) into the leaderstats is a good place to start.

Hello the problem is the leaderstats ‘best’ wont update to the current Number.Value

I have a local script in starterGui that controls a stopwatch timer that is activated/deactivated by touching blocks.
The finalTime variable is sent to a number value when the stopwatch stops (BestTimeNV)
That is located in StarterPlayer.StarterPlayer.Scripts

If i manually set the Number.Value to = 100 this will display in the ‘best’ leaderstats

but when the Number.Value starts from 0 and ‘records’ the final time this is not updated by
‘best’ in leaderstats.

I would appreciate pointers for the ‘best’ displaying the lowest best p.b time. overwriting if the time is lower than previous best.

I will attach the two leaderstats scripts (these are regular scripts)

local function onPlayerJoin(player)
	
	local leaderstats = Instance.new('Folder')
	leaderstats.Name = 'leaderstats'
	leaderstats.Parent = player
	
	local best = Instance.new('NumberValue')
	best.Name = 'Best'
	best.Value = 0
	best.Parent = leaderstats
	
end
game.Players.PlayerAdded:Connect(onPlayerJoin)

Next Script

local function addTime(player)
	
	local bestime = game.StarterPlayer.StarterPlayerScripts.Bv:FindFirstChild("BestTimeNV")
	
	while true do
		wait(1)
		bestime:GetPropertyChangedSignal("Value"):Connect(function(player)
		end)
		
		print(bestime.Value.. "this is the timer script bestime")
		
		player.leaderstats.Best.Value = player.leaderstats.Best.Value + bestime.Value

	end
	
end

game.Players.PlayerAdded:Connect(addTime)

I would like any advice please I know this is a probably simple solution for someone
who proficient at roblox lua, I am just starting out (if you cant tell!)
I can include the stopwatch script if it is needed.
Thanks

1 Like

Both these scripts are in ServerScriptService
Thanks

In the second script you gave, I believe the problem is that you’re ending the GetPropertyChangedSignal too soon. Also, I don’t believe you need to use a function or loop with a wait(), as using GetPropertyChangedSignal will update the value every time “Value” is changed.

Try this instead (Will work for only your own player, which is LocalPlayer):

local player = game.Player.LocalPlayer
local bestime = player.StarterPlayer.StarterPlayerScripts.Bv:FindFirstChild("BestTimeNV")

bestime:GetPropertyChangedSignal("Value"):Connect(function()
    print(bestime.Value.. "this is the timer script bestime")
		
    player.leaderstats.Best.Value += bestime.Value
end)

Extra Tip: Roblox lua, special operators were introduced. So,

value += 1

is now the same as,

value = value + 1

Handy huh?

1 Like

Hello and thanks for trying to help. The code isnt working for me.

15:42:21.121 - Player is not a valid member of DataModel

is the error I am getting.

bro you’re using starter player instead of the actual player

How do I fix it to the actual player then?

player.PlayerScripts I think!!!

game.Players.PlayerAdded:Connect(function(player)
local x = Instance.new("IntValue")
x.Parent = player
x.Name = "BestTime"
local z = Instance.new("IntValue")
z.Parent = player
z.Name = "CurrentTime"
end) -- you could also slide this in your playeradded function or whatever
local z = {}
local stopwatch = require(game.ServerStorage.stopwatch)
--call this event on player start
--this assumes all players start at the same time
for i,v in pairs(game.Players:GetPlayers()) do
 stopwatch.create(v.Name)
end

workspace.EndPart.Touched:Connect(function(part)
 if (part.Position - workspace.EndPart.Position).Magnitude <= 10 then
 local name = part.Parent.Name
 local time = stopwatch.end(name)
if game.Players:FindFirstChild[name]:FindFirstChild("BestTime").Value >= time then game.Players:FindFirstChild[name]:FindFirstChild("BestTime").Value = time end
 end
end) -- assumes the end part is called "EndPart"
 
game.ReplicatedStorage.updatetime.OnServerEvent:Connect(function(player)
 pcall(function()
  game.ReplicatedStorage.updatetime:FireClient(stopwatch.gettime(player.Name))
end)
end)
 

-- stopwatch module
local tbl = {}
local othertbl = {}
local holder = {}
function tbl.create(name)
 if holder[name] == nil then 
 othertbl[name] = true
  coroutine.wrap(function()
   while true do
     game:GetService('RunService').Heartbeat:Wait()
     local t = os.time() 
     repeat wait() until os.time() = t + 1 
     holder[name] = holder[name] + 1
    if othertbl[name] == false then
     break
    end
   end
  end)()
 else 
  error("Player already has a running stopwatch.")
 end
end

function tbl.end(name)
 othertbl[name] = false
 local data = holder[name]
 holder[name] = nil
 return data
end

function tbl.gettime(name)
 return holder[name]
end

return tbl

edit: made a better loop probably

Thanks Its an individuals time per client.
I have a stopwatch (local-script)script in ‘starterplayergui’ this sends the stopwatch - finalTime to a number.value that is in starterplayerscripts (should I move this location?)

the problem i am having is ‘how to fetch’ the number.value into the leaderstats
when i play the game the number.value in the player isn’t updating.

you can’t update leaderstats on the client, only on the server, so that’s probably why

I am under the impression that the leaderstats is the best place to have any ‘player data’ that is
to be used in a datastore?

There must be an easy solution to this

Should I use a remote event to fire the final Time number value to the server?

You miss-spelled Players that’s why it throwed that error.

I didn’t know you could do that! This will save me a lot of time in the future. :smiley:

1 Like

@jellyfishes1298 Hello, did you get this working as I am having a similar problem with my script - as in getting the finishing time to register when a part is hit. I also have a timer in leaderstats. Thank you.