BindableEvent firing twice for no reason..?

I’m using BindableEvents for my server scripts to communicate with each other, but I am so frustrated and confused on why they fire twice only in this script. I’ve been trying to debug this for a few hours now but no luck. I’ve checked if the main event connection fires twice (humanoid.Died), but I’ve checked and it only fires once. Everything else in the script seems to run only once except for the BindableEvents, which fire twice for no reason.

This is the script it’s firing twice from. All of the request BindableEvents seem to fire twice, and make money and bounty doubled.

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(Char)
		enabled = false
		Char.Humanoid.Died:connect(function()
			--print("Char died.")
			enabled = true
			if enabled then
				local killer = getKillerOfHumanoidIfStillInGame(Char.Humanoid)
				if killer then
					local BountyMoneyClaim = GetValue(player, "Bounty") 
					if BountyMoneyClaim <= 100 and BountyMoneyClaim > 0 then
						statRequests.requestAdd:Fire(killer, (BountyMoneyClaim * 50), "Cash")
						moneyLost = BountyMoneyClaim * 50
						statRequests.requestSubtract:Fire(player, moneyLost, "Cash")
					elseif BountyMoneyClaim > 100 then
						moneyLost = 5000
						statRequests.requestAdd:Fire(killer, 5000, "Cash")
						statRequests.requestSubtract:Fire(player, moneyLost, "Cash")
					elseif BountyMoneyClaim == 0 then
						statRequests.requestAdd:Fire(killer, 50, "Cash")
						moneyLost = 50
						statRequests.requestSubtract:Fire(player, moneyLost, "Cash")
					end
					local msg = script.K_GUI:Clone() 
					statRequests.requestAdd:Fire(killer, 2, "Bounty")
					msg.Parent = killer.PlayerGui.MainGUI:WaitForChild("KILLFEED")
					local msg2 = script.K_GUI:Clone() 
					msg2.Parent = player.PlayerGui.MainGUI:WaitForChild("KILLFEED")
					for i, v in pairs(killer.PlayerGui.MainGUI.KILLFEED:GetChildren()) do
						if v.Name == "K_GUI" then
							if v and deb == true then
								deb = false
								local Offset = script:WaitForChild("Offset1")
								Offset.Value = v:WaitForChild("Frame").Position.Y.Offset
							--print("The offset is " ..Offset.Value.." and the frame offset is "..v:WaitForChild("Frame").Position.Y.Offset)
								msg.Frame.txt.Text = kill[math.random(1, #kill)] ..player.Name .. ". The bounty on this player was " .. AddCommas(BountyMoneyClaim) .. ", so you received $" .. AddCommas(moneyLost).."." 
								v:WaitForChild("Frame"):TweenPosition(UDim2.new(0, 0, 0, v:WaitForChild("Frame").Position.Y.Offset - 35), "Out", "Quad", wait())
								deb = true
							end
						end
					end
				
					msg2.Frame.txt:TweenPosition(UDim2.new(0, 0, 0, 0), "Out", "Quad", 3)
					if GetValue(player, "Cash") <= 0 then 
						msg2.Frame.txt.Text = death[math.random(1, #death)] .. killer.Name .. ", but you didn't lose money because you didn't have any to begin with."
						statRequests.requestChange:Fire(player, 0, "Bounty")
					else
						msg2.Frame.txt.Text = death[math.random(1, #death)] .. killer.Name .. " and lost $" .. AddCommas(moneyLost).. "."
						statRequests.requestChange:Fire(player, 0, "Bounty")
					end 
					
					PlaySoundInPlayer(killer)
					wait(7)
					RemoveSoundsInPlayer(killer)
					msg:Destroy()
					enabled = false
				end	
			end
			
		end)
	end)
end)

This is the part from the data handling script, and it processes requests made to it by other server scripts.

	statRequests.requestAdd.Event:Connect(function(plr, amount, index)
		--print("Received!")
		local key = tostring("Player_"..plr.UserId)
		playerData[key]:Increment(index, amount)
		if index == "Cash" then
			updateMoney:FireClient(plr, playerData[key][index])
			MoneyEffect(plr, amount)
		else
			updateTable[index]:FireClient(plr, playerData[key][index]) 	
		end
	end)
	
	statRequests.requestSubtract.Event:Connect(function(plr, amount, index)
		--print("Received!")
		local key = tostring("Player_"..plr.UserId)
		playerData[key]:Subtract(index, amount)
		if index == "Cash" then
			updateMoney:FireClient(plr, playerData[key][index])
			SubtractEffect(plr, amount)	
		else
			updateTable[index]:FireClient(plr, playerData[key][index])
		end
	end)
	
	statRequests.requestChange.Event:Connect(function(plr, value, index)
		print("Received change! Changed "..index.." to "..value)
		local key = tostring("Player_"..plr.UserId)
		playerData[key]:Change(index, value)
		updateTable[index]:FireClient(plr, playerData[key][index]) 
	end)	
	
	statRequests.retrieveValue.OnInvoke = function(plr, index)
		local key = tostring("Player_"..plr.UserId)
		local value =  playerData[key][index]
		return value
	end

Totally no idea about how it fires two times when Humanoid dies it should only fire once, You could add tick() check for the data handling script just for a debounce.

I just tried debouncing all of the fires but it didnt work :frowning:

Also, .Died isn’t firing twice. Only the BindableEvents are, and I’m so lost

I don’t see much other than you firing requestAdd for a second time outside of your if/elseif statements

statRequests.requestAdd:Fire(killer, 2, "Bounty")


If I were you I would use the GOAT shortcut Ctrl + Shift + f which will allow you to search all of your code for a string of text, in this case something like

reqeustAdd:Fire(

You can then put a distinct print before each of these so you know exactly what is firing your BindableEvent

and repeat this for the other BindableEvents you have


you can rest assured, BindableEvents are not buggy and will not misbehave

1 Like

The requestAdd outside of the conditional is for adding bounty, and the requestAdds inside of the conditional are to determine how much cash to add.

Both of them fire twice

I’ll try this though, thanks for your input

1 Like

Turns out there was a bug with studio. I don’t know how, but it cloned my script but I couldn’t see the cloned script in the session I was doing this in. After opening studio a couple of hours later, I could see two scripts

Edit: Never mind, it didn’t work anyway…

Alright, I fixed it by converting the BindableEvents to BindableFunctions so that it would yield until the invoked function ran. I also had a 1 second wait (waiting for a tween to finish) in some of my code connected the old BindableEvents which would cause the response to be delayed, so I just put them into a coroutine and it fixed the problem.

1 Like