Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do I create a sequenced ordered data store leaderboard?

Asked by 5 years ago
Edited 5 years ago

Hello,

Recently, I have created a leaderboard script in ServerScriptService for my game. It controls creating a stage, cash and wins leaderboard, which works great using DataStore2 :)

I have had a couple of issues on a part of this leaderboard, the ordered data store part.

Firstly, it does not order the wins in a high to low order. It has sequenced the players in a 'last updated' order.

For example:

What my leaderboard is showing:

https://cdn.discordapp.com/attachments/356675974928007168/518192064706379787/unknown.png

What I'm trying to get it to show:

https://cdn.discordapp.com/attachments/356675974928007168/518192333758398535/example.png

Secondly, I am having issues where the leaderboard doesn't appear at all. But then other times it appears. I think it is because ROBLOX has troubles with data stores ATM. That's why I switched to DataStore2 on standard data stores. If that is the answer to the problem, how do I use my ordered data store on the DataStore2 system?

This is an example on the leaderboard not appearing:

https://cdn.discordapp.com/attachments/356675974928007168/518193965791576092/unknown.png

This is the DataStore2 module and system:

Module: https://www.roblox.com/library/1936396537/DataStore2-Data-Loss-Prevention-and-Caching

Description: https://devforum.roblox.com/t/how-to-use-datastore2-data-store-caching-and-data-loss-prevention/136317

This is my current code for the leaderboard script in ServerScriptStorage:

The parts of the code that is relevant to the ordered data store leaderboard are lines 1-52.

local DataStore2 = require(game.ServerScriptService:WaitForChild("MainModule"))
local ODS = game:GetService("DataStoreService"):GetOrderedDataStore("WinsFixed")
local Pages = ODS:GetSortedAsync(false,10)
local Data = Pages:GetCurrentPage()
local GUI1=game.StarterGui.LeaderboardUI
local GUI2=game.StarterGui.LeaderboardUI1

local function Update()
    local succ,err = pcall(function()
        local Template = GUI1.Template
            for i,v in pairs(GUI1.MainFrame:GetChildren()) do
                if v:IsA("Frame") then
                    v:Destroy()
                end
            end
        local Template2 = GUI2.Template
            for i,v in pairs(GUI2.MainFrame:GetChildren()) do
                if v:IsA("Frame") then
                    v:Destroy()
                end
            end
        for a,k in pairs(Data) do
            local PlayerName = k.key
            local PlayerPoints = k.value
            local NewTemp = Template:Clone()
            NewTemp.Name = PlayerName
            NewTemp.FrameName.Text = PlayerName
            NewTemp.FrameValue.Text = PlayerPoints
            NewTemp.Visible = true
            NewTemp.Parent = GUI1.MainFrame
            NewTemp:Clone().Parent = GUI2.MainFrame
        end
    end)
    if err then
        warn("An error has occurred when trying to update leaderboard: " .. err)
        Update()
    end
end

game.Workspace.ChildAdded:Connect(function(object)
    local player = game.Players:GetPlayerFromCharacter(object)
    if player ~= nil then
        local ls = player:WaitForChild("leaderstats")
        local sl = game.Workspace:FindFirstChild(ls.Stage.Value)
        object.UpperTorso.CFrame = object.UpperTorso.CFrame + Vector3.new(0,3,0)
        wait()
        object.UpperTorso.CFrame = sl.CFrame + Vector3.new(0,3,0)
        while wait(60*3) do
            Update()
        end
    end
end)

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

    local cashDataStore = DataStore2("cash",player)
    local deathsDataStore = DataStore2("deaths",player)
    local standardDataStore = DataStore2("standard",player)
    local perfectDataStore = DataStore2("perfect",player)
    local speedDataStore = DataStore2("speed",player)

    local leaderstats = Instance.new("Folder",player)
    leaderstats.Name = "leaderstats"

    local winstats = Instance.new("Folder",player)
    winstats.Name = "winstats"

    local stage = Instance.new("IntValue",leaderstats)
    stage.Name = "Stage"
    stage.Value = 1

    local cash = Instance.new("IntValue",leaderstats)
    cash.Name = "Cash"

    local deaths = Instance.new("IntValue",winstats)
    deaths.Name = "Deaths"

    local BestPerfect = Instance.new("IntValue",winstats)
    BestPerfect.Name = "BestPerfect"

    local BestStandard = Instance.new("IntValue",winstats)
    BestStandard.Name = "BestStandard"

    local BestSpeed = Instance.new("IntValue",winstats)
    BestSpeed.Name = "BestSpeed"

    local specialmode = Instance.new("BoolValue",winstats)
    specialmode.Name = "Special"

    local mode = Instance.new("StringValue",leaderstats)
    mode.Name = "Mode"
    mode.Value = "Standard"

    local perfectmode = Instance.new("BoolValue",winstats)
    perfectmode.Name = "Perfect"

    local speedmode = Instance.new("BoolValue",winstats)
    speedmode.Name = "Speed"

    local Wins = Instance.new("NumberValue",winstats)
    Wins.Name = "Wins"

    local function cashUpdate(updatedValue)
        cash.Value = cashDataStore:Get(updatedValue)
    end

    local function deathsUpdate(updatedValue)
        deaths.Value = deathsDataStore:Get(updatedValue)
    end

    local function BestStandardUpdate(updatedValue)
        BestStandard.Value = standardDataStore:Get(updatedValue)
    end

    local function BestPerfectUpdate(updatedValue)
        BestPerfect.Value = perfectDataStore:Get(updatedValue)
    end

    local function BestSpeedUpdate(updatedValue)
        BestSpeed.Value = speedDataStore:Get(updatedValue)
    end

    cashUpdate(0)
    cashDataStore:OnUpdate(cashUpdate)

    deathsUpdate(0)
    deathsDataStore:OnUpdate(deathsUpdate)

    BestStandardUpdate(0)
    standardDataStore:OnUpdate(BestStandardUpdate)

    BestPerfectUpdate(0)
    perfectDataStore:OnUpdate(BestPerfectUpdate)

    BestSpeedUpdate(0)
    speedDataStore:OnUpdate(BestSpeedUpdate)

    player.CharacterAdded:Connect(function(Character)
        local d = true
        Character:WaitForChild("Humanoid").Died:Connect(function()
            if (d) then
                d = false
                local deathsDataStore = DataStore2("deaths",player)
                deathsDataStore:Increment(1, 0)
            end
        end)
    end)

    while true do
        wait()
        if (player.winstats.BestPerfect.Value == 11) and (player.leaderstats.Stage.Value > player.winstats.BestSpeed.Value) then
            if player.winstats.Perfect.Value ~= true then
                local speedDataStore = DataStore2("speed",player)
                speedDataStore:Set(player.leaderstats.Stage.Value)
            end

        elseif (player.winstats.BestStandard.Value == 11) and (player.leaderstats.Stage.Value > player.winstats.BestPerfect.Value) then
            local perfectDataStore = DataStore2("perfect",player)
            perfectDataStore:Set(player.leaderstats.Stage.Value)

        elseif player.leaderstats.Stage.Value > player.winstats.BestStandard.Value then
            local standardDataStore = DataStore2("standard",player)
            standardDataStore:Set(player.leaderstats.Stage.Value)

        end

        wait(40)
        local cashDataStore = DataStore2("cash",player)
        cashDataStore:Increment(1, 0)
    end
end)

game.Players.PlayerRemoving:Connect(function(plr)
    local Wins = plr.winstats.Wins
    if Wins then
        ODS:IncrementAsync(plr.Name, Wins.Value)
    end
end)

Any advice you can give will be appricated.

1 answer

Log in to vote
1
Answered by 5 years ago
Edited 5 years ago

Hello,

I have asked a couple of roblox scripting pros about this. They said this: First of all, they don't think ordered data stores are compatible with DataStore2.

Secondly, the reason why the leaderboard doesn't appear all the time is that the script is needed to include a new pcall function. As shown in the script.

Thirdly, the reason why the leaderboard isn't displaying in the correct order is that the UiListLayout of the actual UI has been setup incorrectly. These are the correct settings for my leaderboard:

https://cdn.discordapp.com/attachments/356675974928007168/524317164220579843/unknown.png

Another reason why the leaderboard didn't display in the correct order, is that I needed to include a new line of code which ordered the leaderboard, as it updated. Here is the corrected version of the code:

local DataStore2 = require(game.ServerScriptService:WaitForChild("MainModule"))
local ODS = game:GetService("DataStoreService"):GetOrderedDataStore("WinsFixed")
local GUI1=game.StarterGui.LeaderboardUI
local GUI2=game.StarterGui.LeaderboardUI1

local function load()
    local succ,err = pcall(function()            --New pcall function
        warn("Successfully loaded the leaderboard")
        local Pages = ODS:GetSortedAsync(true,10)
        local Data = Pages:GetCurrentPage()
        local Template = GUI1.Template

        for i,v in pairs(GUI1.MainFrame:GetChildren()) do
            if v:IsA("Frame") then
                v:Destroy()
            end
        end
        local Template2 = GUI2.Template
        for i,v in pairs(GUI2.MainFrame:GetChildren()) do
            if v:IsA("Frame") then
                v:Destroy()
            end
        end
        local succ2,err2 = pcall(function()
            for a,k in pairs(Data) do
                local PlayerName = k.key
                local PlayerPoints = k.value
                local NewTemp = Template:Clone()
                NewTemp.Name = PlayerName
                NewTemp.LayoutOrder = 10-a    --New line
                NewTemp.FrameName.Text = PlayerName
                NewTemp.FrameValue.Text = PlayerPoints
                NewTemp.Visible = true
                NewTemp.Parent = GUI1.MainFrame
                NewTemp:Clone().Parent = GUI2.MainFrame
            end
        end)
        if err2 then
            warn("No data to process")
            return
        end
    end)
    if err then
        warn("Failed to load the leaderboard")
        load()
    end
end

I have got rid of the 'Update' function and joined the two functions together for simplicity. Hope this helps.

0
Thanks for replying to yourself, I am now finding this useful. TomsGames 225 — 4y
Ad

Answer this question