Data store script?

I basically want to save every item in the inventory, there could be any. Problem is, can’t figure out how to do nor what’s wrong with my script. Currently experiencing no errors:

 local ds = game:GetService("DataStoreService"):GetDataStore("Inventory")

game.Players.PlayerAdded:Connect(function(plr)
	local data = nil
	local success, errormsg = pcall(function()
		ds:GetAsync(plr.UserId)
	end)
	if data ~= nil then
		for i,v in pairs(plr.Inventory:GetChildren()) do
			if v:IsA("StringValue") then
				print(v.Value .. " is the value!" .. v.Name .. " is the name of this item!")
				v.Value = data
			end
		end
	end
end)
game.Players.PlayerRemoving:Connect(function(plr)
	local success, errormsg = pcall(function()
		for i,v in pairs(plr.Inventory:GetChildren()) do
			if v:IsA("StringValue") then
				ds:SetAsync(plr.Userid, v.Value)
			end
		end
	end)
end)


I’ve tested this in the game itself and Api services are activated, not sure what’s wrong.

2 Likes

Note: the script that creates the item in the inventory is perfectly fine.

1 Like

change to

local data = nil
local success, errormsg = pcall(function()
		data = ds:GetAsync(plr.UserId)
	end)
2 Likes

Same problem unfortunately occurs.

1 Like

Did you try testing it in a server? Like not studio, because sometimes the server shuts down before it saves, so there’s game:BindToClose() that makes sure before the server shuts down it will do x things, like saving data.

1 Like

I’ve tested in the game and even published my changes, no hope still, I’ll try using game:BindToClose() though.

1 Like

Maybe there’s an error because you put v.Value = data
But you didnt specify what part of data it’s gonna be, for example v.Value = data.Name, but i don’t know what’s your situation like what are you trying to save and how does it look like

1 Like

True, that could be a possible error due to the fact I’m doing value.Value, is there then an alternative way to save every data inside the inventory? I’m thinking inventory:GetChildren() but that also doesn’t have any of the specifics.

1 Like

before saving data, make a table and each value can be a value you will save, so when you get data you can type v.Value = data[1]…

1 Like

How would I know what data[1] is? Most importantly, how would I know how much is in the table? How would I even know what’s in the table? The inventory can get stuff added when the player buys something and also automatically when they join they’ll get a free item.

when you save a table for example

local saveTable = {
   player.leaderstats.Money.Value, -- Example
   player.leaderstats.Gems.Value 
}

print(saveTable[1]) -- Output is the value of money

In short, the order you save your data in, it will be like that when you gather it, i think this is better because it give you more accessibility:

local saveTable = []
for i,v in pairs(plr.Inventory:GetChildren()) do
	if v:IsA("StringValue") then
		table.insert(saveTable, v.Value)
	end
end

print(saveTable)
ds:SetAsync(plr.Userid, saveTable)

Make sure to add the “print(savetable)” so you can see in what order is the data gonna be saved.

But I also recommend a better way, make a private folder for every single player when they join, that folder is gonna have bool/string values of every single saveable item in the game, and whenever they acquire the item it changes the bool for example hasWeapon = true in the folder, and whenever the player leaves you wanna save every single one of the values from the folder, even if it’s false, so when the player joins you will go through every single bool/string value and give them data depending if it’s true/false/value. There’s a way to automate it but it takes some advanced scripting skills.

Already using a folder, will try the thing you suggested above though.

Really unsure if the printing is not working or the script itself isn’t working. It still doesn’t seem to work.

should be

data = ds:GetAsync(plr.UserId)

Already did that, didn’t work.

does each item in the inventory have a different name?

Yes, each item in the inventory has a different name.

1 Like
local ds = game:GetService("DataStoreService"):GetDataStore("Inventory")

local function load(p)
	local success, valueData = pcall(ds.GetAsync, ds, p.UserId)
	if success and valueData then
		for _, data_item in pairs(valueData) do 
			p['Inventory']:WaitForChild(data_item[1]).Value = data_item[2]
		end
	end
end
local function save(p)
	local data_to_save = {}
	for i,inventory_child in pairs(p.Inventory:GetChildren()) do 
		table.insert(data_to_save,{inventory_child.Name,inventory_child.Value})
	end
	local saved_successfully,failed_saving = pcall(ds.UpdateAsync, ds, p.UserId,function()
		return data_to_save
	end)
	if not saved_successfully then warn(failed_saving) else print('saved_inventory_data') end
end
game.Players.PlayerAdded:Connect(function(plr)
	load(plr)
end)
game.Players.PlayerRemoving:Connect(function(plr)
	save(plr)
end)
game:BindToClose(function()
	if game:GetService("RunService"):IsStudio() then
		wait(1)
	else
		for i, v in pairs(game.Players:GetPlayers()) do 
			save(v)
		end
	end
end)

try that
(i edited it twice, copy paste again)

1 Like

Just a question, how would I know if it saved or not?(after all, I’m dealing with a string value here)

i edited it the third time, copy paste it again.
If the data saves it should show in the output - saved_inventory_data

1 Like