Script to award badge not working

No. He needs to constantly check it.

While loop inside the playerAdded function will do that.

He has a loop.

Writing this to bypass characters.Writing this to bypass characters.

@Lostscrews13 Script to award badge not working - #16 by Fid6et

This needs to be in a script run on the server, not a local script run on the client’s computer. Create a function to set up a player and connect to the pointvalue’s updated connection.

The main function is the setupPlayer function. It sets up a player and handles giving badges for their points. It is run once for all existing players, and every time a player joins the game using the PlayerAdded event.

Inside the function, it will wait until the player has a leaderstats folder and a Points indicator inside it. Once there, the function will create an onUpdate function. This function is to be run every time the player’s points update and gives badges accordingly.

The onUpdate function is run once (in case the player already has enough points to be eligible for a badge), and every time the player’s points update.

These additional measures are useful since by the time the script loads, a player might have already loaded in and will be accounted for. Also, if a player joins with enough points but does not have the appropriate badge(s), they will be automatically given upon join.

local BadgeService = game:GetService("BadgeService")
local Players = game:GetService("Players")

-- function to set up a player
function setupPlayer(player)
    -- wait until the player has leaderstats and points
    -- since they are being added by another script/thread, it's best to yield for them
    local leaderstats = player:WaitForChild("leaderstats")
    local pointsIndicator = leaderstats:WaitForChild("Points")

    -- function to check the player's points and give badges accordingly
    local function onUpdate()
        -- if the player has more than 280 points
        if pointsIndicator.Value > 280 then
            -- give the player a badge
            BadgeService:AwardBadge(player.UserId, 2124653614)
        end
    end

    -- run the onUpdate function incase the player is eligible for a badge already
    onUpdate()
    -- run the onUpdate function every time the points value has changed
    pointsIndicator.Changed:Connect(onUpdate)
end

-- set up any players when they join the game
Players.PlayerAdded:Connect(function(setupPlayer)

-- set up all existing players
for _, player in pairs(Players:GetPlayers()) do
    setupPlayer(player)
end
1 Like

Sigh. Why does no one listen to me? ;-;

This code seems pretty errored.
Put it in ServerScriptService, as a Server Script, with this code.

game.Players.PlayerAdded:Connect(function(Player)
Player.leaderstats.Points.Changed:Connect(function(NewVal)
if NewVal >= 280 then
print("CHAINSAW")
game:GetService("BadgeService"):AwardBadge(Player.UserId,2124653614)
end
end)
end)

I think that should work.

Having a loop isn’t the best option, especially when Roblox provides events to bind to.

1 Like

He wants this as a constant, and not only when the player joins.

Yes, then use a Changed event on the points, like in my code, and hers/his.
Loops cause lag!

It is. Every time a player’s points change, the badges will be given accordingly. Please read my post and the comments in the code.

Your script can be greatly simplified.

game.Players.PlayerAdded:Connect(function(player)
    if player:WaitForChild("leaderstats"):FindFirstChild("Points") then
       player.leaderstats.Points.Changed:Connect(function(points)
          if points >= 280 then
          -- badge award stuff goes here
          end
       end)
    end
end)
4 Likes
game:GetService("Players").PlayerAdded:Connect(function(player)
    local points = player:WaitForChild("leaderstats", math.huge):WaitForChild("Points") 
    points:GetPropertyChangedSignal("Value"):Connect(function()
        if points.Value >= 280 then
          -- badge award stuff goes here
        end
    end)
end)
1 Like

There’s no advantage to adding a math.huge, as the only thing it does is prevent the warning in the output (which is completely harmless, and even useful).

Yep, that is why i put it there, and there is no point of seeing the yellow text in the output if you know it will exist.
You are also correct that the yellow text is useful, but if you are not completely sure if it will exist, use :WaitForChild(item, 30)

The warning only comes up after a few seconds, and by then the leaderstats and points should be added by the other script. If the warning comes up, something is wrong.

I haven’t tested this but it should work, pretty simple.

local BadgeService = game:GetService("BadgeService")
local Players= game:GetService("Players") 
--LocalPlayer doesn't exist server side
--make sure this is serverside and make sure it's in a normal Script.

local REQ_AWARD = 280
local AWARD_ID = 2124653614

--// PLayer Joined, let's set it up
Players.PlayerAdded:Connect(function(player)
    local points = player.leaderstats:WaitForChild("Points")
    --// On points changed we want to check and award.
    points.Changed:Connect(function(newVal)
        if newVal <= REQ_AWARD then return end -- Doesn't meet req.
        print("Award | Chainsaw")
        BadgeService:AwardBadge(player.UserId, AWARD_ID)
    end)
end)

I’d always frown upon using while true do for almost anything as you can so easily damage the performance of your game or even make it unplayable.

A much better solution is setting up events when a value has been updated so only when something of relevance has happened does any of your code run. This is the beauty of event lead programming.

2 Likes

Thank you all for your help! I will try and go through all your responses until one works. Thanks!

Still doesn’t work… what is newVal? Was I supposed to put a number there?

YES!! Thank you! It works! I was looking forwards to this, because now, my game might get a few more plays, since it now has a badge and a shop. Thanks!

1 Like