Badge not awarding?

Hello! I am having trouble with awarding badges to player when they pick up an item that they don’t already have in a folder.

I was trying to make it so when a player finds a new melon, they will get a UI pop up and get awarded the badge with the badge of that melon. In contrast, if they already have the melon, they would get a notification saying that they already have the melon.

How it works is when player walked into a new melon, a clones value will be put into the “melonsCollected” folder and save it there. If the value is there, the player already have the melon, if it’s not, the player will be awarded the badge and the award GUI will pop up

But when I played, and resetted all my data and walk into a melon i don’t have, it passed it onto the “alreadyHave” event instead of awarding player the badge and make the GUI pop up.

here is the main script:

local melonsFolder = script.Parent
local replicatedStorage = game:GetService("ReplicatedStorage")
local melonValuesFolder = replicatedStorage:FindFirstChild("MelonValues")
local BS = game:GetService("BadgeService")
local Players = game:GetService("Players")
local badgeEvent = replicatedStorage.RemoteEvents.badgeGiver
local newCollectedEvent = replicatedStorage.RemoteEvents.newCollected



-- Function to handle the touch event
local function onPartTouched(other, melonPart)
	-- Check if the thing that touched the part is a player's character
	local player = game.Players:GetPlayerFromCharacter(other.Parent)
	if player then
		-- Get the name of the part that was touched
		local touchedPartName = melonPart.Name
		-- Find the corresponding value in the MelonValues folder
		local valueToClone = melonValuesFolder:FindFirstChild(touchedPartName)
		if valueToClone then
			-- Clone the value and parent it to the target folder
		if player:WaitForChild("melonsCollected"):FindFirstChild(melonPart.Name) then return end

				local targetFolder = player:WaitForChild("melonsCollected")
				local clonedValue = valueToClone:Clone()
				clonedValue.Parent = targetFolder
				clonedValue.Value = true
			end
				
		end
	end

function debounce(func)
	local isRunning = false
	return function(hit)
		if not isRunning then
			isRunning = true
			func(hit)
			wait(3)
			isRunning = false
		end
	end
end

local function giveBadge(player, badgeid, imageid, name)
	local success, badgeInfo = pcall(function()
		return BS:GetBadgeInfoAsync(badgeid)
	end)
	if success then
		if badgeInfo.IsEnabled then
	local success, result = pcall(function()
	newCollectedEvent:FireClient(player, badgeid, imageid, name)
	print(badgeid)
		return BS:AwardBadge(player.UserId, badgeid)
	end)
			print("passed")
	if not result then
		badgeEvent:FireClient(player, badgeid, imageid)
			end
		end
	end
end

-- Connect the touch event to all parts in the Melons folder
for _, part in ipairs(melonsFolder:GetChildren()) do
	if part:IsA("BasePart") then -- Ensure the instance is a part
		part.Touched:Connect(debounce(function(other)
			local player = game.Players:GetPlayerFromCharacter(other.Parent)
			onPartTouched(other, part)
			if player then
				giveBadge(player, part.BadgeID.Value, part.MainDecal.Texture, part.Name)
				
				end
		end))
	end
end

Here is the remoteEvents manager:

local replicatedStorage = game:GetService("ReplicatedStorage")
local melonValuesFolder = replicatedStorage:FindFirstChild("MelonValues")
local BS = game:GetService("BadgeService")
local Players = game:GetService("Players")
local badgeEvent = replicatedStorage.RemoteEvents.badgeGiver
local newCollectedEvent = replicatedStorage.RemoteEvents.newCollected
local StarterGUI = game:GetService("StarterGui")
local mushroomAwarded = StarterGUI:WaitForChild("FoundGUI")
local frame = mushroomAwarded:WaitForChild("Frame")
local melonName = frame:WaitForChild("Name")
local melonImage = frame:WaitForChild("Image")


badgeEvent.OnClientEvent:Connect(function(player, imageid)
	StarterGUI:SetCore("SendNotification", {
		Title = "Uh Oh!",
		Text = "You've already collected this melon!🍈🍉",
		Duration = 3,
		Icon = imageid
	})
end)

newCollectedEvent.OnClientEvent:Connect(function(player, imageid, name)
	melonImage.Image = imageid.."!"
	melonName.Text = name
	frame.Visible = true
	wait(5)
	frame.Visible = false
end)

Here is a video for visual:

Help are appreciated!!!

4 Likes

Hi! Looking through your script, it seems pretty solid, so I would assume the issue probably lies in the part, of the following:

local success, result = pcall(function()
	newCollectedEvent:FireClient(player, badgeid, imageid, name)
	print(badgeid)
		return BS:AwardBadge(player.UserId, badgeid)
	end)
			print("passed")
	if not result then
		badgeEvent:FireClient(player, badgeid, imageid)
			end
		end
	end

I was running some tests, and it seems when printing the following statement:

BS:AwardBadge(player.UserId, badgeid)

which returns as false, even when I did not have the badge. This might be the case because it actually can’t award the badge in Studio (?) When testing it in the actual game, it works like a charm, so you might want to check it out to see if you get a different result within the actual game than studio. I am very sure that would be the cause of the error because the code seems pretty solid for the most part. Hope this helps!

3 Likes

Ah, nice! Ty for that! I tested and it worked well! Although it gave me the error along with the badge still. I think that once i touched the part it also checks and treats that as I already have the melon so thats why it gave me that error. Is there any way to counteract that?

2 Likes

Ah I see! Do you mind telling me what exactly is the error you are receiving?

1 Like

I believe it’s this part where if a player already has the value of the melon in their folder, it will give a notification saying that person already owned that melon. I should’ve said the notification instead of error instead. My apologies!

image

1 Like

I think I figured it out! Do you mind showing me your full serverscript for awarding the badge?

1 Like

It’s the first script I sent in the original post. If you need any extra details lmk!

2 Likes

So I was also facing the same issue, the problem was that earlier when trying to debug I happened to do the following:

print(BadgeService:AwardBadge(player.UserId, badgeId))

which runs the function, then prints the output, so when I ran the function later, it was actually running twice, which was a small oversight. I will share the script I used, since I structured some parts a little differently, including the debounce section, which cleared the other problems as well.

ServerScript:

local part = script.Parent
local BadgeService = game:GetService("BadgeService")
local Players = game:GetService("Players")

local RS = game:GetService("ReplicatedStorage")

local give = RS:WaitForChild("newCollected")
local nogive = RS:WaitForChild("badgeGiver")

local BADGE_ID = x -- Your badge id goes here
local debounce = false



local function awardBadge(player, badgeId)
	-- Fetch badge information
	
	local success, badgeInfo = pcall(function()
		return BadgeService:GetBadgeInfoAsync(badgeId)
	end)
	print(BadgeService:GetBadgeInfoAsync(badgeId))

	if success then
		-- Confirm that badge can be awarded
		if badgeInfo.IsEnabled then
			-- Award badge
			print("Here")
			local awardSuccess, result = pcall(function()
				return BadgeService:AwardBadge(player.UserId, badgeId)
			end)
			
			if awardSuccess then
				give:FireClient(player)
			end

			if not awardSuccess then
				-- the AwardBadge function threw an error
				warn("Error while awarding badge:", result)
			elseif not result then
				-- the AwardBadge function did not award a badge
				nogive:FireClient(player)
				warn("Failed to award badge.")
			end
		end
	else
		warn("Error while fetching badge info: " .. badgeInfo)
	end
end

part.Touched:Connect(function(hit)

	
	if not debounce then
		debounce = true
		local char = hit.Parent
		print(hit.Parent)
		local player = Players:GetPlayerFromCharacter(char)
		awardBadge(player, BADGE_ID)
		task.wait(3)
		debounce = false
	end
end)


1 Like

when you create badges then roblox automatically awards them to you, so youll have to remove it from your inventory for it to work

1 Like

Hey! tysm for your effort! I tried to replicate ur code into mine but whenever I get to the “Touched” function it cant seem to go pass the “print(“passed2”)” line. Is there a reason for that? Is it bc of the variables im firing from the server to the client?

-- MelonTouchCloneScript
-- This script clones a value from the "MelonValues" folder in ReplicatedStorage
-- and puts it into another folder when a player touches one of the parts in the "Melons" folder.

local melonsFolder = script.Parent
local replicatedStorage = game:GetService("ReplicatedStorage")
local melonValuesFolder = replicatedStorage:FindFirstChild("MelonValues")
local BS = game:GetService("BadgeService")
local Players = game:GetService("Players")
local badgeEvent = replicatedStorage.RemoteEvents.badgeGiver
local newCollectedEvent = replicatedStorage.RemoteEvents.newCollected

local debounce = false


-- Function to handle the touch event
local function onPartTouched(other, melonPart, imageid)
	-- Check if the thing that touched the part is a player's character
	local player = game.Players:GetPlayerFromCharacter(other.Parent)
	if player then
		-- Get the name of the part that was touched
		local touchedPartName = melonPart.Name
		-- Find the corresponding value in the MelonValues folder
		local valueToClone = melonValuesFolder:FindFirstChild(touchedPartName)
		if valueToClone then
			-- Clone the value and parent it to the target folder
			if player:WaitForChild("melonsCollected"):FindFirstChild(melonPart.Name) then 
				badgeEvent:FireClient(other, melonPart, imageid)
				print(melonPart.Name)
				return 
			end
				local targetFolder = player:WaitForChild("melonsCollected")
				local clonedValue = valueToClone:Clone()
				clonedValue.Parent = targetFolder
				clonedValue.Value = true
			end
				
		end
	end


local function giveBadge(player, badgeid, imageid, name)
	local success, badgeInfo = pcall(function()
		return BS:GetBadgeInfoAsync(badgeid)
	end)
	print(BS:GetBadgeInfoAsync(badgeid))
	
	if success then
		if badgeInfo.IsEnabled then
			local awardSuccess, result = pcall(function()
				return BS:AwardBadge(player.UserId, badgeid)
			end)
			
			if awardSuccess then
				newCollectedEvent:FireClient(player, badgeid, imageid, name)
			end
	
			if not awardSuccess then
				-- the AwardBadge function threw an error
				warn("Error while awarding badge:", result)
				return
			elseif not result then
				-- the AwardBadge function did not award a badge
				warn("Failed to award badge.")
			--	badgeEvent:FireClient(player, badgeid, imageid, name)
				--print(name)
				return
			end
		end
	else
		warn("Error while fetching badge info: " .. badgeInfo)
	end
end

-- Connect the touch event to all parts in the Melons folder
for _, part in ipairs(melonsFolder:GetChildren()) do
	if part:IsA("BasePart") then -- Ensure the instance is a part
		part.Touched:Connect(function(hit)
			if not debounce then
				debounce = true
				local char = hit.Parent
				print(hit.Parent)
				local player = game.Players:GetPlayerFromCharacter(char)
			if player then
				print("passed2")
				giveBadge(player, part.BadgeID.Value, part.MainDecal.Texture, part.Name)
				onPartTouched(hit, part, part.MainDecal.Texture)
				task.wait(3)
				debounce = false
				end
			end
		end)
	end
end

This is my local script:

local replicatedStorage = game:GetService("ReplicatedStorage")
local melonValuesFolder = replicatedStorage:FindFirstChild("MelonValues")
local BS = game:GetService("BadgeService")
local Players = game:GetService("Players")
local badgeEvent = replicatedStorage.RemoteEvents.badgeGiver
local newCollectedEvent = replicatedStorage.RemoteEvents.newCollected
local StarterGUI = game:GetService("StarterGui")
local mushroomAwarded = StarterGUI:WaitForChild("FoundGUI")
local frame = mushroomAwarded:WaitForChild("Frame")
local melonName = frame:WaitForChild("Name")
local melonImage = frame:WaitForChild("Image")


badgeEvent.OnClientEvent:Connect(function(other, melonPart, imageid)
	StarterGUI:SetCore("SendNotification", {
		Title = "Uh Oh!",
		Text = "You've already collected "..tostring(melonPart.Name).."!",
		Duration = 3,
		Icon = imageid
	})
end)

newCollectedEvent.OnClientEvent:Connect(function(player, badgeid, imageid, name)
	melonImage.Image = imageid.."!"
	melonName.Text = tostring(name)
	frame.Visible = true
	wait(5)
	frame.Visible = false
end)
1 Like

No problem at all! Just to clarify, did you get the 1st print statement in the “giveBagde” function and the print(“passed2”)?

1 Like

I just tested it in the main game and it seems like results are different everytime i rejoin, could I share you the game and u test it?

1 Like

Sure, that sounds good with me!

2 Likes