[Solved] My Leaderboards show same Values

[Unsolved Issue]:
My Second Leaderboard is showing the data from my First Leaderboard

So I have two leaderboards. They are supposed to show two different datastores, but both leaderboards show the same data.

Images of the leaderstats

1. My Coins leaderboard. This shows the right data for the right board.

2. My Event leaderboard, This shows the wrong data from the wrong datastore (leaderboard 1).

Scripts

Script of Leaderboard 1. (Works as intended.)

-- [ SETTINGS ] --

local StatsName = "Coins" -- Your stats name
local MaxItems = 20 -- Max number of items to be displayed on the leaderboard
local MinValueDisplay = 1 -- Any numbers lower than this will be excluded
local MaxValueDisplay = 1000000000e1000000 -- (10 ^ 15) Any numbers higher than this will be excluded
local UpdateEvery = 60 -- (in seconds) How often the leaderboard has to update

-- [ END SETTINGS ] --




-- Don't edit if you don't know what you're doing --

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetOrderedDataStore("CoinsDataStore") --CoinsDataStore
local SurfaceGui = script.Parent
local Sample = script.Sample
local List = SurfaceGui.Frame.List
local ItemsFrame = List.ListContent.Items

local function GetItems()
	local Data = DataStore:GetSortedAsync(false, MaxItems, MinValueDisplay, MaxValueDisplay)
	local TopPage = Data:GetCurrentPage()
	
	ItemsFrame.Nothing.Visible = #TopPage == 0 and true or false
	
	for i, v in ipairs(TopPage) do
		local UserId = v.key
		local Value = v.value
		local Username = "[Not Available]"
		local Color = Color3.fromRGB(38, 50, 56)
		
		local Success, Error = pcall(function()
		 	Username = game.Players:GetNameFromUserIdAsync(UserId)
		end)
		
		if i == 1 then
			Color = Color3.fromRGB(255, 215, 0)
		elseif i == 2 then
			Color = Color3.fromRGB(192, 192, 192)
		elseif i == 3 then
			Color = Color3.fromRGB(205, 127, 50)
		end
		
		local Item = Sample:Clone()
		Item.Name = Username
		Item.LayoutOrder = i
		Item.Values.Number.TextColor3 = Color
		Item.Values.Number.Text = i
		Item.Values.Username.Text = Username
		Item.Values.Value.Text = Value
		Item.Parent = ItemsFrame
	end
end

while true do
	for i, v in pairs(game.Players:GetPlayers()) do
		local Stats = v.leaderstats:WaitForChild(StatsName).Value
		if Stats then
			pcall(function()
				DataStore:UpdateAsync(v.UserId, function(Value)
					return tonumber(Stats)
				end)
			end)
		end
	end
	
	for i, v in pairs(ItemsFrame:GetChildren()) do
		if v:IsA("ImageLabel") then
			v:Destroy()
		end
	end
	
	GetItems()
	
	wait()
	List.ListContent.GuideTopBar.Value.Text = StatsName
	List.CanvasSize = UDim2.new(0, 0, 0, ItemsFrame.UIListLayout.AbsoluteContentSize.Y + 35)
	wait(UpdateEvery)
end

Script of Leaderboard 2. (The one that needs to be fixed)

-- [ SETTINGS ] --

local StatsName = "Events" -- Your stats name
local MaxItems = 20 -- Max number of items to be displayed on the leaderboard
local MinValueDisplay = 1 -- Any numbers lower than this will be excluded
local MaxValueDisplay = 1000000000e1000000 -- (10 ^ 15) Any numbers higher than this will be excluded
local UpdateEvery = 60 -- (in seconds) How often the leaderboard has to update

-- [ END SETTINGS ] --




-- Don't edit if you don't know what you're doing --

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetOrderedDataStore("Event") --CoinsDataStore
local SurfaceGui = script.Parent
local Sample = script.Sample
local List = SurfaceGui.Frame.List
local ItemsFrame = List.ListContent.Items

local function GetItems()
	local Data = DataStore:GetSortedAsync(false, MaxItems, MinValueDisplay, MaxValueDisplay)
	local TopPage = Data:GetCurrentPage()
	
	ItemsFrame.Nothing.Visible = #TopPage == 0 and true or false
	
	for i, v in ipairs(TopPage) do
		local UserId = v.key
		local Value = v.value
		local Username = "[Not Available]"
		local Color = Color3.fromRGB(38, 50, 56)
		
		local Success, Error = pcall(function()
		 	Username = game.Players:GetNameFromUserIdAsync(UserId)
		end)
		
		if i == 1 then
			Color = Color3.fromRGB(255, 215, 0)
		elseif i == 2 then
			Color = Color3.fromRGB(192, 192, 192)
		elseif i == 3 then
			Color = Color3.fromRGB(205, 127, 50)
		end
		
		local Item = Sample:Clone()
		Item.Name = Username
		Item.LayoutOrder = i
		Item.Values.Number.TextColor3 = Color
		Item.Values.Number.Text = i
		Item.Values.Username.Text = Username
		Item.Values.Value.Text = Value
		Item.Parent = ItemsFrame
	end
end

while true do
	print("updating")
	for i, v in pairs(game.Players:GetPlayers()) do
		local Stats = v.leaderstats:WaitForChild(StatsName).Value
		if Stats then
			pcall(function()
				DataStore:UpdateAsync(v.UserId, function(Value)
					return tonumber(Stats)
				end)
			end)
		end
	end
	
	for i, v in pairs(ItemsFrame:GetChildren()) do
		if v:IsA("ImageLabel") then
			v:Destroy()
		end
	end
	
	GetItems()
	
	wait()
	List.ListContent.GuideTopBar.Value.Text = StatsName
	List.CanvasSize = UDim2.new(0, 0, 0, ItemsFrame.UIListLayout.AbsoluteContentSize.Y + 35)
	wait(UpdateEvery)

end

  • Script 1 / Leaderboard 1 uses a currency called “Coins” and a datastore called “CoinsDataStore”
  • Script 2 / Leaderboard 2 uses a currency called “Event” and a datastore called “Event”

As shown in the details, Script 2 / Leaderboard 2 shows the same data as Script 1 / Leaderboard 1, but it should show its own data. Please help me fix this! By the way, I duplicated the coins script and modified it for the events script, so there must be something I overlooked in the second leaderboard.

Thank you!

1 Like

Could it be you accidentally saved the Coins to the Event data store as well. Perhaps you copied your coin saving code and pasted it for you events, changed the datastore and forgot to change where it saves the coins to save the events?

I don’t think so. This is all that could potentially rig the whole system apart but I don’t see anything that seem to cause interruption with the second script here. For context, this is the script that handles all my data stores and saves them when a player leaves.

local DataStoreService = game:GetService("DataStoreService") --Calls DataStoreService



local SavedData = DataStoreService:GetDataStore("CoinsDatasStore") --Gets saved data

local SavedData2 = DataStoreService:GetDataStore("Level") --Gets saved data

local SavedData3 = DataStoreService:GetDataStore("Multiplier")

local SavedData4 = DataStoreService:GetDataStore("SwordlLevel")

local SavedData5 = DataStoreService:GetDataStore("Event")

-----------------------------------------------------------------------------------------------------------------------
game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = player
	leaderstats.Name = "leaderstats"
	local coins = Instance.new("IntValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats
	
	local Level = Instance.new("IntValue")
	Level.Name = "Level"
	Level.Parent = leaderstats
	
	local Multiplier = Instance.new("NumberValue")
	Multiplier.Name = "Multiplier"
	Multiplier.Parent = player
	
	local Kills = Instance.new("IntValue")
	Kills.Name = "Kills"
	Kills.Parent = player
	
	local Event = Instance.new("IntValue")
	Event.Name = "Event"
	Event.Parent = player
	

	local success,Data = pcall(function()
		return SavedData:GetAsync(player.UserId)
	end)
	if not Data then
		--Data = coins.Value == 0 useless junk =]
	end
	
	local success,Data2 = pcall(function()
		return SavedData2:GetAsync(player.UserId)
	end)
	if not Data2 then
		--
	end
	
	local success,Data3 = pcall(function()
		return SavedData3:GetAsync(player.UserId)
	end)
	if not Data3 then
		--
	end
	
	local success,Data5 = pcall(function()
		return SavedData3:GetAsync(player.UserId)
	end)
	if not Data5 then
		--
	end
	
	
	
	coins.Value = Data
	Level.Value = Data2
	Multiplier.Value = Data3
	Kills.Value = 0
	Event.Value = Data5
	
	
	if Level.Value == 0 then
		Level.Value = 1 
	end
	if coins.Value == 15 then
		Level.Value = Data
	end
	if Multiplier.Value == 0 or Multiplier.Value < 1 then
		print(Multiplier.Value)
		print("Changing val")
		Multiplier.Value = 1
		print(Multiplier.Value)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local coins = player.leaderstats.Coins
	SavedData:SetAsync(player.UserId, coins.Value)
	
	local Level = player.leaderstats.Level
	SavedData2:SetAsync(player.UserId, Level.Value)
	
	local Multiplier = player.Multiplier
	SavedData3:SetAsync(player.UserId, Multiplier.Value)
	
	local Event = player.Event
	SavedData5:SetAsync(player.UserId, Event.Value)
end)

^^^ Ignore the datastores like SwordLevel & Kills.

Something I did notice is you are loading your Multipliers data to your events value:

Notice SavedData3 in there, so your saving SaveData3 in Data5. if we look up, SavedData3 is:

And then you save the value of SavesData3 for the player in events:

Oh, thank you! Even though it wasn’t the main topic I appreciate it :slight_smile:

Another thing your doing, second time I’ve seen this today.

Lets see if you can see the error:

and

And for events:

And

Hint: it’s the kind of DataStore you got

You’re so amazing. But how do I fix this? The code from the leaderboard is not “ordered”. Do I just change it and leave it or do I have to modify something else?

I’ll mark this as the solution once we’re done with this! :slight_smile:

Okay, so the first step is to change the leaderstats script to use GetOrderedDataStore instead of normal DataStore

1 Like

When I used GetOrderedDataStore for my own first Global Leaderboard (100% from scratch and first time using it, only resources I used was one DevHub article) I used this function I made to get the Top 50 players for that data store (since my leaderboard was top 50 cause why not). Here it is if you want:

local function getTop50Players()
	local isAscending = false
	local pageSize = 50
	local pages = DS:GetSortedAsync(isAscending, pageSize)
	local top50 = pages:GetCurrentPage()

	local top = {}

	for rank, data in ipairs(top50) do
		local dataName = data.key
		local name = game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2])
		local coins = data.value

		local currentPlayer =  { Player = name, Coins = coins, Rank = rank, }
		table.insert(top, rank, currentPlayer)
	end

	return top
end

This is mostly refactored DevHub example code lol (you will have to change a few things) like you can just change game:GetService("Players"):GetNameFromUserIdAsync(dataName:split('_')[2]) to game:GetService("Players"):GetNameFromUserIdAsync(dataName)

1 Like

Thanks! But what about my previous leaderboard code?

I was just showing that as an example. You don’t have to use it. What are the current results for the leaderboard when you just

Also looking more at your old code, it pretty much does that function (just less organized lol)

Not really much. I haven’t really seen any differences, though when I just tried to print the DataStore:GetSortedAsync it does this.
image
from code:
image

I don’t know if it’s intended for a :GetSortedAsync to return Instance.

I really don’t know, instead print TopPage

Something definitely worked there. I’ll respond when I’ve investigated further. I think I’m close to finding the answer

thanks in advance

@domboss37 seems like you’ve somehow found the error along the way! If I ever hit this issue again, I’ll make sure to continue the conversation. But for now, I’ll mark your answer as the solution!

Thank you so so much for your help :slight_smile:

1 Like