Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Why is this code having trouble when I store more than one leaderstat?

I was following a tutorial from AlvinBlox, because I'm relatively new to RBX Lua scripting, on how to DataStore leaderstats. I couldn't really find anything on Youtube that stored multiple leaderstats and worked for me, so I tried to common-sense my way out of the problem. Turns out this doesn't work, because even though everything prints out success it doesn't actually load anything in. If anyone could fix up my code and/or tell me why it doesn't work would be greatly appreciated.

local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
local myDataStore2 = DataStoreService:GetDataStore("myDataStore2")
local myDataStore3 = DataStoreService:GetDataStore("myDataStore3")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Points = Instance.new("IntValue")
	Points.Name = "LagPoints"
	Points.Parent = leaderstats
	
	local Minutes = Instance.new("IntValue")
	Minutes.Name = "Minutes"
	Minutes.Parent = leaderstats
	
	local Bricks = Instance.new("IntValue")
	Bricks.Name = "Bricks"
	Bricks.Parent = leaderstats
	
	local datapoints
	local dataminutes
	local databricks
	
	local success, errormessage = pcall(function()
		datapoints = myDataStore:GetAsync(player.UserId.."-points")
	end)
	if success then
		Points.Value = datapoints
		print("Data succesfully loaded your LagPoints.")
	else
		print("There was an error whilst getting your data for LagPoints.")
	end
	
	local success, errormessage = pcall(function()
		dataminutes = myDataStore2:GetAsync(player.UserId.."-mins")
	end)
	if success then
		Points.Value = dataminutes
		print("Data succesfully loaded your Minutes in Lag-Mode.")
	else
		print("There was an error whilst getting your data for Minutes.")
	end
	
		local success, errormessage = pcall(function()
		datapoints = myDataStore3:GetAsync(player.UserId.."-bricks")
	end)
	if success then
		Points.Value = databricks
		print("Data succesfully loaded your Bricks Spawned.")
	else
		print("There was an error whilst getting your data for Bricks.")
	end

end)

game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		myDataStore:SetAsync(player.UserId.."-points",player.leaderstats.LagPoints.Value)
	end)
	if success then
		print(player.Name.."'s Data Saved Succesfully.")
	else
		print("There was an error saving "..player.Name.."'s data!")
		warn(errormessage)
	end
	
	local success, errormessage = pcall(function()
		myDataStore2:SetAsync(player.UserId.."-mins",player.leaderstats.Minutes.Value)
	end)
	if success then
		print(player.Name.."'s Data Saved Succesfully.")
	else
		print("There was an error saving "..player.Name.."'s data!")
		warn(errormessage)
	end
	
	local success, errormessage = pcall(function()
		myDataStore3:SetAsync(player.UserId.."-bricks",player.leaderstats.Bricks.Value)
	end)
	if success then
		print(player.Name.."'s Data Saved Succesfully.")
	else
		print("There was an error saving "..player.Name.."'s data!")
		warn(errormessage)
	end
end)

3 answers

Well in order to make a fully functioning leaderboard, here is my approach.

Setting the leaderboard

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

	local dollar = Instance.new('IntValue')
	dollar.Name = 'Money'
	dollar.Value = 0
	dollar.Parent = leaderstats
	
	local item = Instance.new('IntValue')
	item.Name = 'Items'
	item.Value = 0
	item.Parent = leaderstats
end)

Now in order to actually see visible change, I added a part to show the intValue increment by 1.

Updating leaderboard

script.Parent.Parent.Part.Touched:Connect(function(touch)
	local parent = touch.Parent --Who touched the part
	local humanoid = parent:FindFirstChildWhichIsA('Humanoid')
	if humanoid then --If humanoid
		local plr = game:GetService('Players'):GetPlayerFromCharacter(parent) -- Gets leaderboard
		local leaderstats = plr.leaderstats
		local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money')
		if moneyMaker then
			moneyMaker.Value = moneyMaker.Value + 1 --Changes value from 0 to +1 everytime it is touched.
		end
	end
end)

This is a simple leaderboard approach that I made just now. I also suggest you look on roblox's tutorials here- Leaderboard tutorial - https://developer.roblox.com/en-us/articles/Leaderboards

Full script-

local dds = game:GetService('DataStoreService')
local moneyData = dds:GetDataStore('MONEYDATA')
local itemData = dds:GetDataStore('ITEMDATA')

game.Players.PlayerAdded:Connect(function(plr)
	local data
	local data2
	local leaderstats = Instance.new('Folder')
	leaderstats.Name = 'leaderstats'
	leaderstats.Parent = plr

	local dollar = Instance.new('IntValue')
	dollar.Name = 'Money'
	dollar.Value = 0
	dollar.Parent = leaderstats
	
	local item = Instance.new('IntValue')
	item.Name = 'Items'
	item.Value = 0
	item.Parent = leaderstats
	
	while wait(5) do --every 5 seconds saves data
		moneyData:SetAsync(plr.UserId..'-moneyData', dollar.Value)
		itemData:SetAsync(plr.UserId..'-itemData', item.Value)
	end
	
	local success, err = pcall(function()
		data = moneyData:GetAsync(plr.UserId..'-moneyData') or 0
	end)
	if success then
		dollar.Value = data
	else
		-- Failed to retrieve data
	end
	
	local success, err = pcall(function()
		data2 = itemData:GetAsync(plr.UserId..'-itemData') or 0
	end)
	if success then
		item.Value = data2
	else
		-- Failed to retrieve data2
	end
end)

Part Script

script.Parent.Parent.Part.Touched:Connect(function(touch)
	local parent = touch.Parent
	local humanoid = parent:FindFirstChildWhichIsA('Humanoid')
	if humanoid then
		local plr = game:GetService('Players'):GetPlayerFromCharacter(parent)
		local leaderstats = plr.leaderstats
		local moneyMaker = leaderstats and leaderstats:FindFirstChild('Money')
		if moneyMaker then
			moneyMaker.Value = moneyMaker.Value + 1
		end
	end
end)

Also, if u dont understand, here is a link for datastores - https://developer.roblox.com/en-us/api-reference/function/GlobalDataStore/GetAsync

I believe I know the error in this script, you're setting the value of "points" 3 different times, but you only need to set it once.

Here's the fix:

Change line 41 to:

Minutes.Value = dataminutes

Change line 51 to:

Bricks.Value = databricks

have fun scripting, hydrogyn

I recommend saving it all in one table, this way you don't have to multiple setasyncs or update async

local StatsTable = {}
StatsTable.Money = Player.leaderstats.Money.Value
StatsTable.Items = Player.leaderstats.Items.Value
while true do
repeat
local Success, Error_ = pcall(function()
StatsDataStore:SetAsync(Player.Userid.."_Stats", StatsTable)
end)
wait(2)
until Success
wait(10)
end

I am pretty sure while wait() do is a bad idea, so just do a normal while true do is good with a coroutine on the while true do function for saving data, also, having a longer wait period on set asyncs is a good idea because you don't want to make to many requests in a short period of time. Using the pccall is a good idea because sometimes Datastores will error, and using a call can prevent it from breaking the code. https://devforum.roblox.com/t/avoiding-wait-and-why/244015

This discussion is preserved as it was. New answers, comments, and votes are closed.