Data script doesn't load tools

I’m giving you scenarios so I can better understand what your issue is. It’s not very clear in your post. How do you know your script isn’t loading tools? Where are you seeing what’s being loaded? After which point is it supposed to be saved? What are your errors? What have you already tried to fix it?

You should include all of this and more in your initial post.

The error is from a plugin, don’t worry about that.

Is Studio’s access to API services enabled? It should be in your game settings.

Yes it is, and I’m not getting any errors.

Okay, two things:

Remove the data =. I don’t think it should make a difference, but best to do it anyway.

You’re setting a completely new Tools table that’s empty. When you save this, it saves that empty table that you’ve initialized.

I’m still looking at the tokens issue. Let me know if there’s any change with the tools.

Your tokens not saving may be a separate issue. Are you changing this value on the server or the client? Can you post the script?

Sorry, I went to go eat.

It’s a server script in serverscriptservice. Here’s the code.

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Data")

local function GenerateUID(player)
	return "UID_"..player.UserId
end

function onPlayerAdded(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local tokens = Instance.new("IntValue")
	tokens.Name = "Tokens"
	tokens.Parent = leaderstats
	
	
	local data
	local key = GenerateUID(player)
	
	local success, err = pcall(function()
		data = DS:GetAsync(key)
	end)
	if not success then
		player:Kick("\nDataHandler\n\nCouldn't fetch data!")
	else
		print("Successfully got data")
		for i,v in pairs(data.Tools) do
			print(v)
			if game.ReplicatedStorage.Tools:FindFirstChild(v) then
				local clone = game.ReplicatedStorage.Tools[v]:Clone()
				clone.Parent = player.Backpack
				clone.Parent = player.StarterGear
			end
		end
	end
end

function onPlayerRemoving(player)
	local data = {
		Tokens = player.leaderstats.Tokens.Value,
		Tools = {
			--starter sword
		}
	}
	local key = GenerateUID(player)

	local success, err = pcall(function()
		DS:SetAsync(key, data)
	end)
	if not success then
		warn("Error while saving data: "..err)
	else
		print("Successfully saved data")
	end
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoving)

Then how do I save the table instead of resetting it?

I fixed the tokens not loading. Just had to add this line.

tokens.Value = data.Tokens

You need to either store some sort of global or shared table, or just Instance:GetChildren() the player’s folder of tools. You definitely should not use the actual tools that the player will be using as the reference, though. You could save the table every time the player makes a purchase.

Anything along those lines.

Here’s my new data script, still not loading.

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Data")

local function GenerateUID(player)
	return "UID_"..player.UserId
end

function onPlayerAdded(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local tokens = Instance.new("IntValue")
	tokens.Name = "Tokens"
	tokens.Parent = leaderstats
	
	local folder = Instance.new("Folder")
	folder.Name = player.Name
	folder.Parent = game.ReplicatedStorage.PlayerTools
	
	local data
	local key = GenerateUID(player)
	
	local success, err = pcall(function()
		data = DS:GetAsync(key)
	end)
	if not success then
		player:Kick("\nDataHandler\n\nCouldn't fetch data!")
	else
		tokens.Value = data.Tokens
		print("Successfully got data")
		for i,v in pairs(data.Tools) do
			print(v)
			if game.ReplicatedStorage.Tools:FindFirstChild(v) then
				local clone = game.ReplicatedStorage.Tools[v]:Clone()
				clone.Parent = player.Backpack
				clone.Parent = player.StarterGear
			end
		end
	end
end

function onPlayerRemoving(player)
	local data = {
		Tokens = player.leaderstats.Tokens.Value,
		Tools = game.ReplicatedStorage.PlayerTools[player.Name]:GetChildren()
	}
	print(data.Tools)
	local key = GenerateUID(player)

	local success, err = pcall(function()
		DS:SetAsync(key, data)
	end)
	if not success then
		warn("Error while saving data: "..err)
	else
		print("Successfully saved data")
	end
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoving)

Your tokens are loading though, correct?

I miscommunicated. You can’t save instances to a datastore. If you’re going to go the instance route, you need to be storing string values of some sort, and then loading the object that corresponds to that value.

I highly suggest doing the alternative of referencing a table of stored strings that will be used to fetch the player’s tools, though.

1 Like

Yes, but not the tools.

So I should save the names instead?

For my games, I create a table for each player that keeps their player info in _G. Only use that if you’re comfortable with it, though. Many people will tell you not to use it, because you can easily overwrite it if you’re not careful. Otherwise, you need to find some other way to share the table between scripts. Saving after the player purchases an item, and then loading that table and saving again after they leave would work, but it’s less flexible. There are many ways to do this, but they all have their disadvantages, unfortunately.

That is an option, yes. You should consider your alternatives too, though.

Would this work?

for _,v in pairs(game.ReplicatedStorage.PlayerTools[player.Name]:GetChildren()) do
	table.insert(data.Tools, v.Name)
end

I think so. Try it out. There may be another option too.

I, personally, never really liked the idea of using instances for this sort of thing, but other people do it. It’s a lot easier, but it’s also messy in my opinion. I just wanted to give you every option I could think of.

Edit: I will say, though, I recommend keeping that folder in each player’s Player object. You won’t have to worry about removing it after they leave, and you certainly don’t want every player’s tools being replicated to each client.

The tools are saving, but they aren’t loading.

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("Data")

local function GenerateUID(player)
	return "UID_"..player.UserId
end

function onPlayerAdded(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local tokens = Instance.new("IntValue")
	tokens.Name = "Tokens"
	tokens.Parent = leaderstats
	
	local folder = Instance.new("Folder")
	folder.Name = "Tools"
	folder.Parent = player
	
	local data
	local key = GenerateUID(player)
	
	local success, err = pcall(function()
		data = DS:GetAsync(key)
	end)
	if success then
		tokens.Value = data.Tokens
		print("Successfully got data")
		print(data.Tools)
		for i,v in pairs(data.Tools) do
			print(v)
			if game.ReplicatedStorage.Tools:FindFirstChild(v) then
				local clone = game.ReplicatedStorage.Tools:FindFirstChild(v):Clone()
				print(clone)
				clone.Parent = player.Backpack
				clone.Parent = player.StarterGear
				clone.Parent = player.Tools
			end
		end
	else
		player:Kick("\nDataHandler\n\nCouldn't fetch data!")
	end
end

function onPlayerRemoving(player)
	local data = {
		Tokens = player.leaderstats.Tokens.Value,
		Tools = {}
	}
	
	for _,v in pairs(player.Tools:GetChildren()) do
		table.insert(data.Tools, v.Name)
		print(v)
	end
	local key = GenerateUID(player)

	local success, err = pcall(function()
		DS:SetAsync(key, data)
	end)
	if success then
		print("Successfully saved data")
	else
		warn("Error while saving data: "..err)
	end
end

game.Players.PlayerAdded:Connect(onPlayerAdded)
game.Players.PlayerRemoving:Connect(onPlayerRemoving)

Tell me how you’re using StarterGear and why it’s necessary in your game.

In the mean time, try replacing lines 34-38 with the following code:

local tool = game.ReplicatedStorage.Tools:FindFirstChild(v)
print(tool)
			
local clone = tool:Clone()
clone.Parent = player.Backpack
			
local otherClone = tool:Clone()
otherClone.Parent = player.StarterGear -- ???
			
local instVal = Instance.new("StringValue")
instVal.Name = tool.Name
instVal.Parent = player.Tools