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

Why wont this pcall datastore save?

Asked by
Zeluxis 100
5 years ago
Edited 5 years ago

Hi,

I am creating a currency system where a localscript detects when the value has changed and fires a RemoteEvent. After this, the script in ServerScriptService then should save it to datastores.

It prints no errors however wont work.

Can I have some help?

Server Script (ServerScriptService):

local DataStore=game:GetService("DataStoreService")
local CashStore=DataStore:GetDataStore("Currency")
local UpdateNeeded=game.ReplicatedStorage.Events.CashUpdateNeeded

UpdateNeeded.OnServerEvent:Connect(function(plr, CashValue)
    local Success, err=pcall(function()
        CashStore:SetAsync(plr, CashValue)
    end)
    if not Success then
        print(err)
    end
end)

Local Script (StarterPlayerScripts):

local DataValues=game.Players.LocalPlayer:WaitForChild("DataValues")

DataValues.Cash.Changed:connect(function()
    game.ReplicatedStorage.Events.CashUpdateNeeded:FireServer(game.Players.LocalPlayer.DataValues.Cash.Value)
end)
1
Can you edit your post and include the local script please? LawlR 182 — 5y
0
Done. Zeluxis 100 — 5y
0
You are trying to set something to an object not a string Kikitob 105 — 5y
0
The CashValue is an integer, sent from the LocalScript. Zeluxis 100 — 5y
View all comments (3 more)
1
You need a key. Currently, you're setting the key as a Player instance, which is wrong. https://developer.roblox.com/api-reference/function/GlobalDataStore/SetAsync LawlR 182 — 5y
0
Wow, I feel like an idiot now, thank you so much haha. Zeluxis 100 — 5y
0
Glad to help. Be sure to use the exact same key when you're loading the player's data. It's recommended to have the player's UserId in the key. LawlR 182 — 5y

1 answer

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

There are a lot of things that need to be changed in this code. The most critical one being you are asking the client to send how much cash they have to save. ?????????

The second thing which needs to be changed is that the player should never decide when to save their data. This is a job solely for the server, yes they can ask the server to save their data but the server should decide if it should save the data. This also means that you should never save data when you have no control over how many requests are made. Another common error is to save player data in a Changed event.

Lastly SetAsync needs a string key and is commonly a prefix with the players user id to make sure the key is unique.

local keys = "usr_" .. tostring(player.UserId)

On the more posative side you have used pcall to catch any potentual errors while saving data but you would still need to retry this until it runs successfully or you stop the request after 3 failed attempts.

Note that you also need to use pcall when getting the data if you have not already done so.

In most cases you would simply save data when the player leaves the game or at key points in the game that you program.

Example only to show how it a save/load can be setup.

local DataStore=game:GetService("DataStoreService")
local CashStore=DataStore:GetDataStore("Currency")

local plrDataList = {}
local prefix = "usr_"

local function getData(key)
    local success, result = pcall(function()
        return CashStore:GetAsync(key)
    end)

    if success then
        return result 
    else
        warn("Data store get request failed for key ", key)
        warn(result)
        -- your retry code ect...
    end
end

local function saveData(key, data)
    local success, result = pcall(function()
        CashStore:SetAsync(key, data)
    end)

    if success then
        print("saved data for key", key)
        return true
    else
        warn("Data store save request failed for key ", key)
        warn(result)
        -- your retry code ect...
    end
end

game.Players.PlayerAdded:Connect(function(plr)
    plrDataList[plr.UserId] = getData(prefix .. tostring(plr.UserId)) or 0 -- gets the player data or sets to 0

    print("Player data is", plrDataList[plr.UserId] )
end)


game.Players.PlayerRemoving:Connect(function(plr)
    saveData(prefix .. tostring(plr.UserId), plrDataList[plr.UserId])
    plrDataList[plr.UserId] = nil -- remove data from table
end)

-- you should also save data on server close
-- Roblox does not fire PlayerRemoving unpon server shutdown
game:BindToClose(function()
    for i, v in pairs(plrDataList) do
        spawn(function()
            saveData(i, v) -- spawn a theread for each player data save
        end)
    end
end)

This is only and example and is not fully suited for an active game as there is no retry attempts.

Hope this helps.

0
Thanks, love the criticism, really helped me better the script. Zeluxis 100 — 5y
Ad

Answer this question