Help with Timing System

I am attempting to create a timing system for an obby. Here is my timeManager script.

-- Variables
local timeManager = {}
local timeData = {}

-- Services
local coreModule = require(script:FindFirstAncestor("CoreModule"))
local timeFormattingLibrary = coreModule:Get("Libraries.TimeFormattingLibrary")
local players = coreModule.Services.Players

-- Data
local playerDataManager = coreModule:Get("GameModules.ServerGameManager.PlayerManager.PlayerDataManager")
local orderedDataLibrary = coreModule:Get("Libraries.DataLibrary.OrderedDataLibrary")

-- Remotes
local leaderboardRemote = coreModule.SharedCore:Get("Libraries.RemoteLibrary"):GetRemote("GetTimes")
local startTimeRemote = coreModule.SharedCore:Get("Libraries.RemoteLibrary"):GetRemote("StartTime")

-- Methods
function timeManager:StartTiming(player)
	local playerData = playerDataManager:GetData(player)
	if playerData.Values.TimeMode == true then return end
	
	playerData.Values.TimeMode = true
	timeData[#timeData + 1] = {userId = player.UserId, startTime = tick(), totalTime = nil}
end

function timeManager:StopTiming(player, optional)
	local playerData = playerDataManager:GetData(player)
	
	local index = timeManager:find(timeData, player.UserId, 'userId')
	if not index then return end
	
	if optional == true then
		print(optional)
		playerData.Values.LatestCheckpoint = 1
		playerData.Values.TimeMode = false
		startTimeRemote:FireClient(player)
		return
	end
	
	playerData.Values.LatestCheckpoint = 1
	index["totalTime"] = tick() - index["startTime"]
	startTimeRemote:FireClient(player)
	playerData.Values.TimeMode = false

	local timeToComplete = timeFormattingLibrary:FormatSecondsToHMS(index["totalTime"]*60)
	timeManager:UpdateLeaderboard(index["userId"], index["totalTime"])
	table.remove(timeData, player.UserId)
end

function timeManager:UpdateLeaderboard(id, value)
	return orderedDataLibrary:SetAsync("_TimeLeaderboard", id, value)
end

function timeManager:find(tbl, value, key)
    if key then
        for k, v in pairs(tbl) do
            if v[key] == value then
                return v, k
            end
        end
    else
        return table.find(tbl, value)
    end
end

-- Initialize
function timeManager:Initialize()
    coroutine.wrap(function()
		if #players:GetPlayers() == 0 then
			players.PlayerAdded:Wait()
		end

		wait(1)
		
        while true do
            pcall(function()
				local sendTimeData = orderedDataLibrary:GetSortedAsync("_TimeLeaderboard", false, 18):GetCurrentPage()
                leaderboardRemote:FireAllClients(sendTimeData)
            end)
            wait(180)
        end
    end)()
end

--
return timeManager
Here is the code for saving
-- Variables
local orderedDataLibrary = {}
local coreModule = require(script:FindFirstAncestor("CoreModule"))

local throttleProtectionLibrary = coreModule:Get("Libraries.DataLibrary.ThrottleProtectionLibrary")
local config = coreModule:Get("Libraries.DataLibrary.Config")

-- Methods
function orderedDataLibrary:GetSortedAsync(orderdDataStoreName, ...)
	local orderedDataStore = coreModule.Services.DataStoreService:GetOrderedDataStore(orderdDataStoreName)
	
	-- L O O P
	for i = 1, config.RetryAttempts + 1 do
		throttleProtectionLibrary:WaitForRequestBudget(Enum.DataStoreRequestType.GetSortedAsync, orderedDataStore)
		
		local wasSuccesful, returnedData = pcall(orderedDataStore.GetSortedAsync, orderedDataStore, ...)
		if wasSuccesful then return returnedData end
	end
end

function orderedDataLibrary:SetAsync(orderedDataStoreName, orderedDataStoreKey, newValue)
	if not config.SaveInStudio and coreModule.Services.RunService:IsStudio() then return end
	local orderedDataStore = coreModule.Services.DataStoreService:GetOrderedDataStore(orderedDataStoreName)
	
	-- L O O P
	for i = 1, config.RetryAttempts + 1 do
		throttleProtectionLibrary:WaitForRequestBudget(Enum.DataStoreRequestType.SetIncrementAsync, orderedDataStore, orderedDataStoreKey)
		throttleProtectionLibrary:AddToTemporaryCache(orderedDataStore, orderedDataStoreKey)
		
		local wasSuccesful = pcall(orderedDataStore.SetAsync, orderedDataStore, orderedDataStoreKey, newValue)
		if wasSuccesful then break end
	end
end

--
return orderedDataLibrary

I believe that the issue involves the timeManager script but I cannot figure out what the issue is.

1 Like

What exactly is the issue here? Is there something wrong with timing or what?

1 Like

When I try sending the ordered datastore page to the client, its nil. #sendTimeData is 0 and I cannot figure out why. It seems that there may be an issue with the saving but I cannot figure out what it is.

try outputting the value of wasSuccesful whenever you do the pcall, maybe this code isn’t running at all because of the .SaveInStudio and :IsStudio() or maybe it’s unsuccessful for each of the RetryAttempts

you could also try checking a known saved value in the datastore with :GetAsync before doing :FireAllClients to see if it exists

I tested all of this in-game, not in studio.

Figured out what the issue was - thanks @4SHN! I was converting the amount of time to 00:00:00 format when OrderedDataStores only accept numbers.