This DataStore script does not work

You can write your topic however you want, but you need to answer these questions:
My goal
I am trying to make a DataStore that can save items from the Inventory then when joining place them back into the inventory

My Issue
Whenever I try to get the table from the DataStore using Inv:GetAsync(key..plr.UserId) it ends up just returning as nil and not actually grabbing the values. I can tell it saves, due to the final print in the function that runs when a player is removed.

What I have tried so far
I have tried to use the GetAsync as a Variable of local GetSave = Inv:GetAsync which didn’t end up working. I have also printed all around the script to check if things are working properly, as well as Setting Async in a different way but this one seems to not output any errors.

When I tried saving with Inv:GetAsync(key..plr.UserId, tools) it’d output with the error of “Cannot store Array in data store. Data stores can only accept valid UTF-8 characters.”

The Code

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Inv = D_S:GetDataStore("Inventory")
local PlayerStorage = ReplicatedStorage:WaitForChild("PlayerStorage")

local key = "Demo_"

game:GetService("Players").PlayerAdded:connect(function(plr)
	
    local plrFolder = Instance.new("Folder")
    plrFolder.Name = plr.UserId
    plrFolder.Parent = PlayerStorage
    
    local inv = Instance.new("Folder")
    inv.Name = "Inventory"
    inv.Parent = plrFolder
	
	local toolFolder = game.ReplicatedStorage:WaitForChild("Weapons")
	
	local tools = Inv:GetAsync(key..plr.UserId)
	
	-- print(game:GetService("HttpService"):JSONEncode(tools))
	
	-- print(tools[1].." "..tools[2])
	
    if tools ~= nil then
		
        for i, v in pairs(tools) do
			
			print(tools[1])
			print(v)
			
            local tool = toolFolder:FindFirstChild(v):Clone()
			
            tool.Parent = inv
			
        end
		
	else
		
		tools = {"TempTool"}
		
		for i, v in pairs(tools) do
			
			print(v)
			print(tools[i])
			
			local tool = toolFolder:FindFirstChild(v):Clone()
			
			tool.Parent = inv
			
		end
		
    end
	
end)

game:GetService("Players").PlayerRemoving:connect(function(plr)
	
    local plrFolder = PlayerStorage:WaitForChild(plr.UserId)
    local inv = plrFolder:WaitForChild("Inventory")
    
    local tools = {}
	
    for i, v in pairs(inv:GetChildren()) do
	
        table.insert(tools, v.Name)
		
    end
    
	print(game:GetService("HttpService"):JSONEncode(tools))
	
    Inv:SetAsync(key..plr.UserId, game:GetService("HttpService"):JSONEncode(tools))
	
end)

Anything else

I’d like to know why it hasn’t been working and the way I can fix it, please and thank you.

Do not encode the table on save. Roblox will handle the table encoding on save and decode it for you on load. Just pass the table directly to SetAsync.

Oh that was the other saving I tried, and it said Cannot store Array in data store. Data stores can only accept valid UTF-8 characters.

1 Like

There is a few things wrong with this picture, the first one key,plr.UserId
and the second one being you try to grab this table twice.

Oh whoops I guess I left that Variable in whenever I tried something else hahah

Lmao, it’s all good, just thought I’d point that out.

1 Like

You know how I could fix it now?

The only real issue I can see, is that you’re Encoding the table, and then sending it to be encoded again by the actual datastore, where as you’re only doing one layer of decoding.

1 Like

Idk if it is Encoding if it’s saying that error and it has to be a string or something.

Give me one second, I’ll open studio really quick.

1 Like

Ok thank you for your assistance :smile:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Inv = game:GetService("DataStoreService"):GetDataStore("Inventory")
local PlayerStorage = ReplicatedStorage:WaitForChild("PlayerStorage")

local key = "Demo_"

game:GetService("Players").PlayerAdded:connect(function(plr)
	
    local plrFolder = Instance.new("Folder")
    plrFolder.Name = plr.UserId
    plrFolder.Parent = PlayerStorage
    
    local inv = Instance.new("Folder")
    inv.Name = "Inventory"
    inv.Parent = plrFolder
	
	local toolFolder = game.ReplicatedStorage:WaitForChild("Weapons")
	
	local success, tools = pcall(function() return Inv:GetAsync(key..plr.UserId) end)
	
	-- print(game:GetService("HttpService"):JSONEncode(tools))
	
	-- print(tools[1].." "..tools[2])
	
	if not success then
		warn("Couldn't load save")
	end
	
    if success and tools ~= nil then
		print("found")
		
		tools = game:GetService("HttpService"):JSONDecode(tools)
		
        for i, v in pairs(tools) do
				
            local tool = toolFolder:FindFirstChild(v)
			
			if tool then
            	tool:Clone().Parent = inv
			end
        end
		
	else
		
		tools = {"TempTool"}
		
		for i, v in pairs(tools) do
			
			local tool = toolFolder:FindFirstChild(v):Clone()
			
			tool.Parent = inv
			
		end
		
    end
	
end)

game:GetService("Players").PlayerRemoving:connect(function(plr)
	
    local plrFolder = PlayerStorage:WaitForChild(plr.UserId)
    local inv = plrFolder:WaitForChild("Inventory")
    
    local tools = {}
	
    for i, v in pairs(inv:GetChildren()) do
	
        table.insert(tools, v.Name)
		
    end
    
	
    Inv:SetAsync(key..plr.UserId, game:GetService("HttpService"):JSONEncode(tools))
	
end)

I ended up getting it to work like this.

1 Like

Alright, I am just going to look over it and alter my code to fit like that so I actually learn why. Thank you for your help I really appreciate it!

No problemo, good luck with development

1 Like