Badge counter recounting badges many times

  1. What do you want to achieve? I want a working badge counter that refreshes every 5 seconds and shows the badges the player owns in the game and doesn’t recount the same badges again and counts the badges in a table

  2. What is the issue? The badge counter recounts the same badges the player owns and then it goes on infinitely and doesn’t work correctly.

Screen Shot 2022-01-12 at 10.00.31 AM -this is adding badges again and again even tho the player only owns 17 and doesn’t own 107 of them (there aren’t even 107 badges in the table)

  1. What solutions have you tried so far? I’ve private messaged with someone to help me but we keep on discovering more and more bugs
local bIDs = {2124871551,2124871927,2124871927,2124874652,2124875134,2124875135,2124875283,2124883537,2124883540,2124883811,2124883814,2124883850,2124883955,2124883958,2124902920,2124902921,2124902922,2124885305,2124904543,2124903302,2124903285,2124904556,2124903961,2124903965,2124903963,2124906387,2124907283,2124907055,2124907311}


game.Players.PlayerAdded:Connect(function(plr)
	while true do
		wait(5)
		local val1 = Instance.new("IntValue", game.Workspace)
		val1.Name = "checkVal"
		local BS = game:GetService("BadgeService")
		if BS:UserHasBadgeAsync(plr.UserId, bIDs[val1.Value + 1]) then
			wait(5)
			wait(0.5)
			local BadgeService = game:GetService("BadgeService")
			for _, id in next, bIDs do
				wait(0.2)
				if BadgeService:UserHasBadgeAsync(plr.UserId, id) then  -- checks if user has badge
					print("check")
					plr.leaderstats.Exorics.Value += 1 -- if so then adds 1
					val1.Value += 1
				end 
			end
		elseif plr.leaderstats.Exorics.Value >= 29 then
			break
		end
	end
end)
local badgeIds = {2124871551, 2124871927, 2124874652, 2124875134, 2124875135, 2124875283, 2124883537, 2124883540, 2124883811, 2124883814, 2124883850, 2124883955, 2124883958, 2124885305, 2124902920, 2124902921, 2124902922, 2124903285, 2124903302, 2124903961, 2124903963, 2124903965, 2124904543, 2124904556, 2124906387, 2124907055, 2124907283, 2124907311}
local players = game:GetService("Players")
local badges = game:GetService("BadgeService")

local function onPlayerAdded(plr)
	task.wait()
	local ls = plr:WaitForChild("leaderstats")
	local exorics = ls:WaitForChid("Exorics")
	for _, badgeId in ipairs(badgeIds) do
		task.wait(5)
		local succ, res = pcall(function()
			return badges:UserHasBadgeAsync(plr.UserId, badgeId)
		end)
		
		if succ then
			if res then
				exorics.Value += 1
			end
		else
			warn(res)
		end
	end
end

players.PlayerAdded:Connect(onPlayerAdded)

Providing the leaderstats have been setup correctly the “Exorics” stat will display the total number of badges the player owns.

The script has no errors but for some reason, it just doesn’t count the badges?
Screen Shot 2022-01-12 at 11.27.01 AM

Here’s how Players look like:
Screen Shot 2022-01-12 at 11.28.28 AM

Leaderstats should be a folder inside the player and any stats which should display on the leaderboard need to be inside that folder.

https://education.roblox.com/en-us/resources/adventure-game-creating-a-leaderboard

I set it up properly but it still won’t work
Screen Shot 2022-01-12 at 11.41.38 AM

Screen Shot 2022-01-12 at 11.41.54 AM

local badgeIds = {2124871551, 2124871927, 2124874652, 2124875134, 2124875135, 2124875283, 2124883537, 2124883540, 2124883811, 2124883814, 2124883850, 2124883955, 2124883958, 2124885305, 2124902920, 2124902921, 2124902922, 2124903285, 2124903302, 2124903961, 2124903963, 2124903965, 2124904543, 2124904556, 2124906387, 2124907055, 2124907283, 2124907311}
local players = game:GetService("Players")
local badges = game:GetService("BadgeService")

local function onPlayerAdded(player)
	local ls = Instance.new("Folder")
	ls.Parent = player
	ls.Name = "leaderstats"

	local badgeCount = Instance.new("IntValue")
	badgeCount.Parent = ls
	badgeCount.Name = "Badges"

	for _, badgeId in ipairs(badgeIds) do
		task.wait(5)
		local succ, res = pcall(function()
			return badges:UserHasBadgeAsync(player.UserId, badgeId)
		end)

		if succ then
			if res then
				badgeCount.Value += 1
			end
		else
			warn(res)
		end
	end
end

players.PlayerAdded:Connect(onPlayerAdded)

image

I tested using this script and I added a badge to the badge table which I owned (removed in the above script).

It’s still not working for me. It keeps on saying 0 exorics owned and i own 17 out of the 29 badges in the table

You’ll need to delete your old leaderstats script if you want to use the most recent script I’ve provided (I was just showing you that it works).

You could save a player owned badges inside their datastore(as data.badges assuming you use dictionaries). Then if they earn a badge, which isn’t part of their saved badges, add it to the data.badges array. Then to get the amount of badges they own use the # operator which returns the length of an array. Example:

local data = {
	badges = {1, 2, 3, 4, 5} --badge ids a user owns
end

local length = #data.badges 
print(length) --5

And to detect when a user earns a badge, I consider it better to have a custom event instead of looping(and fire it when rewarding a badge)

--in scripts rewarding badges
local BadgeService = game:GetService("BadgeService")
local Remote = game.ReplicatedStorage.BadgeAwarded --a bindable event

function AwardBadge(userId, badgeId)
	local Success, Error = pcall(function()
		BadgeService:AwardBadge(userId, badgeId)
	end)
	if Success then 
		Remote:Fire(userId, badgeId)
		print("succesfully rewarded badge!")
	else 
		warn(Error)
	end
end
--inside the script counting them
local Players = game:GetService("Players")

local Remote = game.ReplicatedStorage.BadgeAwarded --a bindable event

Remote.Event:Connect(function(userId, badgeId)
	local Player = Players:GetPlayerByUserId(userId)
	print(badgeId, "was rewarded to", Player.Name) --you can use userId or Player to retrieve their datastore
	if not table.find(data.badges, badgeId) then --where data is the player data with the specific userId
		table.insert(data.badges, badgeId) 
		Player.leaderstats.Exorics.Value = #data.badges
	end
end)

And to avoid over-complicating the post I leave it here, but it’s better to create a system for this, responsible for rewarding in-game badges and firing “badgeRewarded” remotes, so you can avoid having to make an enormous amount of actual API requests each time a user joins.

Sorry for the late response but the badge counter doesn’t seem to refresh and show the badges i just collected.
Screen Shot 2022-01-12 at 12.53.26 PM
i just collected 1 badge and it still shows 16