Hello, so I’ve been trying to save Cash in my game for the past 2 days and I can just not figure out why it’s not working. This is my code:
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Cash = Instance.new("IntValue")
Cash.Name = "Cash"
Cash.Parent = leaderstats
local playerUserId = "Player_"..player.UserId
local data
local success, errormessage = pcall(function()
data = myDataStore:GetAsync(playerUserId)
end)
if success then
Cash.Value = data
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId
local data = player.leaderstats.Cash.Value
local success, errormessage = pcall(function()
myDataStore:SetAsync(playerUserId, data)
end)
if success then
print("data loaded")
else
print("error occur")
end
end)
Any help would be appreciated, thank you for reading.
Okay, I think the issue is that .PlayerRemoved gets fired but SetAsync does not complete quickly enough. This can be fixed by using BindToClose as you are able to save the data before the server shuts down completely.
It saves the amount that I give the player, but it doesn’t save the new amount when a player buys something. Example: I give the player 1000 cash, they rejoin and they still have 1,000 cash. They buy something from the in-game shop for 100 cash. Their cash goes to 900. They rejoin and then their cash is 1,000 again.
New script with the BindToClose:
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Cash = Instance.new("IntValue")
Cash.Name = "Cash"
Cash.Parent = leaderstats
local playerUserId = "Player_"..player.UserId
local data
local success, errormessage = pcall(function()
data = myDataStore:GetAsync(playerUserId)
end)
if success then
Cash.Value = data
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId
local data = player.leaderstats.Cash.Value
local success, errormessage = pcall(function()
myDataStore:SetAsync(playerUserId, data)
end)
if success then
print("data loaded")
else
print("error occur")
end
end)
game:BindToClose(function()
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
if RunService:IsStudio() then
return
end
print("saving player data")
local players = Players:GetPlayers()
for _, player in pairs(players) do
local userId = player.UserId
local data = myDataStore[userId]
if data then
local success, result = pcall(function()
myDataStore:SetAsync(userId, data)
end)
if not success then
warn(result)
end
end
end
print("completed saving player data")
end)
That wouldn’t make a difference as you would be getting the current data and not the updated one. Since I assume you want to be storing their cash you can do something like this:
I saw you asking for help in HD, this should work:
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local DefaultAmount = 200
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Cash = Instance.new("IntValue")
Cash.Name = "Cash"
Cash.Parent = leaderstats
local playerUserId = "Player_"..player.UserId
local data
local success,data = pcall(function()
return myDataStore:GetAsync(playerUserId)
end)
print(data)
if (success and data) then
Cash.Value = data
elseif (success and not data) then
Cash.Value = DefaultAmount
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerUserId = "Player_"..player.UserId
local data = player.leaderstats.Cash.Value
local success, errormessage = pcall(function()
myDataStore:SetAsync(playerUserId, data)
end)
if success then
print("data loaded")
else
print("error occur")
end
end)
Make sure you are using a server script for the datastore and that any changes to the Cash.Value are made on the server or the datastore won’t be able to save that data I added a default amount of 200 so you can make sure it’s actually saving by seeing what print(data) prints.
I’m sure this will solve your queries. This method is a very short method. You can compare your code with this and in case it errors, feel free to contact me. If I helped, mark as the solution I’ll also advise you to change the topic name.
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local playersLeft = 0
game.Players.PlayerAdded:Connect(function(player)
playersLeft += 1
local leaderstats = Instance.new("Folder",player)
leaderstats.Name = "leaderstats"
local Cash = Instance.new("IntValue",leaderstats)
Cash.Name = "Cash"
pcall(function()
Cash.Value= myDataStore:GetAsync(player.UserId.."-Cash") or 0
end)
end)
local BindableEvent = Instance.new("BindableEvent")
game.Players.PlayerRemoving:Connect(function(player)
pcall(function()
myDataStore:SetAsync(player.UserId.."-Cash", player.leaderstats.Cash.Value)
end)
playersLeft -= 1
BindableEvent:Fire()
end)
game:BindToClose(function()
while playersLeft > 0 do
BindableEvent.Event:Wait()
end
end)
I looked into the problem further and managed to solve it. When the BindToClose handler gets called, GetPlayers might return no players. To fix this we have to store all players who join in a table, we of course remove them once their data is saved.
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local players = {}
local function GetData(player)
local playerUserId = "Player_"..player.UserId
local data
local success, err = pcall(function()
data = myDataStore:GetAsync(playerUserId)
end)
if (not success) then
warn(err)
end
print("Got data", playerUserId, data)
return success and data or 0
end
local function SaveData(player)
local playerUserId = "Player_" .. player.UserId
local data = player.leaderstats.Cash.Value
print("Saving", playerUserId, data)
local success, result = pcall(function()
myDataStore:SetAsync(playerUserId, data)
end)
if not success then
warn(result)
end
print("Saved data", playerUserId)
return success
end
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Cash = Instance.new("IntValue")
Cash.Name = "Cash"
Cash.Parent = leaderstats
Cash.Value = GetData(player)
players[player] = player
end)
game.Players.PlayerRemoving:Connect(function(player)
-- If we are in studio let BindToClose save the data
local RunService = game:GetService("RunService")
if (RunService:IsStudio()) then
return
end
players[player] = nil
SaveData(player)
end)
game:BindToClose(function()
local Players = game:GetService("Players")
for _, player in pairs(players) do
SaveData(player)
players[player] = nil
end
print("completed saving player data")
end)