So, I'm having an issue with a certain script of mine. It's a badge awarder script that also prints in chat who received it. Here is the script:
local bs = game:GetService("BadgeService") local kill_request = 5 local badge_id = 00000000 local badge_Chat = game.ReplicatedStorage.Chat game.Players.PlayerAdded:Connect(function(newPlayer) newPlayer.CharacterAdded:Connect(function() local Data = newPlayer:WaitForChild("Data") local kill_stat = Data.InGameStats.Kills kill_stat.Changed:Connect(function() if kill_stat.Value == kill_request then if bs:UserHasBadgeAsync(newPlayer.UserId, badge_id) then print(newPlayer.Name .. " already has the 5 kills badge.") else bs:AwardBadge(newPlayer.UserId, badge_id) local gui = script.RewardGUI local copygui = gui:Clone() copygui.Parent = game.Players[newPlayer.Name].PlayerGui print(newPlayer.Name .. " was awarded the 5 kills badge!") badge_Chat:FireAllClients({ Name = "", Message = newPlayer.Name .. " has earned the badge: 5 Kills!", PlayerTags = {"Server"}, }) end end end) end) end)
The script works as intended. It awards the badge when it's supposed to, as well as fires the chat event and creates the message correctly. HOWEVER, it doesn't do it just once. It will print in the console multiple times as well as create duplicate chats. It's never a set number, it'll range from like 2 to 6 duplicates. I am assuming this is due to lag/latency which is making it fire multiple times. If that is the case, would Debounce be the way to go in order to fix this? If so, can someone link me to a good Debounce source/tutorial?
Your if kill_stat.Value == kill_request then
statement is comparing against an exact value 5. That block will be entered presumably when kills goes from 4 to 5, and then not again if it increments to 6 or beyond. Because of this, a debounce is not going to solve your problem.
Your problem is that the kill_stat "Data" object is a persistent child of the Player, and you're connecting a new anonymous function handler to the kill_stat.Changed event on CharacterAdded. That's every time the player respawns. You're not using the return value from Connect(), so you have no reference to the closure, so you can't be cleaning it up with a Disconnect() in CharacterRemoving. So when a player gets 5 kills, you are trying to award them the badge exactly as many times as they have spawned their character during their play session.