Datastore unable to save dictionary?

So I created a datastore script to save the level and xp, and after doing so the dictionary variables are unsaved. Here are the code and the error.

game.Players.PlayerAdded:Connect(function(p)
	local e = script.lvg:Clone()
	e.Parent = p.PlayerGui
	local DataStoreService = game:GetService("DataStoreService")
	local experienceStore = DataStoreService:GetDataStore("lv")
	local success, currentExperience = pcall(function()
		return experienceStore:GetAsync(p.Name)
	end) 
	if success then
		e.Frame.xpv.Value = currentExperience["xp"]
		e.Frame.lvv.Value = currentExperience["lv"]
	end
end)

And

if p.Parent.Name=="Forest Goon" then
		if cooldown==false then
			cooldown = true
			p.Parent.Humanoid.Health = p.Parent.Humanoid.Health-math.random(33,88)
			local DataStoreService = game:GetService("DataStoreService")
			
			local experienceStore = DataStoreService:GetDataStore("lv")
			
			local success, currentExperience = pcall(function()
				return experienceStore:GetAsync(p.Name)
			end)
			
			if success then
				if currentExperience~=nil then
					local newt = {
						xp = 0,
						lv = 0,
					}
					if currentExperience.xp+5>=currentExperience.lv*50 then
						newt = {
							xp = 0,
							lv = currentExperience.lv+1,
						}
					else
						newt = {
							xp = currentExperience.xp+5,
							lv = currentExperience.lv
							}
					end
					experienceStore:SetAsync(game.Players[""..script.Parent.Parent.Parent.Name],newt)
					local t = "xp"
					local n = newt["xp"]
					game.Players[""..script.Parent.Parent.Parent.Name].PlayerGui.lvg.Frame.RemoteEvent:FireClient(game.Players[""..script.Parent.Parent.Parent.Name],t,n)
					local t = "lv"
					local n = newt["lv"]
					game.Players[""..script.Parent.Parent.Parent.Name].PlayerGui.lvg.Frame.RemoteEvent:FireClient(game.Players[""..script.Parent.Parent.Parent.Name],t,n)
					
				else
					local newt = {
						xp = 5,
						lv = 1,
					}
					experienceStore:SetAsync(game.Players[""..script.Parent.Parent.Parent.Name],newt)
					local t = "xp"
					local n = newt["xp"]
					game.Players[""..script.Parent.Parent.Parent.Name].PlayerGui.lvg.Frame.RemoteEvent:FireClient(game.Players[""..script.Parent.Parent.Parent.Name],t,n)
					local t = "lv"
					local n = newt["lv"]
					game.Players[""..script.Parent.Parent.Parent.Name].PlayerGui.lvg.Frame.RemoteEvent:FireClient(game.Players[""..script.Parent.Parent.Parent.Name],t,n)
				end
			end
			
			wait(.1)
			cooldown = false
		end
	end

image

The Issues

The error in the output you’re getting is caused by the returned data not yet existing.
You can fix this by doing something like:
currentExperience = currentExperience or {xp = 0, lv = 0}
before indexing it.

I believe this is the reason for the data not saving. You are trying to set the key to the player object itself, which won’t work. Setting a DataStore key to an object will cause the data to save to the key “Instance” instead.



Some Additional Advice

  1. I highly recommend you use player UserIds rather than player names as DataStore keys. If you use player names, their data will be lost when they change their name.

  2. You don’t need to concatenate the player’s name with an empty string.

  3. For getting the player from a character, you can use Players:GetPlayerFromCharacter instead of Players[character.Name].

  4. You don’t need to fetch the services and GlobalDataStores within the function. Do that when the script first runs.

  5. Judging by the fact that the cooldown gets set back to false after only 0.1 seconds, this could easily exhaust the DataStore.

2 Likes

How is [""…script.Parent.Parent.Parent.Name] an object? It returns a string and is not an instance.

The key for datastores isn’t the player itself, but the player name. image

That by itself returns a string. It becomes an object when you put game.Players before it. Doing this indexes the Players service and returns the first player object it finds.

You’re using GetAsync with the player name, but SetAsync with the player instance.

Ahhhh. I see where I went wrong here. It’s always the little things that affect the bigger picture. Thanks for the effort. image