Datastore not saving tools

Im trying to make a system that saves the players tools by making a objectvalue in a folder in the player but the tools dont work it doesnt make a object value at all

Explorer:
image

Script:

local DataStoreService = game:GetService("DataStoreService")
local PlayerCashStore = DataStoreService:GetDataStore("Dabloons")
local PlayerToolStore = DataStoreService:GetDataStore("Tools")
local tooldata = nil
function savedata(player) 
	local success, err = pcall(function()
		local tosave = {}
		for i_,v in pairs(player.tooldata:GetChildren()) do
		table.insert(tosave,v.Name)	
		end
		PlayerCashStore:SetAsync(player.UserId, player.leaderstats.Dabloons.Value,tosave)
	end)
end

game.Players.PlayerRemoving:Connect(function(player)
	savedata(player)
end)

game:BindToClose(function()
	for i, player in pairs(game.Players:GetPlayers()) do
		savedata(player)
	end
end)


game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local inv = Instance.new("Folder")
	inv.Name = "tooldata"
	inv.Parent = player	
	tooldata = inv

	local Cash = Instance.new("IntValue")
	Cash.Name = "Dabloons"
	Cash.Parent = leaderstats
	Cash.Value = PlayerCashStore:GetAsync(player.UserId) or 0
	
	if PlayerToolStore:GetAsync(player) then
		for i_,v in pairs(PlayerToolStore:GetAsync(player))	do
			local inst = Instance.new("ObjectValue")
			inst.Name = v.Name
			inst.Parent = inv	
			if game.ServerStorage.ShopProducts:FindFirstChild(v.Name) then
				game.ServerStorage.ShopProducts:FindFirstChild(v.Name):Clone().Parent = player.Backpack
			end
		end
	end
	
	while wait(30) do
		if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 678756566) then
			Cash.Value = Cash.Value + 10 * 3
		else
			Cash.Value = Cash.Value + 10 		
		end
	end
end)
1 Like

Correct me if I’m wrong, but SetAsync() only takes two parameters: the save key, and one piece of data to store. If you want to save all data into one store, try using a dictionary.

local toolsToSave = {}
for _, tool in ipairs(player.tooldata:GetChildren()) do
    table.insert(toolsToSave, tool.Name)
end

local toSave = {
    ["Dabloons"] = player.leaderstats.Dabloons.Value,
    ["Tools"] = toolsToSave
}
--might wanna change this DataStore name if it's not only going to hold currency
PlayerCashStore:SetAsync(player.UserId, toSave)

Then, when unpacking, you can get the data from the store and navigate via key.

local playerData = nil --imagine this is the save data
player.leaderstats.Dabloons.Value = playerData.Dabloons
for _, tool in ipairs(playerData.Tools) do
    --do stuff with each saved tool name
end

Also, try to avoid using pairs() unless you absolutely must - I’m pretty sure ipairs() iterates faster anyway.

When to use pairs():

  • If you have a dictionary with non-numerical keys

When to use ipairs():

  • An array with numerical keys

Most functions, including GetChildren() and GetDescendants(), return arrays with numerical keys.

i tried your code but it still doesnt do anything!

When you say it “doesn’t do anything”, what do you mean? You’d need to adapt this to unpack data correctly, etc. Are there any errors? I need some more information to help further.

1 Like

0 errors i dont get my tools at all

1 Like

I’m assuming that’s with the loading code. Can you send the full script you use to load and save?

1 Like

i did already at my first message

1 Like

This line.

  1. You’re trying to send an instance as a key
  2. No pcall() is being used to catch errors

Essentially, you’re saving with one key, and loading with an instance.
I also noticed you are using two different DataStores, one for tools, and one for cash, even though my code wrote it all to one store.

Try this in your data unpacking:

local playerData
local success, err = pcall(function()
    playerData = PlayerCashStore:GetAsync(player.UserId) --my code saved both under one DataStore
end)

if success and playerData then
    Cash.Value = playerData.Dabloons
    for _, tool in ipairs(playerData.Tools) do
        --do stuff to load each tool here
    end
end

i get error: attempt to index number with ‘Dabloons’

Are you 100% sure you are saving using my code and loading using my code, saving to the exact same DataStore? If yes, it might be because before any of this code was implemented, you already had a number saved in the PlayerCashStore DataStore. Try running this line in the command bar (NOT during testing) and let me know if anything else happens.

game:GetService("DataStoreService"):GetDataStore("PlayerCashStore"):RemoveAsync(game.Players.LocalPlayer.UserId)

nothing happened at all and the tool system doesnt work still im sure i copied your code fully

also the full code i have right now is:

local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")

function savedata(player) 
	local success, err = pcall(function()
		local toolsToSave = {}
		for _, tool in ipairs(player.tooldata:GetChildren()) do
			table.insert(toolsToSave, tool.Name)
		end
		local toSave = {
			["Dabloons"] = player.leaderstats.Dabloons.Value,
			["Tools"] = toolsToSave
		}
		PlayerData:SetAsync("userkey_" .. player.UserId,toSave)
	end)
end

game.Players.PlayerRemoving:Connect(function(player)
	savedata(player)
end)

game:BindToClose(function()
	for i, player in ipairs(game.Players:GetPlayers()) do
		savedata(player)
	end
end)


game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local inv = Instance.new("Folder")
	inv.Name = "tooldata"
	inv.Parent = player	

	local Cash = Instance.new("IntValue")
	Cash.Name = "Dabloons"
	Cash.Parent = leaderstats
	Cash.Value = PlayerData:GetAsync(player.UserId) or 0
	
	local playerData
	local success, err = pcall(function()
		playerData = PlayerData:GetAsync(player.UserId) --my code saved both under one DataStore
	end)
	if success and playerData then
		Cash.Value = playerData.Dabloons
		for _, tool in ipairs(playerData.Tools) do
			local inst = Instance.new("ObjectValue")
			inst.Name = tool.Name
			inst.Parent = inv	
			if game.ServerStorage.ShopProducts:FindFirstChild(tool.Name) then
				game.ServerStorage.ShopProducts:FindFirstChild(tool.Name):Clone().Parent = player.Backpack
			end
		end
	end
	while wait(30) do
		if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, 678756566) then
			Cash.Value = Cash.Value + 10 * 3
		else
			Cash.Value = Cash.Value + 10 		
		end
	end
end)

You’re using the wrong key to load data - it’s different to the one you’re using to save.
playerData = PlayerData:GetAsync("userkey_"..player.UserId)
This might not be the only issue, I’m unpicking these one at a time.

Also, wrap UserOwnsGamepassAsync() in a pcall().

did that but i still dont get the tool

add a print() statement in here and let me know if it outputs. Also, add a print() statement in the loop that prints the tool’s name.

i think we are getting somewhere
image

also where it gives the tool doesnt print

The tools saved are already in a string - don’t do tool.Name, just do tool

1 Like

YES that fixed it! that tiny of a change too!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.