How can I make a win badge?

Hello all,
I’m new to the scripting community and was trying to learn how badges work and was wondering how I can make a script that awards a badge when the player obtains its first win by checking the leaderstats,
for example

if the leaderstats value = 1 then
the badge gets awarded

how would I achieve that?
Thanks in advance

1 Like
local YourBadgeID = 0
if player.leaderstats.Wins.Value == 1 then
if game:GetService("BadgeService"):UserHasBadge(player.UserId,YourBadgeID) then return end
game:GetService("BadgeService"):AwardBadge(player.UserId,YourBadgeID)
end
1 Like

I suggest wrapping that in a pcall. To prevent issues when the web is down.

image
Returns this error, plus the if player.leaderstats.Wins.Value == 1 then is underlined red, what do I specify as the player?

Here, maybe this could help:

local Players = game:GetService("Players")
local Badges = game:GetService("BadgeService")
local BadgeID =  000000

Players.PlayerAdded:Connect(function(Player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = Player
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = 0
	wins.Parent = folder
	
	wins.Changed:Connect(function(Value)
		if Value == 1 then
			local success,result = pcall(function()
				return Badges:UserHasBadgeAsync(Player.UserId,BadgeID)
			end)
			if success then
				if result then -- if he owns the badge
					
				else -- if not, award him here
					local success2,result2 = pcall(function()
						return Badges:AwardBadge(Player.UserId,BadgeID)
					end)
					if success2 then
						Badges:AwardBadge(Player.UserId,BadgeID)
					end
				end
			end
		end
	end)
end)

when do you exactly want to reward the badge to the player?

Even better, this line here:

if game:GetService("BadgeService"):UserHasBadge(player.UserId,YourBadgeID) then return end

This isn’t actually needed, you can just directly call:

  game:GetService("BadgeService"):AwardBadge(player.UserId,YourBadgeID)

It won’t error or anything either, it’s almost like a try and forget function call and won’t error if they already have the badge (saves an extra call to the BadgeService too).

This script should be good:

local YourBadgeID = 0

if player.leaderstats.Wins.Value == 1 then
    game:GetService("BadgeService"):AwardBadge(player.UserId,YourBadgeID)
end
local Players = game:GetService("Players")
local Badges = game:GetService("BadgeService")
local BadgeID =  000000

Players.PlayerAdded:Connect(function(Player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = Player
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = 0
	wins.Parent = folder
	
	wins.Changed:Connect(function(Value)
		if Value == 1 then
			local success,result = pcall(function()
				return Badges:UserHasBadgeAsync(Player.UserId,BadgeID)
			end)
			if success then
				if result then -- if he owns the badge
					
				else -- if not, award him here
					local success2,result2 = pcall(function()
						return Badges:AwardBadge(Player.UserId,BadgeID)
					end)
					if success2 then
						Badges:AwardBadge(Player.UserId,BadgeID)
					end
				end
			end
		end
	end)
end)

You should always wrap such calls/services in pcalls.

When the player reaches its first win

Try this script:

local Players = game:GetService("Players")
local Badges = game:GetService("BadgeService")
local BadgeID =  000000

Players.PlayerAdded:Connect(function(Player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = Player
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = 0
	wins.Parent = folder
	
	wins.Changed:Connect(function(Value)
		if Value == 1 then
			local success,result = pcall(function()
				return Badges:UserHasBadgeAsync(Player.UserId,BadgeID)
			end)
			if success then
				if result then -- if he owns the badge
					
				else -- if not, award him here
					local success2,result2 = pcall(function()
						return Badges:AwardBadge(Player.UserId,BadgeID)
					end)
					if success2 then
						Badges:AwardBadge(Player.UserId,BadgeID)
					end
				end
			end
		end
	end)
end)

[It is an example]
This should work 100% to you. Why using pcalls? simply because the web can sometimes go down, and cause issues to our code, so using pcalls would still run that code in such cases.

local YourBadgeID = 0
game.Players.PlayerAdded:Connect(function(plr)
plr.leaderstats.Wins.Changed:Connect(function(val)
if val == 1 then
if game:GetService("BadgeService"):UserHasBadge(plr.UserId,YourBadgeID) then return end
game:GetService("BadgeService"):AwardBadge(plr.UserId,YourBadgeID)
end
end)
end)

Why not try out my script? It is safer to use

About his issue , he forgot to put a ‘)’ at the last end

oops, i fixed the code try again.

Yours seems to be creating a new problem within the leaderstats
image

then just remove the leaderstats code

local Players = game:GetService("Players")
local Badges = game:GetService("BadgeService")
local BadgeID =  000000

Players.PlayerAdded:Connect(function(Player)
	local wins = Player:WaitForChild("leaderstats"):WaitForChild("Wins")

	wins.Changed:Connect(function(Value)
		if Value == 1 then
			local success,result = pcall(function()
				return Badges:UserHasBadgeAsync(Player.UserId,BadgeID)
			end)
			if success then
				if result then -- if he owns the badge

				else -- if not, award him here
					local success2,result2 = pcall(function()
						return Badges:AwardBadge(Player.UserId,BadgeID)
					end)
					if success2 then
						Badges:AwardBadge(Player.UserId,BadgeID)
					end
				end
			end
		end
	end)
end)

I agree with you for the most part, but not in the case where there’s human error in terms of calling the function (invalid parameter type?) so to fix up your implementation, I would have added the pcall, but print the error if the call doesn’t succeed. That way the developer would know it wasn’t them that was the cause of functionality breaking (could be Roblox’s servers, API endpoints being unavailable etc, depending on what service you’re dealing with).

And in that particular example, I was only demonstrating how it wasn’t needed to query :UserHasBadgeAsync() all the time (only in cases where you NEED to know if they have a badge or not, maybe to give an item in a game?), you can just directly call :AwardBadge and save the API call behind the scenes that :UserHasBadgeAsync() would be doing.