Do not print "We already gave out badge..."

As a Roblox developer, it is currently too hard to make an efficient badge giving script because it takes less time by orders of magnitude to just call the awardbadge function no matter what than it does to first check if the user already has the badge. This is too hard because I can’t afford to have a simple badge check take .1 seconds. I also don’t want to resort to making my own cache system, Roblox should stop printing warnings that someone already has a badge.

I realize I can hide warnings, but that may not be ideal because I could use warnings elsewhere in my code, but I would never find them with the badge warning spam.
My server output (on a server with only me)


Code that gave this output:

Output with a full server

My bagde system has server side sanity checks, as clients fire events when they hit certain parts. This is why there are so many duplicate warnings.

If there is something wrong with calling the award badge so many times when a user already has it, can something be done to make it not as bad. I don’t know what goes on under the hood for this code on Roblox’s end. I am looking for answers because there has got to be a better way.

If Roblox is able to address this issue, it would not clog up the Server output with warnings that do not need to be there.

19 Likes

You should only really use MarketplaceService, GamepassService, BadgeService, or any other service when necessary. Spamming Awardbadge every single time regardless if the player has the badge or not, is very bad practice. I would just take the time to make a table of player data stating if they own the badge or not and go based on that so you dont have to keep calling the services. When you need to award the badge, check if its false, if it is then award it and set it to true. It’s that simple :grin:

Example of one way this can be done:

-- Create global table:
local playerData = {}

-- in PlayerAdded do:
playerData["id"..player.UserId] = { Badges = {} }

-- The function to check if user has badge:
local function hasBadge(player, badgeId)
	if type(playerData["id"..player.UserId].Badges["id"..badgeId]) ~= "boolean" then
		local hasBadge = -- check if they have the badge, should return a boolean
		playerData["id"..player.UserId].Badges["id"..badgeId] = hasBadge
		return hasBadge
	else
		return playerData["id"..player.UserId].Badges["id"..badgeId]
	end
end

-- The part to use before awarding badge:
if not hasBadge(player, badgeId) then
	-- TODO: awardBadge here
	playerData["id"..player.UserId].Badges["id"..badgeId] = true
end
7 Likes

Really not sure why you’re doing this seemingly on renderstepped or heartbeat, I agree it is a nuisance but is this some kind of exaggerated example or are you legitimately using this code in your game?

He is showing that the execution time is orders of magnitude different between check + award and just awarding, even though the awarding code clearly also does a cache check in the background, otherwise it wouldn’t know to throw the warning. Developers should either be able to do that fast cache check too or just forfeiting the warning altogether.

It’s not renderstepped or heartbeat, just calling the code in a loop.

3 Likes

At the very least, don’t print it on production. They could keep the warning in studio that it’s not a best practice.

On the wiki for AwardBadge:

  • The player must not already have the badge.
    -Yet in the code examples, there is no official Roblox created developer way to do this check efficiently.

UserHasBadge is depreciated, but it is very fast (only after the 1st call…). (either that or it is mistaken in thinking this isn’t a badge in play solo, so it skips part of the function)

1 Like

Took your advice using similar code
Now I get to have the satisfaction of removing the print myself!


2 Likes