How would i give a user a badge if they have a certain score in the leaderboard?

What I have is a survivals system in my game, what I want to do is when the user gets lets say 100 survivals, I give them a badge, how would I do that?

1 Like

You can use BadgeService:AwardBadge(userId, badgeId)

1 Like

I know that but i’m talking about awarding them the badge when they have a certain score on the leaderboard

1 Like
leaderstats.Score.Changed:Connect(function()
      if leaderstats.Score.Value >= 10 then
            BadgeService:AwardBadge(userId, badgeId)
      end
end)
1 Like

That only checks the default value of the score in the leaderboard and not the players

1 Like

Yes, so what you do is go into the folder inside the player called leaderstats.
Normally when leaderstats are created they are like this:

local badgeService = game:GetService("BadgeService")
local badgeId = 0

game.Players.PlayerAdded:Connect(function(player)
      local leaderstats = Instance.new("Folder")
      leaderstats.Name = "leaderstats"
      leaderstats.Parent = player

      local scoreVal = Instance.new("NumberValue")
      scoreVal.Name = "Score"
      scoreVal.Parent = leaderstats

      scoreVal.Changed:Connect(function()
            if scoreVal.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) then
                  badgeService:AwardBadge(player.UserId, badgeId)
            end
      end)
end)

As you can see, I added the changed event from my last post that checks if the score is high enough to get a badge.

2 Likes

But does the part where it actually checks if the score changed checks if the players score changed check everytime the score actually changes, checks only once, or checks all the time, the reason I ask this is because the script which gives the player survivals is the same script that makes the game work so i dont want a part in the middle to completely stop the script (if it for example is like a while true loop the checks all the time)

The ‘Changed’ event is fired every time a value is, well… changed. This means that it will only check if the player has enough score for a badge when their score is actually updated.

In short, no. It won’t completely stop the script and it will run asynchronously.

1 Like

but is there a way to make it a completely other script that checks the players score because i dont want to risk breaking the main script

If you don’t want it to break the main script, you can wrap it in a pcall like so:

xpcall(function()
      scoreVal.Changed:Connect(function()
            if scoreVal.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) 
      then
                  badgeService:AwardBadge(player.UserId, badgeId)
            end
      end)
end, warn)

This will prevent any errors from breaking your script, but also warn them to the dev console if they do happen.

1 Like

Also, if you want to put them in a seperate script you can do:

player:WaitForChild("leaderstats").Score.Changed:Connect()
1 Like

So how would i define the player?
I can’t have it when the player joins or the character is added since i want to check it all the time and not when they just spawn
Also thats one of the only ways i know how to define the actual player through a server script since im not too good at scripting

Well not nessesarily all the time but when the players score changed

If you want it to check just when the character spawns you can do:

game.Players.PlayerAdded:Connect(function(player)
      player.CharacterAdded:Connect(function(character)
            if player:WaitForChild("leaderstats").Score.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) then
                  badgeService:AwardBadge(player.UserId, badgeId)
            end
      end)
end)

thats what i said i didnt want it to do
i want it to check every time their score changed which i know is the changed event but idk how to define the player itself

The code I sent a few posts ago does it when the score changes, thus we use the ‘Changed’ event

xpcall(function()
      scoreVal.Changed:Connect(function()
            if scoreVal.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) 
      then
                  badgeService:AwardBadge(player.UserId, badgeId)
            end
      end)
end, warn)

i know how to check when their score changed and how to give them the badge but my question is how to define the player themselves everytime their score changed instead of defineing them everytime they spawn

Okay to make it clearer here is the full code:

local badgeService = game:GetService("BadgeService")
local badgeId = 0

game.Players.PlayerAdded:Connect(function(player)
      local leaderstats = Instance.new("Folder")
      leaderstats.Name = "leaderstats"
      leaderstats.Parent = player

      local scoreVal = Instance.new("NumberValue")
      scoreVal.Name = "Score"
      scoreVal.Parent = leaderstats

      scoreVal.Changed:Connect(xpcall(function()
            if scoreVal.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) then
                  badgeService:AwardBadge(player.UserId, badgeId)
            end
      end), warn)
end)

The player is defined on the game.Players.PlayerAdded event, as it is passed into the function connected to it.

The part below is what im confused about

local badgeService = game:GetService("BadgeService")
local badgeId = 0

    game.Players.PlayerAdded:Connect(function(player)
    --I dont need to create the leaderboard since the main script already does it
    local scoreVal = player.leaderstats.scoreVal
    --would i have to put a while true loop here to make the script check everytime when the score changes or does it always check if the score changes even without a while loop
          scoreVal.Changed:Connect(xpcall(function() --im confused as to if this only happens once of all the time
                if scoreVal.Value >= 10 and not badgeService:UserOwnsBadgeAsync(player.UserId, badgeId) then
                      badgeService:AwardBadge(player.UserId, badgeId)
                end
          end))
    end)`