Datastore Not Working

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)

1 Like

Did you enabled Api services on your game ?

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.

1 Like

I have API Services already enabled yes,
I am gonna place “BindToClose” before the “PlayerRemoving”.

1 Like

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.

1 Like

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.

1 Like

Did you create the leaderstats using Instance.new() when the player is added (in your current script)?

1 Like

I use Instance.new(“IntValue”) for leaderstats

1 Like

Do you mean for the values inside leaderstats?

1 Like

This is a bit of a weird way of doing it:

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)

If you want to add a Value, you can do:

Value.Value = Sesh[p.UserId].Example

and to Change, you can do:

Sesh[p.UserId].Example = Value.Value

(woops accidental reply)

1 Like

which values?
this is the script I use:

game.Players.PlayerAdded:connect(function(player)
local leaderstats = Instance.new(“Model”)
leaderstats.Name = “leaderstats”
leaderstats.Parent = player

local money = Instance.new("IntValue") 
money.Name = "YourStat" 
money.Parent = leaderstats 

end)

1 Like

Oh… Would have been more understandable if you sent the full code :face_exhaling:

why is leaderstats a model?

1 Like

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

1 Like

Can you send the full script using ``` please?

1 Like

this is the full script:

game.Players.PlayerAdded:connect(function(player)
local leaderstats = Instance.new(“Model”)
leaderstats.Name = “leaderstats”
leaderstats.Parent = player

local money = Instance.new(“IntValue”) 
money.Name = “Clicks” 
money.Parent = leaderstats 
local money = Instance.new(“IntValue”) 
money.Name = “Humans” 
money.Parent = leaderstats 
local money = Instance.new(“IntValue”) 
money.Name = “ClickLevel” 
money.Parent = leaderstats 
local money = Instance.new(“IntValue”) 
money.Name = “HumanLevel” 
money.Parent = leaderstats 
local money = Instance.new(“IntValue”) 
money.Name = “HouseholdLevel” 
money.Parent = leaderstats
local money = Instance.new(“IntValue”) 
money.Name = “CityLevel” 
money.Parent = leaderstats
local money = Instance.new(“IntValue”) 
money.Name = “StateLevel” 
money.Parent = leaderstats
local money = Instance.new(“IntValue”) 
money.Name = “CountryLevel” 
money.Parent = leaderstats
local money = Instance.new(“IntValue”) 
money.Name = “ContinentLevel” 
money.Parent = leaderstats
local money = Instance.new(“IntValue”) 
money.Name = “WorldLevel”
money.Parent = leaderstats

end)

1 Like

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.

1 Like

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.

1 Like

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)

This doesn’t work either, I am going to try if datastores work if I use a working datastore experience.

1 Like

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)
1 Like

This one also doesn’t work for some reason.

1 Like