Hello,
I am currently making a game, I know the datastore works because I use it in all my games but for some reason it doesn’t in this one, in output it tells me that the data is getting loaded and saved.
this is the code, I know its messy:
game.Players.PlayerRemoving:connect(function(player)
local datastore = game:GetService(“DataStoreService”):GetDataStore(player.Name…“Stats”)
local statstorage = player:FindFirstChild(“leaderstats”):GetChildren()
game:BindToClose(function()
for i = 1, #statstorage do
datastore:SetAsync(statstorage[i].Name, statstorage[i].Value)
print("saved data number "…i)
end
print(“stats successfully saved”)
end)
end)
game.Players.PlayerAdded:connect(function(player)
local datastore = game:GetService(“DataStoreService”):GetDataStore(player.Name…“Stats”)
player:WaitForChild(“leaderstats”)
wait(1)
local stats = player:FindFirstChild(“leaderstats”):GetChildren()
for i = 1, #stats do
stats[i].Value = datastore:GetAsync(stats[i].Name)
print(“stats number “…i…” has been found”)
end
end)
Also, the “BindToClose” function is useless where it is and should be outside the “PlayerRemoving” function because “PlayerRemoving” do not run when a player get kicked for any reasons… “BindToClose” is there to save up data stats when a kick is hapenned.
First, you should place game.Players.PlayerAdded before game.Players.PlayerRemoving
Second, you should only get the datastore once, and not get a datastore for each player.
Third, instead of doing datastore:SetAsync() or datastore:GetAsync() for one object at a time, you can just use it for all of the objects. That means you should use a table.
Fourth, you need a key for the user to save the data. You also can’t add multiple values to save in SetAsync().
Fifth, and the most important- you can’t save objects. The solution to this is to just create the object using Instance.new() and parent it to the player. You can do this manually, or use a pairs loop.
Try using this code I made:
local datastore = game:GetService(“DataStoreService”):GetDataStore(“Stats”)
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local statstorage
local PlayerID = "Player_"..player.UserId
local Success, ErrorMessage = pcall(function()
statstorage = dataStore:GetAsync(PlayerID)
end)
if Success then
if statstorage then
print("Data successfully loaded")
for i,v in pairs(statstorage) do
local Loaded_Stat = string.split(v, ":")
local Loaded_Stat_Name = Loaded_Stat[1]
local Loaded_Stat_Value = Loaded_Stat[2]
local Loaded_Stat_ClassName = Loaded_Stat[3]
local Loaded_Stat_Object = Instance.new(Loaded_Stat_ClassName)
Loaded_Stat_Object.Name = Loaded_Stat_Name
Loaded_Stat_Object.Value = Loaded_Stat_Value
Loaded_Stat_Object.Parent = leaderstats
end
end
else
warn(ErrorMessage)
end
end)
local function OnPlayerLeaving(player)
local statstorage = {}
for i,v in pairs(player:FindFirstChild(“leaderstats”):GetChildren()) do
local stat = v.Name..":"..v.Value..":"..v.ClassName
table.insert(statstorage,stat)
end
local PlayerID = "Player_"..player.UserId
local Success,ErrorMessage = pcall(function()
dataStore:SetAsync(PlayerID,statstorage)
end)
if Success then
print("Data successfully saved")
else
warn(ErrorMessage)
end
end
game.Players.PlayerRemoving:connect(function(player)
OnPlayerLeaving(player)
end)
game:BindToClose(function()
for _, player in pairs(Players:GetPlayers()) do
OnPlayerLeaving(player)
end
end)
Note that I haven’t tested it so tell me if something doesn’t work or if I forgot to add something.
it has some errors, I will try to fix them myself, the script shown here above works fine because I use it in all of my games but for some reason it doesn’t in this game.
DSS = game:GetService("DataStoreService")
Str = DSS:GetDataStore("DataStore")
Sesh = {}
New = { -- Create Keys on what you want to The new Player to have, For Example
Level = 1,
Cash = 100,
EXP = 0,
Items = {}
}
game.Players.PlayerAdded:Connect(function(p)
local Success, Data = pcall(function() -- protected call
return Str:GetAsync("p_"..p.UserId) -- Gets Data
end)
if Success then -- if Accessed Data
if Data then -- if Data
Sesh[p.UserId] = Data -- sets Data
else -- if no Data
Sesh[p.UserId] = New -- sets new Data
end
else -- if Failed to Access Data
-- Something in case DataStores fail
end
end)
game.Players.PlayerRemoving:Connect(function(p)
local Attempts = 0 -- Attempts
local Success, Data
repeat -- loop
Success, Data = pcall(function()
Str:SetAsync("p_"..p.UserId, Sesh[p.UserId]) -- Sets Data
end)
task.wait(2)
Attempts += 1 -- Adds Attempt
until Success and Attempts > 3
if not Success then -- if didnt succeed
warn("Failed to Save Data for", p.Name)
end
Sesh[p.UserId] = nil
end)
I don’t really know anymore, this is a script I already use for 4 years so I don’t know what I was thinking back then, I was probably happy that it worked lol
one possibility is that there are too many SetAsync() requests due to many values.
You’re basically doing datastore:SetAsync()i times. And also you should look at the format for datastore:SetAsync() in this image:
They key and value is necessary so you don’t have to add anything after the value. Remember that you can’t use a comma to add multiple values in one segment of the format.
One solution is to cooperate with me and tell me where you get the errors so I could fix them.
Another solution is to modify my code if possible.
You should maybe use AlvinBlox’s code if you can’t find any other solution.
I removed 7 stats to see if it would save with the datastores, I tried my own script and it didn’t work and then I tried your script again and it doesn’t work too but your script gets all leaderstats back while the leaderstats are removed, even with less stats its not working.
Try this, this is a datastore with leaderstats that have numbers, so it might help you.
local statstore = DataStoreService:GetDataStore("leaderstatsdata")
game.Players.PlayerAdded:Connect(function(player)
player.leaderstats.Gold.Changed:Connect(function(Gold)
statstore:SetAsync(player.UserId, Gold.Value)
end)
local Gold = statstore:GetAsync(player.UserId)
if Gold then
player.leaderstats.Gold.Value = Gold
else
print("Set a number.")
end
end)
try this, it should work.
i’ve listed inside the snippet what the script does so you can read it and not be confused
local plrData = game:GetService("DataStoreService"):GetDataStore("PlayerData") -- the datastore to get data from
game.Players.PlayerAdded:Connect(function(player) -- connection for when player is added
local data = plrData:GetAsync(player.UserId.."_Data") -- get data
if data == nil then warn("No data was found for player "..player.Name) return end -- if the player has no data, lets do nothing so the script doesnt error
for i,v in pairs(player:WaitForChild("leaderstats"):GetChildren()) do -- for all of the player's stats, lets set them
if data[v.Name] ~= nil then -- we'll only set data if its actually found in the data
v.Value = data[v.Name] -- setting data
print("Setting data for "..v.Name) -- success print
else
print("No data was found for "..v.Name) -- error print
end
end
end)
game.Players.PlayerRemoving:Connect(function(player) -- conntection for player disconnect
local newData = {} -- we're going to overwrite the current data with new
for i,v in pairs(player:WaitForChild("leaderstats"):GetChildren()) do
newData[v.Name] = v.Value -- set it inside the table
print("Saving data for "..v.Name) -- success
end
plrData:SetAsync(player.UserId.."_Data", newData) -- set the table for their data
warn("Successfully saved data")
end)