I am making a simple DataStore that saves you money in leaderstats. It isn’t saving for some reason but it is loading fine and I can’t work out why.
Here is the code:
Server Script in ServerScriptService:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("StatsSave")
local DefultData = {
Money = 100;
}
-- Load Data
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
local Money = Instance.new("IntValue")
Money.Name = "Money"
Money.Parent = leaderstats
local Data = DataStore:GetAsync(Player.UserId)
if Data then
Money.Value = Data
else
Money.Value = DefultData.Money
end
end)
-- Save Data
local function SaveData(Player)
local Money = Remotes.MoneySave:InvokeClient(Player)
DataStore:SetAsync(Player.UserId, Money)
end
game.Players.PlayerRemoving:Connect(SaveData)
LocalScript in StarterPlayerScripts:
local leaderstats = script.Parent.Parent:WaitForChild("leaderstats")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local function SendData()
return leaderstats.Money.Value
end
Remotes.MoneySave.OnClientInvoke = SendData
I have a RemoteFunction in ReplicatedStorage in a folder called Remotes and the RemoteFunction is called MoneySave.
Note:I have Studio API Services turned on and I get no errors.
I think SaveData won’t work because you’re waiting for the client to respond, but they’re already leaving the game (since you’re using PlayerRemoving and using InvokeClient).
Also a side note, I don’t think it’s a good idea to allow the client to send information to the server which it can manipulate.
Edit: You are using GetAsync and SetAsync correctly.
Yeah going on what someonedie said dont let the client send information back to the server and just find that information on the server, same with that the player is already leaving and all scripts mostly yield when a player leaves.
I have tried doing this now and it still doesn’t want to save:
local function SaveData(Player)
local Money = Player.leaderstats.Money.Value
DataStore:SetAsync(Player.UserId, Money)
end
game.Players.PlayerRemoving:Connect(SaveData)
local function SaveData(Player)
local Money = Player.leaderstats.Money.Value
DataStore:SetAsync(Player.UserId, Money)
end
game.Players.PlayerRemoving:Connect(SaveData)
I just done:
local function SaveData(Player)
DataStore:SetAsync(Player.UserId, 1000) -- The 1000 is the users money
end
game.Players.PlayerRemoving:Connect(SaveData)
local function SaveData(Player)
local Money = Player.leaderstats.Money.Value
DataStore:SetAsync("player_"..Player.UserId, Money)
end
game.Players.PlayerRemoving:Connect(SaveData)
Okay so this should work
It states on the wiki that the first piece of data has to be a string so just Player.UserId wouldn’t work. Also for loading data make sure you add in “player_” before the UserID thing
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("StatsSave")
local DefultData = {
Money = 100;
}
-- Load Data
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = Player
local Money = Instance.new("IntValue")
Money.Name = "Money"
Money.Parent = leaderstats
local Data = DataStore:GetAsync(tostring(Player.UserId))
if Data then
Money.Value = Data
else
Money.Value = DefultData.Money
end
end)
-- Save Data
local function SaveData(Player)
local Money = Player.leaderstats.Money.Value
DataStore:SetAsync(tostring(Player.UserId), Money)
end
game.Players.PlayerRemoving:Connect(SaveData)
Use “tostring()” on the key. The SetAsync and GetAsync (Along with UpdateAsync and IncrementAsync, etc) use strings for their keys. The value on the other hand can be a Variant of any type.