This is my first time making a code for a leaderboard in my game. I didn’t really do much research, only about OrderedDataStores. For that reason, I really want to know if there’s anything I could improve, specially about the data saving part of the code. I’m afraid if this amount of :SetAsync()
s could be a bad practice.
I’ll emphasize that my game doesn’t have many players, rarely there are enough players to have more than 1 server (the size of one server is 25). Even though, I still want to have the best code possible for this, specially because who knows if the game will get bigger.
local dataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")
local boardDataStore = dataStoreService:GetOrderedDataStore("AllTimeKills")
local leaderboardModel = script.Parent
local boardSize = 25
local updateTime = 60 * 5 -- 5 minutes
local function SetPlayerKills(player) -- save the kills in the new global data store
local kills = player:WaitForChild("leaderstats"):WaitForChild("Total Kills").Value
boardDataStore:SetAsync(player.UserId, kills)
end
for _, player in players:GetPlayers() do -- set in case a player joined before the PlayerAdded signal is connected
SetPlayerKills(player)
end
players.PlayerAdded:Connect(SetPlayerKills)
players.PlayerRemoving:Connect(SetPlayerKills)
-- saves their kills once they join and leave
local function LoadLeaderboard()
local orderedDataPages: DataStorePages = boardDataStore:GetSortedAsync(false, boardSize)
local pagesInfo: {{key: string, value: any}} = orderedDataPages:GetCurrentPage()
-- getting the pages in the function in case a player gets more kills than the 25th place for example, which would remove them from the page
for rank, data in pagesInfo do
local userId = data.key
local kills = data.value
local chosenSlot = leaderboardModel.Leaderboard.ScrollingFrame[tostring(rank)]
chosenSlot.PlayerName.Text = players:GetNameFromUserIdAsync(userId)
chosenSlot.Kills.Text = tostring(kills)
end
end
while true do
-- saves the new kills of the players each 5 minutes, also updating the leaderboard between multiple servers
for _, player in players:GetPlayers() do
SetPlayerKills(player)
end
LoadLeaderboard()
task.wait(updateTime)
end