Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do you award a badge with a certain amount of leaderstats?

Asked by 8 years ago

I'm trying to make a FPS game, and if you get 20 kills, you get a badge. I don't know why it's not working, as the BadgeID is correct and the "currency" is correct as well. Can someone tell me why it's not working? And can tell me the mistakes so I can solve it?

currency = "Kills"
BadgeID = 561649914

while true do 
    wait() 
    for i,v in pairs(game.Players:getPlayers()) do 
        if v.leaderstats[currency].Value > 19 then
            ser = game:getService("BadgeService") 
            ser:AwardBadge(v.UserId,BadgeID) 
        end 
    end 
end 

1 answer

Log in to vote
0
Answered by
evaera 8028 Trusted Badge of Merit Snack Break Game Jam Winner Moderation Voter Administrator Community Moderator Super Administrator
8 years ago
Edited 8 years ago

Good job on tabbing your code and thinking about a way to solve your problem- you're almost there!

Some things I would change:

  1. Use local variables.
  2. Don't use deprecated methods, such as getPlayers and getService. You should use GetPlayers and GetService in future code.
  3. Give variable names a real meaning, so instead of ser you could use BadgeService as a variable.
  4. Don't redefine variables when they won't change from the previous iteration- i.e., you are redefining ser in every run of the loop, but the value of ser won't have changed. Instead, define this at the top of your script.
  5. Your code will be running every frame, since you only used wait with no arguments. This is bad because this code doesn't need to run that often, so it's just sucking up resources and contributing to lag. A more reasonable amount of time to wait is anywhere from 1 to 5 seconds. This may not seem like a huge change, but you will be running the code far less and achieving the same experience for the player. (This is just for reference- this isn't the approach I suggest for this specific problem, for that, see #6).
  6. Since ROBLOX is an event-driven platform, it will be better to check if the player has reached enough Kills using an event rather than a loop. We can use the Changed event of the Int/NumberValue you used to see when the value changes.

All together now:

local BadgeService = game:GetService("BadgeService")

local function hookPlayerKillsAchievement(player)
    local function checkPlayerKills(kills)
        if kills >= 20 then
            BadgeService:AwardBadge(player.UserId, 561649914)
        end
    end

    player:WaitForChild("leaderstats"):WaitForChild("Kills").Changed:connect(checkPlayerKills)
end

-- Iterate over any players that might already be in the game
local players = game.Players:GetPlayers()
for i = 1, #players do
    hookPlayerKillsAchievement(players[i])
end

-- Connect the event
game.Players.PlayerAdded:Connect(hookPlayerKillsAchievement)

Some important things to remember:

  • This code will only work when executed in a Script, not a LocalScript
  • This code will only work in online mode, not in Studio.
  • The Changed event of *Value objects acts differently than in other objects- its first parameter is the new value, not the property changed as seen in other types.
1
Thank you so much! I'll remember the information that you gave me for my future scripting! BARBARIAN59 25 — 8y
Ad

Answer this question