Donation Leaderboard not loading Top Donated user's avatar

  1. What do you want to achieve?

I want to be able to display a user’s avatar if they’re #1 on a donated leaderboard.

  1. What is the issue? Include screenshots / videos if possible!

No errors are in the output and the player’s name is “Unknown Player,” which is given in the first script listed below on line 9.

  1. What solutions have you tried so far?
    I’ve tried making the data value 1 instead of empty or just nil, since at first it was giving me errors saying data was nil.

There are two scripts that are affiliated with this leaderboard, “Init,” which is under the dummy, and “boards,” which controls multiple leaderboards from ServerScriptService.

Init:

local id = script.Parent:GetAttribute("ID")
local success, data = pcall(function()
	return game:GetService("UserService"):GetUserInfosByUserIdsAsync({tonumber(id)})
end)

if success and data and #data > 0 then
	script.Parent.Head.Overhead.Username.Text = data[1].Name
else
	script.Parent.Head.Overhead.Username.Text = "Unknown Player"
	return
end

local description = game:GetService("Players"):GetHumanoidDescriptionFromUserId(id)
if description then
	script.Parent:WaitForChild("Humanoid"):ApplyDescription(description)
else
	warn("Failed to get humanoid description for user ID:", id)
	return
end

Asset = "http://www.roblox.com/Asset?id="
IDs = {507770239}
anims = {}
animsL = {}
humanoid = script.Parent:WaitForChild("Humanoid")

for i = 1, #IDs do
	local anim = Instance.new("Animation")
	anim.AnimationId = (Asset..IDs[math.random(1, #IDs)])
	table.insert(anims, anim)
	wait()
end

for i = 1, #anims do
	local animL = humanoid:LoadAnimation(anims[i])
	table.insert(animsL, animL)
	wait()
end

local logic = function(part)
	game:GetService("PhysicsService"):SetPartCollisionGroup(part, "sword_effects")
end

for k, v in pairs(script.Parent:GetChildren()) do
	if v:IsA("BasePart") then
		logic(v)
	end
end

script.Parent.ChildAdded:Connect(function(v)
	if v:IsA("BasePart") then
		logic(v)
	end
end)

while true do
	local dance = animsL[math.random(1, #animsL)]
	dance:Play()
	wait(15)
end

board:

local format = require(script:WaitForChild("format"))
local amnt = game:GetService("RunService"):IsStudio() and 15 or 35
shared.load_amount = 10

return function(statName, dataStore, board, name, displayName, statsDisabled, npcName)
	local players = game:GetService("Players")
	local datastore = game:GetService("DataStoreService"):GetOrderedDataStore(dataStore)
	local valueName = statName
	board.CanvasSize = UDim2.new(1, 0, 0, 0)

	game.ReplicatedStorage:WaitForChild("events"):WaitForChild("boardUpdate").OnServerEvent:Connect(function(p)
		game.ReplicatedStorage.events.boardUpdate:FireClient(p, board)
	end)

	local updatingLabel = board.Parent.Updating
	shared["wipe_" .. displayName] = function(key, new)
		datastore:SetAsync(key, new)
	end

	local update = function(value, key, plr)
		while wait(35) do
			if plr.Parent == game:GetService("Players") then
				local s, e = pcall(function()
					datastore:UpdateAsync(key, function(old)
						return value.Value
					end)
				end)
				if e and not s then
					warn(e)
				end
			else
				break
			end
		end
	end

	local logic = function(player)
		coroutine.wrap(function()
			repeat
				wait()
			until player:FindFirstChild("leaderstats") or not players:FindFirstChild(player.Name)
			pcall(function()
				if not statsDisabled then
					local stat = player.leaderstats:WaitForChild(name)
					update(stat, player.UserId, player)
				end
			end)
		end)()
	end

	local tag = function(text)
		return "<font color=\"rgb(200,200,200)\">" .. text .. "</font>"
	end

	for _, v in pairs(players:GetPlayers()) do
		logic(v)
	end
	players.PlayerAdded:Connect(logic)
	players.PlayerRemoving:Connect(function(plr)
		if displayName == "time" then
			pcall(function()
				local last = plr.leaderstats.Time.Value
				local s, e = pcall(function()
					datastore:UpdateAsync(plr.UserId, function(old)
						return last
					end)
				end)
				if e and not s then
					warn(e)
				end
			end)
		end
	end)

	while true do
		local s, e = pcall(function()
			local data = datastore:GetSortedAsync(false, shared.load_amount, 1, math.maxinteger)
			local top = data:GetCurrentPage()
			for _, v in pairs(board:GetChildren()) do
				if v:IsA("Frame") then
					v:Destroy()
				end
			end
			local users = {}
			local numberOne = 0
			for _, v in pairs(top) do
				table.insert(users, tonumber(v.key))
				if k == 1 then
					numberOne = v.key
				end
			end
			if numberOne then
				if npcName then
					workspace.NPCs:ClearAllChildren()
					local npc = game.ServerStorage[npcName]:Clone()
					npc:SetAttribute("ID", numberOne)
					npc.Parent = workspace.NPCs
				end
			end
			local success, result = pcall(function()
				return game:GetService("UserService"):GetUserInfosByUserIdsAsync(users)
			end)
			if not success then
				warn(result)
			end
			for k, v in pairs(top) do
				local username = "[FAILED TO LOAD NAME]"
				local hasDisplayName = false
				local s, e = pcall(function()
					for _, i in pairs(result) do
						if i.Id == tonumber(v.key) then
							username = i["DisplayName"]
							hasDisplayName = (i["DisplayName"] ~= i["Username"]) and i["Username"] or false
						end
					end
				end)
				local p = game.Players:GetPlayerByUserId(v.key)
				if p and k <= 5 then
					pcall(function()
						p:SetAttribute("OnLeaderboard", true)
						task.spawn(function()
							p:WaitForChild("Inventory"):SetAttribute("Leaderboard", true)
						end)
					end)
				end
				if username == "[FAILED TO LOAD NAME]" then
					local s, e = pcall(function()
						return game:GetService("Players"):GetNameFromUserIdAsync(tonumber(v.key))
					end)
					if e and s then
						username = e
					end
				end
				if e and not s then
					warn("USER LOAD FAILED", e)
				end
				local score = v.value
				if type(score) == "number" then
					score = format.FormatStandard(score)
				end

				local place = script:WaitForChild("Place"):Clone()
				place.Score.Text = score .. " " .. (v.value > 1 and valueName:sub(1, #valueName) or valueName:sub(1, #valueName - 1))
				place.User.Text = username
				place.Place.Text = "#" .. k
				place.User:SetAttribute("AlternateText", (hasDisplayName ~= false) and tag(" @" .. hasDisplayName) or "")

				local image = game.Players:GetUserThumbnailAsync(v.key, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
				place.Icon.Image = image
				place.Parent = board
			end
			game.ReplicatedStorage.events.boardUpdate:FireAllClients(board)
			board.CanvasSize = UDim2.new(1, 0, 0, board.UIListLayout.AbsoluteContentSize.Y)
		end)
		if e and not s then
			warn(e)
		end
		coroutine.wrap(function()
			updatingLabel.Text = "Updating in " .. amnt
			for i = 1, amnt - 1 do
				wait(1)
				updatingLabel.Text = "Updating in " .. tostring(amnt - i)
			end
		end)()
		wait(amnt)
	end
end

In-Game Screenshot:
image

1 Like

I believe the data would be a dictionary and thus if success and data and #data > 0 then would always output false as it would always be 0. The correct way to then check if the data exists instead would be if success and data and next(data) ~= nil then.

Edit - Alternatives:

  • #table.keys(dictionary) > 0

You may also be to remove the return and as follows (as I belive the return may stop the rest of your code from continuing not sure though as I cannot see the rest) -

if success and data and data[1] and data[1]["Name"] then
	script.Parent.Head.Overhead.Username.Text = data[1].Name
else
	script.Parent.Head.Overhead.Username.Text = "Unknown Player"
end

Edit 2:

local id = script.Parent:GetAttribute("ID")
if tonumber(id) == 0 then return end

script.Parent.Head.Overhead.Username.Text = game:GetService("Players"):GetNameFromUserIdAsync(id)

local description = game:GetService("Players"):GetHumanoidDescriptionFromUserId(id)
script.Parent:WaitForChild("Humanoid"):ApplyDescription(description)
2 Likes

Is it possible that the “ID” attribute isn’t added to the dummy or that the code in “Init” is running before “boards” so the “ID” attribute is added after “Init” already ran, thus not detecting it? If the latter is the case, try the following code:

local function updateDescription(id)
	local description = game:GetService("Players"):GetHumanoidDescriptionFromUserId(id)
	if description then
		script.Parent:WaitForChild("Humanoid"):ApplyDescription(description)
	else
		warn("Failed to get humanoid description for user ID:", id)
		return
	end
end

local function updateDummy(id)
	local success, data = pcall(function()
		return game:GetService("UserService"):GetUserInfosByUserIdsAsync({tonumber(id)})
	end)

	if success and data and #data > 0 then
		script.Parent.Head.Overhead.Username.Text = data[1].Name
		updateDescription(id)
	else
		script.Parent.Head.Overhead.Username.Text = "Unknown Player"
		return
	end
end

script.Parent:GetAttributeChangedSignal("ID"):Connect(updateDummy)

1 Like

Thank you for this feedback! I just got this error:
image

Here’s the current state of Init for reference.

local id = script.Parent:GetAttribute("ID")
local success, data = pcall(function()
	return game:GetService("UserService"):GetUserInfosByUserIdsAsync({tonumber(id)})
end)

if success and data and data[1] and data[1]["Name"] then
	script.Parent.Head.Overhead.Username.Text = data[1].Name
else
	script.Parent.Head.Overhead.Username.Text = "Unknown Player"
end

local description = game:GetService("Players"):GetHumanoidDescriptionFromUserId(id)
if description then
	script.Parent:WaitForChild("Humanoid"):ApplyDescription(description)
else
	warn("Failed to get humanoid description for user ID:", id)
	return
end

Asset = "http://www.roblox.com/Asset?id="
IDs = {507770239}
anims = {}
animsL = {}
humanoid = script.Parent:WaitForChild("Humanoid")

for i = 1, #IDs do
	local anim = Instance.new("Animation")
	anim.AnimationId = (Asset..IDs[math.random(1, #IDs)])
	table.insert(anims, anim)
	wait()
end

for i = 1, #anims do
	local animL = humanoid:LoadAnimation(anims[i])
	table.insert(animsL, animL)
	wait()
end

local logic = function(part)
	game:GetService("PhysicsService"):SetPartCollisionGroup(part, "sword_effects")
end

for k, v in pairs(script.Parent:GetChildren()) do
	if v:IsA("BasePart") then
		logic(v)
	end
end

script.Parent.ChildAdded:Connect(function(v)
	if v:IsA("BasePart") then
		logic(v)
	end
end)

while true do
	local dance = animsL[math.random(1, #animsL)]
	dance:Play()
	wait(15)
end

I’ve already checked the dummy’s attributes and it’s there, with a value of zero.
I tried applying your code to mine and now we’ve made some progress. Still no errors, but now the dummy has animations. Also, the name continues to be Unknown Player.
image

1 Like

:GetUserInfosByUserIdsAsync() is returning a empty array because 0 isn’t a valid user id, thats why your getting the “Unknown Player” and that error.

It looks like the problem is occurring on line 86 of “boards”,

local numberOne = 0 -- Defaults to 0, "ID" attribute is later set to this
			for _, v in pairs(top) do
				table.insert(users, tonumber(v.key))
				if k == 1 then -- "k" doesn't exist and never equals 1 so "numberOne" stays 0, it also doesn't throw any errors
					numberOne = v.key
				end
			end

I think you just forgot to add “k” to your for loop.

local numberOne = 0
			for k, v in pairs(top) do -- "_" --> "k"
				table.insert(users, tonumber(v.key))
				if k == 1 then
					numberOne = v.key
				end
			end
1 Like

I’ve tried this out and now I get this error: “Unable to assign property Text. string expected, got nil”

Thanks for that suggestion, here’s my init script currently:

local id = script.Parent:GetAttribute("ID")
local success, data = pcall(function()
	return game:GetService("UserService"):GetUserInfosByUserIdsAsync({tonumber(id)})
end)

if success and data and #data > 0 then
	script.Parent.Head.Overhead.Username.Text = data[1].Name
else
	script.Parent.Head.Overhead.Username.Text = "Unknown Player"
	return
end

local description = game:GetService("Players"):GetHumanoidDescriptionFromUserId(id)
if description then
	script.Parent:WaitForChild("Humanoid"):ApplyDescription(description)
else
	warn("Failed to get humanoid description for user ID:", id)
	return
end

Asset = "http://www.roblox.com/Asset?id="
IDs = {507770239}
anims = {}
animsL = {}
humanoid = script.Parent:WaitForChild("Humanoid")

for i = 1, #IDs do
	local anim = Instance.new("Animation")
	anim.AnimationId = (Asset..IDs[math.random(1, #IDs)])
	table.insert(anims, anim)
	wait()
end

for i = 1, #anims do
	local animL = humanoid:LoadAnimation(anims[i])
	table.insert(animsL, animL)
	wait()
end

local logic = function(part)
	game:GetService("PhysicsService"):SetPartCollisionGroup(part, "sword_effects")
end

for k, v in pairs(script.Parent:GetChildren()) do
	if v:IsA("BasePart") then
		logic(v)
	end
end

script.Parent.ChildAdded:Connect(function(v)
	if v:IsA("BasePart") then
		logic(v)
	end
end)

while true do
	local dance = animsL[math.random(1, #animsL)]
	dance:Play()
	wait(15)
end
1 Like

I had some errors in my leaderboard function but I ended up fixing it. Thank you very much!

1 Like

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