Player Removing Event Callback Not Firing

I’m currently working on a capture-the-flag style game. When a player touches the flag, it gets welded onto a player. The issue is, when a player holding the flag dies, the flag dies along with them, rather than falling to the ground as I designed.

For some weird reason, the PlayerRemoving event callback (in which the flag is supposed to fall off) does not fire. The print statements I placed inside are never displayed. I have placed the entire script below. Does anyone have any suggestions? Thanks!

-- local flag = script.Parent
local winEvent = game.ServerScriptService.CheckFlagWin
local holding = false
local holder = nil

function PickupFlag(player)
	local torso
	if player.Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
		torso = player.Character:FindFirstChild('Torso')
	else
		torso = player.Character:FindFirstChild('UpperTorso')
	end
print("pickingup")
	flag.Anchored = false
	flag.CanCollide = false
	
	--weld flag to player
	local weld = Instance.new("Weld", flag)
	weld.Name = "PlayerFlagWeld"
	weld.Part0 = flag
	weld.Part1 = torso
	weld.C0 = CFrame.new( 0, 0.5, -1) --x, y, z, X, Y, Z  -- (0,.5,-1)
	
	holding = true
	holder = player
end

--check if player brought the flag
function CheckWin(plr)
	if holding and plr == holder then
		game.Workspace.FlagCaptured.Value = true --set end game condition
	end
end

--drop flag
game:GetService("Players").PlayerRemoving:Connect(function(plr) --player died or left game
	print(plr)
	if holding and plr == holder then
		print("droppingFlag")
		flag:FindFirstChild("PlayerFlagWeld"):Destroy() --destroy weld to player
		--keep from falling through ground
		flag.CanCollide = true
		holder = nil
		holding = false
	end
end)

script.Parent.Touched:connect(function(part)
	if (not holding) then --flag isn't carried by another player
		
		local humanoid = part.Parent:FindFirstChild("Humanoid")
	
		if not humanoid then
			humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
		end
	
		local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
		
		if humanoid ~= nil and player.TeamColor == BrickColor.new("Really red")then --player is an offense player
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			PickupFlag(player)
		end
	end
end)

winEvent.Event:Connect(CheckWin)

PlayerRemoving only fires IF the player is leaving the server.

If you want to check if the Player’s Character died, you can use Humanoid.Died or Player.CharacterRemoving.

PlayerAdded isn’t firing either after I tried your suggestion.

Player removing fires to the server when a given client disconnects. What you are looking for is when the players dies. We can instead of using the event listen “PlayerRemoving” we can use a event from the humanoid instance of the player we want to listen to called “Died”. Note, you should be requipping the flag after the players character has loaded and make sure to update data that might have been affected by the death (such as object values in the character model?)

I didn’t say anything about PlayerAdded???

Sorry, should have clarified. The documentation shows that you need to put characterRemoving into a playerAdded event. There doesn’t appear to be any other way to get characterRemoving to fire.

Also, instead of assigning values to nil for placeholder reasons, you can simply not assign it. Like so:

local Player = nil
-- Turns into
local Player;

You could use the HumanoidRootPart instead of the player’s torso.

And, @OP, supposedly the player already has joined before you listened to the event. You could possibly try using GFink’s Catch-All PlayerAdded/Removing Event Module.

Other thing, no, you don’t need to listen to the PlayerAdded event. CharacterRemoving's self is the player, meaning you just need a player to listen to the value. And this player should be ‘holder’.

I think you just inspired a solution, thanks! PlayerAdded was likely not firing since it is part of a map that loads in from server storage meaning all the PlayerAdded events already fired.

Updated code, still not working

local flag = script.Parent
local winEvent = game.ServerScriptService.CheckFlagWin
local holding = false
local holder = nil

function PickupFlag(player)
	local torso
	if player.Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
		torso = player.Character:FindFirstChild('Torso')
	else
		torso = player.Character:FindFirstChild('UpperTorso')
	end

	flag.Anchored = false
	flag.CanCollide = false
	
	--weld flag to player
	local weld = Instance.new("Weld", flag)
	weld.Name = "PlayerFlagWeld"
	weld.Part0 = flag
	weld.Part1 = torso
	weld.C0 = CFrame.new( 0, 0.5, -1) --x, y, z, X, Y, Z  -- (0,.5,-1)
	
	holding = true
	holder = player
	
	print("setting connection")
	--drop flag on death
	player.CharacterRemoving:Connect(function(character) --player died or left game
		print(game.Players:GetPlayerFromCharacter(character))
		if holding and game.Players:GetPlayerFromCharacter(character)== holder then
			print("droppingFlag")
			flag:FindFirstChild("PlayerFlagWeld"):Destroy() --destroy weld to player
			--keep from falling through ground
			flag.CanCollide = true
			holder = nil
			holding = false
		end
	end)
end

--check if player brought the flag
function CheckWin(plr)
	if holding and plr == holder then
		game.Workspace.FlagCaptured.Value = true --set end game condition
	end
end


script.Parent.Touched:connect(function(part)
	if (not holding) then --flag isn't carried by another player
		
		local humanoid = part.Parent:FindFirstChild("Humanoid")
	
		if not humanoid then
			humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
		end
	
		local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
		
		if humanoid ~= nil and player.TeamColor == BrickColor.new("Really red")then --player is an offense player
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			PickupFlag(player)
		end
	end
end)


winEvent.Event:Connect(CheckWin)