Leaderboard and DataStore not updating race times

I have a leaderboard script with a datastore in it as well… One leaderboard (named “board”) is showing race times (best and last lap) but it won’t save once player leaves server. I tried to add the native leaderstats to save these times and then load that to the board, but it isn’t saving the stats nor updating that leaderstats ui at all.

Ideally i dont want the native leaderstats, I just want that to save my times so that my physical leaderboard can display the saved times (Best Lap) to the board when players enter and leave. I am not strong enough in scripting to figure this out. And i think i should also be using ordereddatastore, but not sure how to work that out.

Here is my script:

local times = {}

local replicatedStorage = game:GetService("ReplicatedStorage")
local setLapTimeEvent = Instance.new("RemoteEvent", replicatedStorage)
setLapTimeEvent.Name = "SetLapTimeEvent"
local showLapsEvent = Instance.new("RemoteEvent", replicatedStorage)
showLapsEvent.Name = "ShowLapsEvent"
local cornerCutEvent = Instance.new("RemoteEvent", replicatedStorage)
cornerCutEvent.Name = "CornerCutEvent"

local board = script.Parent.Board
local timesFrame = board.TimingGui.LapTimes

local converter = require(workspace.TimingModule)

function NumberToTime(number)

	return converter:NumberToTime(number)

end

function SortTimes()

	return converter:SortTimes(times)

end

function DisplayLapTimes()

	local sortedTimes = SortTimes()

	showLapsEvent:FireAllClients(sortedTimes)

	for _, item in pairs(timesFrame:GetChildren()) do
		if item.Name ~= "Temp" then
			item:Destroy()
		end
	end

	for pos, item in pairs(sortedTimes) do
		local frame = timesFrame.Temp:Clone()
		frame.Parent = timesFrame
		frame.PlayerName.Text = item["player"]
		frame.Name = item["player"]
		frame.LastLap.Text = NumberToTime(item["lastTime"])
		if item["lapValid"] then
			frame.LastLap.TextColor3 = Color3.fromRGB(255, 246, 147)
		else
			frame.LastLap.TextColor3 = Color3.fromRGB(255, 150, 150)
		end
		frame.BestLap.Text = NumberToTime(item["bestTime"])
		frame.Pos.Text = pos
		frame.Position = UDim2.new(0, 0, 0, 50 * (pos - 1))
		frame.Visible = true
	end

	timesFrame.CanvasSize = UDim2.new(0, 0, 0, #sortedTimes)

end

function SetLapTime(plr, lapTime, lapValid)

	UpdateLapCount(plr, times[plr.Name]["lastTime"], times[plr.Name]["bestTime"])

	times[plr.Name]["lastTime"] = lapTime

	times[plr.Name]["lapValid"] = lapValid

	if lapValid and (times[plr.Name]["bestTime"] > lapTime or times[plr.Name]["bestTime"] == 0) then
		times[plr.Name]["bestTime"] = lapTime
	end

	setLapTimeEvent:FireAllClients(plr.Name, lapTime, lapValid)
	DisplayLapTimes()
end


function UpdateLapCount(plr, newLastLap, newBestLap)
	if plr:FindFirstChild("leaderstats") and plr.leaderstats:FindFirstChild("Last lap") then
		plr.leaderstats["Last lap"].Value = newLastLap
	end
	if plr:FindFirstChild("leaderstats") and plr.leaderstats:FindFirstChild("Best lap") then
		plr.leaderstats["Best lap"].Value = newBestLap
	end
end


game.Players.PlayerAdded:Connect(function(plr)
	times[plr.Name] = {lastTime = 0, bestTime = 0, laps = 0, lapValid = true}
	DisplayLapTimes()
end)

game.Players.PlayerRemoving:Connect(function(plr)
	times[plr.Name] = nil
	DisplayLapTimes()
end)

setLapTimeEvent.OnServerEvent:Connect(SetLapTime)



local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("MyDataStore")


local function saveData(plr)

	local tableToSave = {
		plr.leaderstats["Last lap"].Value; 
		plr.leaderstats["Best lap"].Value
	}

	local success, err = pcall(function()
		dataStore:SetAsync(plr.UserId, tableToSave) 
	end)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(plr) 

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Laptime = Instance.new("NumberValue")
	Laptime.Name = "Last lap"
	Laptime.Value = 0
	Laptime.Parent = leaderstats

	local Besttime = Instance.new("NumberValue")
	Besttime.Name = "Best lap"
	Besttime.Value = 0
	Besttime.Parent = leaderstats

	local data 
	local success, err = pcall(function()

		data = dataStore:GetAsync(plr.UserId) 

	end)

	if success and data then -- If there were no errors and player loaded the data

		Laptime.Value = data[1] 
		Besttime.Value = data[2]

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
	end

end)

game.Players.PlayerRemoving:Connect(function(plr)
	local success, err  = pcall(function()
		saveData(plr) -- Save the data
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, plr in pairs(game.Players:GetPlayers()) do 
		local success, err  = pcall(function()
			saveData(plr) -- Save the data
		end)

		if success then
			print("Data has been saved")
		else
			print("Data has not been saved!")
		end
	end
end)

Is there anything in the output?

I got some help from a friend with this and it is storing data now… i will post it up here when i get to computer. I will need help with making it an ordered datastore though please.

You should try it yourself first and ask for help about issues afterwards.

Yes that’s why I said i will need help. You can see from the script posted above that i dont need people to