Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why wont this pcall datastore save?

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)

7 comments

1

Can you edit your post and include the local script please?

0

Done.

0

You are trying to set something to an object not a string

0

The CashValue is an integer, sent from the LocalScript.

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

0

Wow, I feel like an idiot now, thank you so much haha.

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.

1 answer

✓ Accepted answer

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.

1 comment

0

Thanks, love the criticism, really helped me better the script.

This discussion is preserved as it was. New answers, comments, and votes are closed.