Datastore/Leaderboard Problem

I’ll get straight to the problem

So basically I was making a datastore and a leaderboard in separate scripts (for the datastore to save the leaderboard data) , but I didn’t know how, so here’s what I got

image

The problems :

  • Rank is showing as nil, whereas it is string , like “Beginner”
  • There are only 3 int values supposed to come under the leaderboard:
    rCoins , kills, rebirths, and their values,but the datastore script i’m using will
    only save ALL the values parented to the folder,so they might show sometime,and I don’t want that.

image

image

Data Store script code :

local DataStore = game:GetService("DataStoreService"):GetDataStore("CoinSaveService")

game.Players.PlayerAdded:Connect(function(player)
	local key = "player-"..player.UserId
	
	local savedValues = DataStore:GetAsync(key)
		
	local leaderstatsFolder = Instance.new("Folder", player)
	leaderstatsFolder.Name = "leaderstats"
	
	if(savedValues) then		
		for i,v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName, player.leaderstats)
			stat.Name = v.Name
		end
		
		for i,v in pairs(player.leaderstats:GetChildren()) do
			v.Value = savedValues[i]
		end
	else	 
		local save = {} 
		for i,v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName, player.leaderstats)
			stat.Name = v.Name
			table.insert(save, stat.Value)
		end
		DataStore:SetAsync(key, save)
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local key = "player-"..player.UserId
	
	local save = {}
	
	for i,v in pairs(player.leaderstats:GetChildren()) do
		table.insert(save, v.Value)
	end
	DataStore:SetAsync(key, save)
	
end)

and here is the code for the script parented to it :
if I use this script (below) then those values won’t be saved , whereas it is essential that they do,

--[[I have no idea whether i should use this or not,

because if I do, then if these values get changed, they won't be saved anywhere

    --]]

    local col = script.Parent.collected

    local tool = script.Parent.toolnum

    local Players = game:GetService("Players")

    local player = Players.LocalPlayer

    ---------

    col.Parent = player.leaderstats

    tool.Parent = player.leaderstats

Any help at all would be completely appreciated, thanks for your time and for trying to help me out

Did you make sure it was a string value?

I’d suggest doing them in the same script and see if it works

Doesn’t look like anything’s wrong, I suggest coding the script from scratch. This happens sometimes when the script becomes faulty because of ROBLOX Studio.

Can you show us the leaderstat script? Because I can’t find the instance where you created the Rank

lines 13 -18, in my code in my post,
i use the folder’s children , they’re parented to leaderstats, so when the game runs , the values show, or the IntValues atleast, the only one that’s string, i.e Rank
isn’t showing, the instance is already created, therefore there is no need for making one more, I basically did two things in one script, but not very well, as it seems.

if (savedValues) then		
		for i,v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName, player.leaderstats)
			stat.Name = v.Name
		end
		
		for i,v in pairs(player.leaderstats:GetChildren()) do
			v.Value = savedValues[i]

I don’t know then, because that looks like the start of the data stores

At the part where you unload the data, you loop through expecting the data to be in the same order as the leaderstats - this is probably the issue, it’s loading data for the wrong leaderstat.

I recommend when you save the data, to include the index as the name:

	local save = {}
	
	for _, v in pairs(player.leaderstats:GetChildren()) do
		save[v.Name] = v.Value
	end

Then when you unload it, you can use the index:

		for _, v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName)
			stat.Name = v.Name
                        if savedValues[v.Name] ~= nil then
                             stat.Value = savedValues[v.Name]
                        end
                        stat.Parent = player.leaderstats
		end

FYI: Using the 2nd argument of Instance.new is much slower than parenting it yourself, you can read more here:

1 Like

it explains the order, and double loop …but what seems to be wrong with doing this

local DataStore = game:GetService("DataStoreService"):GetDataStore("DataSaveService")

game.Players.PlayerAdded:Connect(function(player)
	local key = "player-"..player.UserId
	
	local savedValues = DataStore:GetAsync(key)
		
	local leaderstatsFolder = Instance.new("Folder", player)
	leaderstatsFolder.Name = "leaderstats"
	
	if(savedValues) then		
		for i,v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName, player.leaderstats)
			stat.Name = v.Name
		end
		
		for i,v in pairs(player.leaderstats:GetChildren()) do
			v.Value = savedValues[i]
		end
	else	 
		local save = {} 
		for i, v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName)
			stat.Name = v.Name
                        if savedValues[v.Name] ~= nil then
                             stat.Value = savedValues[v.Name]
                        end
                        stat.Parent = player.leaderstats
		
			table.insert(save, stat.Value)
		end
		DataStore:SetAsync(key, save)
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local key = "player-"..player.UserId
	local save = {}
	
	for i, v in pairs(player.leaderstats:GetChildren()) do
		save[v.Name] = v.Value
	end
		table.insert(save, v.Value)
	
	DataStore:SetAsync(key, save)
	
end)

The new version of the for loop was meant for if they have data, I fixed it up for you:

local DataStore = game:GetService("DataStoreService"):GetDataStore("DataSaveService")

game.Players.PlayerAdded:Connect(function(player)
	local key = "player-"..player.UserId
	
	local savedValues = DataStore:GetAsync(key)
		
	local leaderstatsFolder = Instance.new("Folder")
	leaderstatsFolder.Name = "leaderstats"
        leaderstatsFolder.Parent = player	

	if(savedValues) then		
		for i,v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName)
			stat.Name = v.Name
                        stat.Value = savedValues[v.Name] or v.Value
		end
	else	 
		local save = {} 
		for i, v in pairs(script.leaderstats:GetChildren()) do
			local stat = Instance.new(v.ClassName)
			stat.Name = v.Name
                        stat.Value = v.Value
                        stat.Parent = player.leaderstats
		
			save[v.Name] = v.Value
		end
		DataStore:SetAsync(key, save)
	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	local key = "player-"..player.UserId
	local save = {}
	
	for i, v in pairs(player.leaderstats:GetChildren()) do
		save[v.Name] = v.Value
	end
	
	DataStore:SetAsync(key, save)
	
end)

This may not be a total concern yet, put you should look into using pcalls for datastore functions as they can error.
You can read more here:

2 Likes