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

Why is this code having trouble when I store more than one leaderstat?

Asked by 3 years ago

I was following a tutorial from AlvinBlox, because I'm relatively new to RBX Lua scripting, on how to DataStore leaderstats. I couldn't really find anything on Youtube that stored multiple leaderstats and worked for me, so I tried to common-sense my way out of the problem. Turns out this doesn't work, because even though everything prints out success it doesn't actually load anything in. If anyone could fix up my code and/or tell me why it doesn't work would be greatly appreciated.

local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local myDataStore2 = DataStoreService:GetDataStore("myDataStore2")
local myDataStore3 = DataStoreService:GetDataStore("myDataStore3")

game.Players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local Points = Instance.new("IntValue")
    Points.Name = "LagPoints"
    Points.Parent = leaderstats

    local Minutes = Instance.new("IntValue")
    Minutes.Name = "Minutes"
    Minutes.Parent = leaderstats

    local Bricks = Instance.new("IntValue")
    Bricks.Name = "Bricks"
    Bricks.Parent = leaderstats

    local datapoints
    local dataminutes
    local databricks

    local success, errormessage = pcall(function()
        datapoints = myDataStore:GetAsync(player.UserId.."-points")
    end)
    if success then
        Points.Value = datapoints
        print("Data succesfully loaded your LagPoints.")
    else
        print("There was an error whilst getting your data for LagPoints.")
    end

    local success, errormessage = pcall(function()
        dataminutes = myDataStore2:GetAsync(player.UserId.."-mins")
    end)
    if success then
        Points.Value = dataminutes
        print("Data succesfully loaded your Minutes in Lag-Mode.")
    else
        print("There was an error whilst getting your data for Minutes.")
    end

        local success, errormessage = pcall(function()
        datapoints = myDataStore3:GetAsync(player.UserId.."-bricks")
    end)
    if success then
        Points.Value = databricks
        print("Data succesfully loaded your Bricks Spawned.")
    else
        print("There was an error whilst getting your data for Bricks.")
    end

end)

game.Players.PlayerRemoving:Connect(function(player)
    local success, errormessage = pcall(function()
        myDataStore:SetAsync(player.UserId.."-points",player.leaderstats.LagPoints.Value)
    end)
    if success then
        print(player.Name.."'s Data Saved Succesfully.")
    else
        print("There was an error saving "..player.Name.."'s data!")
        warn(errormessage)
    end

    local success, errormessage = pcall(function()
        myDataStore2:SetAsync(player.UserId.."-mins",player.leaderstats.Minutes.Value)
    end)
    if success then
        print(player.Name.."'s Data Saved Succesfully.")
    else
        print("There was an error saving "..player.Name.."'s data!")
        warn(errormessage)
    end

    local success, errormessage = pcall(function()
        myDataStore3:SetAsync(player.UserId.."-bricks",player.leaderstats.Bricks.Value)
    end)
    if success then
        print(player.Name.."'s Data Saved Succesfully.")
    else
        print("There was an error saving "..player.Name.."'s data!")
        warn(errormessage)
    end
end)

3 answers

Log in to vote
0
Answered by 3 years ago

Well in order to make a fully functioning leaderboard, here is my approach.

Setting the leaderboard

game.Players.PlayerAdded:Connect(function(plr)
    local leaderstats = Instance.new('Folder')
    leaderstats.Name = 'leaderstats'
    leaderstats.Parent = plr

    local dollar = Instance.new('IntValue')
    dollar.Name = 'Money'
    dollar.Value = 0
    dollar.Parent = leaderstats

    local item = Instance.new('IntValue')
    item.Name = 'Items'
    item.Value = 0
    item.Parent = leaderstats
end)

Now in order to actually see visible change, I added a part to show the intValue increment by 1.

Updating leaderboard

script.Parent.Parent.Part.Touched:Connect(function(touch)
    local parent = touch.Parent --Who touched the part
    local humanoid = parent:FindFirstChildWhichIsA('Humanoid')
    if humanoid then --If humanoid
        local plr = game:GetService('Players'):GetPlayerFromCharacter(parent) -- Gets leaderboard
        local leaderstats = plr.leaderstats
        local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money')
        if moneyMaker then
            moneyMaker.Value = moneyMaker.Value + 1 --Changes value from 0 to +1 everytime it is touched.
        end
    end
end)

This is a simple leaderboard approach that I made just now. I also suggest you look on roblox's tutorials here- Leaderboard tutorial - https://developer.roblox.com/en-us/articles/Leaderboards

Full script-

local dds = game:GetService('DataStoreService')
local moneyData = dds:GetDataStore('MONEYDATA')
local itemData = dds:GetDataStore('ITEMDATA')

game.Players.PlayerAdded:Connect(function(plr)
    local data
    local data2
    local leaderstats = Instance.new('Folder')
    leaderstats.Name = 'leaderstats'
    leaderstats.Parent = plr

    local dollar = Instance.new('IntValue')
    dollar.Name = 'Money'
    dollar.Value = 0
    dollar.Parent = leaderstats

    local item = Instance.new('IntValue')
    item.Name = 'Items'
    item.Value = 0
    item.Parent = leaderstats

    while wait(5) do --every 5 seconds saves data
        moneyData:SetAsync(plr.UserId..'-moneyData', dollar.Value)
        itemData:SetAsync(plr.UserId..'-itemData', item.Value)
    end

    local success, err = pcall(function()
        data = moneyData:GetAsync(plr.UserId..'-moneyData') or 0
    end)
    if success then
        dollar.Value = data
    else
        -- Failed to retrieve data
    end

    local success, err = pcall(function()
        data2 = itemData:GetAsync(plr.UserId..'-itemData') or 0
    end)
    if success then
        item.Value = data2
    else
        -- Failed to retrieve data2
    end
end)

Part Script

script.Parent.Parent.Part.Touched:Connect(function(touch)
    local parent = touch.Parent
    local humanoid = parent:FindFirstChildWhichIsA('Humanoid')
    if humanoid then
        local plr = game:GetService('Players'):GetPlayerFromCharacter(parent)
        local leaderstats = plr.leaderstats
        local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money')
        if moneyMaker then
            moneyMaker.Value = moneyMaker.Value + 1
        end
    end
end)

Also, if u dont understand, here is a link for datastores - https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/GetAsync

Ad
Log in to vote
0
Answered by
Hydrogyn 155
3 years ago

I believe I know the error in this script, you're setting the value of "points" 3 different times, but you only need to set it once.

Here's the fix:

Change line 41 to:

Minutes.Value = dataminutes

Change line 51 to:

Bricks.Value = databricks

have fun scripting, hydrogyn

Log in to vote
0
Answered by 3 years ago
Edited 3 years ago

I recommend saving it all in one table, this way you don't have to multiple setasyncs or update async

local StatsTable = {}
StatsTable.Money = Player.leaderstats.Money.Value
StatsTable.Items = Player.leaderstats.Items.Value
while true do
repeat
local Success, Error_ = pcall(function()
StatsDataStore:SetAsync(Player.Userid.."_Stats", StatsTable)
end)
wait(2)
until Success
wait(10)
end

I am pretty sure while wait() do is a bad idea, so just do a normal while true do is good with a coroutine on the while true do function for saving data, also, having a longer wait period on set asyncs is a good idea because you don't want to make to many requests in a short period of time. Using the pccall is a good idea because sometimes Datastores will error, and using a call can prevent it from breaking the code. https://devforum.roblox.com/t/avoiding-wait-and-why/244015

Answer this question