Better way to award badge?

The players stats can change every 1 second which leads to issues with this current system. Is there a work around? Trying to avoid spamming BadgeService

-- Player joins
game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = player:WaitForChild("leaderstats")
	local Slept = leaderstats:WaitForChild("Slept")

	Slept.Changed:Connect(function()
		local sleepValue = Slept.Value

		-- Award in increasing order so they can earn all applicable ones
		if sleepValue >= 100 then
			awardBadge(player, "Slept 100")
		end
		if sleepValue >= 10000 then
			awardBadge(player, "Slept 10,000")
		end
		if sleepValue >= 100000 then
			awardBadge(player, "Slept 100,000")
		end
		if sleepValue >= 1000000 then
			awardBadge(player, "Slept 1,000,000")
		end
		if sleepValue >= 100000000 then
			awardBadge(player, "Slept 100,000,000")
		end
	end)
end)
1 Like

local sleepBadges = {
		-- badge name ... sleep value
		["Slept 100"] = 100,
		["Slept 10,000"] = 10000,
		["Slept 100,000"] = 100000,
}

-- after some condition 

for badgeName, badgeValue in sleepBadges do
	if sleepValue.Value >= badgeValue then

		  awardBadge(player, badgeName)

	end
end

I am not sure if a failed awardBadge will count toward the limit or not, but to be safe, don’t call the function every .Changed .

1 Like

You could simply use else-if conditionals and use a dictionary to keep track.

local WasAwarded = {}

...

WasAwarded[plr.UserId] = {
	["100000000"] = false,
	["1000000"] = false,
	["100000"] = false,
	["10000"] = false,
	["100"] = false
}

...

if sleepValue >= 100000000 and WasAwarded[plr.UserId]["100000000"] == false then
	WasAwarded[plr.UserId]["100000000"] = true
	awardBadge(player, "Slept 100,000,000")
elseif sleepValue >= 1000000 and WasAwarded[plr.UserId]["1000000"] == false then
	WasAwarded[plr.UserId]["1000000"] = true
	awardBadge(player, "Slept 1,000,000")
elseif sleepValue >= 100000 and WasAwarded[plr.UserId]["100000"] == false then
	WasAwarded[plr.UserId]["100000"] = true
	awardBadge(player, "Slept 100,000")
elseif sleepValue >= 10000 and WasAwarded[plr.UserId]["10000"] == false then
	WasAwarded[plr.UserId]["10000"] = true
	awardBadge(player, "Slept 10,000")
elseif sleepValue >= 100 and WasAwarded[plr.UserId]["100"] == false then
	WasAwarded[plr.UserId]["100"] = true
	awardBadge(player, "Slept 100")
end

This’ll prevent repeatedly calling awardBadge for the same badge. =)

And if you reaaaaally wanted to go that far, you could disconnect the event, preventing the Changed event from executing the code any further after receiving the final award.

local SleepConn = Slept.Changed:Connect(function()

...

if sleepValue >= 100000000 and WasAwarded[plr.UserId]["100000000"] == false then
	WasAwarded[plr.UserId]["100000000"] = true
	SleepConn:Disconnect()
	awardBadge(player, "Slept 100,000,000")
elseif sleepValue >= 1000000 and WasAwarded[plr.UserId]["1000000"] == false then
...
1 Like

Yup, did something similar. I decided to add Flags for each Badge. If they have enough points, it would check if it’s been flagged already. If not, it would Award the badge then causing it to be flagged. (Each flag is individual for each player)

Kinda took inspiration from ya lol

1 Like

Haha, sweet. Hope that works out well for ya!

1 Like

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