Help with FireClient Error

Hello, so I commissioned someone to make a shadow boxing system, and when multiple people joined, it started to bug out. I checked the log and read this error.
image
How would I be able to fix this?

Here is part of the code that give the error

PP.Triggered:Connect(function(Player)
	local Found = false
	for i, v in pairs(Corners) do
		if v.Occupant.Value == Player.Character then
			Found = true
		end
	end
	if Found then return end
	Occupants = Occupants + 1
	local Corner = Corners[Occupants]
	Corner.Occupant.Value = Player.Character
	Player.Backpack.Data.Ring.Value = script.Parent

	Billboard.TextLabel.Text = Occupants.. "/2"

	if Occupants == 2 then
		coroutine.wrap(function()
			wait(1)
			Billboard.Enabled = false
		end)()
		PP.Enabled = false
		local RandomNumber = math.random(1,2)
		Attacker.Value = Corners[RandomNumber].Occupant.Value
		Defender.Value = Corners[((RandomNumber == 1) and 2) or 1].Occupant.Value

		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Attacker.Value))     <----- Error
		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Defender.Value))
		wait(3)
		StartFight()
		PP.Enabled = true
		Billboard.Enabled = true
	end
end)

for i, v in pairs(Corners) do
	v.Occupant.Changed:Connect(function()
		if not v.Occupant.Value then return end
		local Char = v.Occupant.Value
		local Hrp:Part = Char:FindFirstChild("HumanoidRootPart")
		if not Hrp then return end
		Char.Humanoid.WalkSpeed = 0
		Hrp.AssemblyLinearVelocity = Vector3.new()
		Hrp.CFrame = v.CFrame
		Hrp.Anchored = true
		wait()
		Char.Humanoid.WalkSpeed = 16
	end)
end
2 Likes
Attacker.Value = Corners[RandomNumber].Occupant.Value
Defender.Value = Corners[((RandomNumber == 1) and 2) or 1].Occupant.Value

Is Corners[RandomNumber] a Seat? If so, then you don’t need to use Value. What I mean is like this:

Attacker.Value = Corners[RandomNumber].Occupant
Defender.Value = Corners[((RandomNumber == 1) and 2) or 1].Occupant
1 Like

So the Corners are parts where the play is teleported to so they dont move. Basically the picture below.

Perhaps you can replace the game.Players:GetPlayerFromCharacter(Attacker.Value) with game.Players:FindFirstChild(Attacker.Value.Name)?

game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:FindFirstChild(Attacker.Value.Name))
1 Like

Should I do that with the defender as well?

1 Like

Sure, try that with the defender too.

1 Like

I think the problem is, when the play joins a ring, I dont have a leave button for them to leave the ring, so they leave the game instead which has the system still “count them” as being in the ring. Then another player joins and the queue starts with only 1 person. That person leaves and now the ring cannot be played in. Is there any possibility I can show you on Discord of what I mean? I know im not supposed to hire here but to fix this bug and I can pay you whatever? The commissioner closed the ticket and pretty much quit roblox for exams.

1 Like

I understand what you mean. You don’t have to pay me, because I like to help for free.
At the end of the code, when you check for new occupants, you can try this:

for i, v in pairs(Corners) do
	v.Occupant.Changed:Connect(function()
		if not v.Occupant.Value then
			Occupants -= 1
			return
		end
		local Char = v.Occupant.Value
		local Hrp:Part = Char:FindFirstChild("HumanoidRootPart")
		if not Hrp then return end
		Char.Humanoid.WalkSpeed = 0
		Hrp.AssemblyLinearVelocity = Vector3.new()
		Hrp.CFrame = v.CFrame
		Hrp.Anchored = true
		wait()
		Char.Humanoid.WalkSpeed = 16
	end)
end

And, at the line where you determine the corner to assign the player, change it to this:

local Corner = Corners[1]

if Corner.Occupant.Value ~= nil then
	Corner = Corners[2]
end
1 Like

Here is the whole script, where would I add the second part?

local PP = script.Parent.Proximity.ProximityPrompt
local Billboard = script.Parent.Billboard.BillboardGui

local MPS = game:GetService("MarketplaceService")

local Attacker = script.Parent.Attacker
local Defender = script.Parent.Defender

local Corners = {script.Parent.Corner1, script.Parent.Corner2}
local Occupants = 0


local function StartFight()
	local AttackingPlayer:Player = game.Players:GetPlayerFromCharacter(Attacker.Value)
	local DefendingPlayer:Player = game.Players:GetPlayerFromCharacter(Defender.Value)

	AttackingPlayer.Backpack.Data.CurrentLives.Value = 20
	DefendingPlayer.Backpack.Data.CurrentLives.Value = 20

	game.ReplicatedStorage.Client.ChangeIcons:FireClient(AttackingPlayer, DefendingPlayer.UserId)
	game.ReplicatedStorage.Client.ChangeIcons:FireClient(DefendingPlayer, AttackingPlayer.UserId)

	local Switch = false
	local Rows = {}
	while (DefendingPlayer.Backpack.Data.CurrentLives.Value > 0) do

		if Switch then
			local TempPlayer = AttackingPlayer
			AttackingPlayer = DefendingPlayer
			DefendingPlayer = TempPlayer
			Switch = false
		end

		AttackingPlayer.Backpack.Data.State.Value = "Attack"
		DefendingPlayer.Backpack.Data.State.Value = "Defend"

		repeat task.wait() until (AttackingPlayer.Backpack.Data.ChosenMove.Value ~= "") and (DefendingPlayer.Backpack.Data.ChosenMove.Value ~= "")
		local AttackerChose = AttackingPlayer.Backpack.Data.ChosenMove.Value
		local DefenderChose = DefendingPlayer.Backpack.Data.ChosenMove.Value

		print("Attacker Chose", AttackerChose)
		print("Defender Chose", DefenderChose)
		local PlayedAnimation = false
		if AttackerChose == DefenderChose then
			print("Defender Loses a life, Total:", DefendingPlayer.Backpack.Data.CurrentLives.Value)
			DefendingPlayer.Backpack.Data.CurrentLives.Value -= 1

			print(Rows)
			table.insert(Rows, DefendingPlayer.Backpack.Data.ChosenMove.Value)
			for i, v in pairs(Rows) do
				PlayedAnimation = true
				AttackingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Attack"..v]):Play()
				DefendingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Defend"..v]):Play()
				wait(0.4)
			end
			if #Rows == 3 then
				DefendingPlayer.Backpack.Data.CurrentLives.Value = 0
			end
			game.ReplicatedStorage.Client.HideButton:FireClient(AttackingPlayer, "Attack", AttackerChose)
			game.ReplicatedStorage.Client.HideButton:FireClient(DefendingPlayer, "Defend", DefenderChose)
		else
			Rows = {}
			Switch = true
		end
		if not PlayedAnimation then
			AttackingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Attack"..AttackingPlayer.Backpack.Data.ChosenMove.Value]):Play()
			DefendingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Defend"..DefendingPlayer.Backpack.Data.ChosenMove.Value]):Play()
		end
		wait(1)
		AttackingPlayer.Backpack.Data.ChosenMove.Value = ""
		DefendingPlayer.Backpack.Data.ChosenMove.Value = ""
	end
	DefendingPlayer.Character.Humanoid.Health = 0
	AttackingPlayer.Character.HumanoidRootPart.Anchored = false
	AttackingPlayer.Backpack.Data.State.Value = ""
	DefendingPlayer.Backpack.Data.State.Value = ""
	AttackingPlayer.Backpack.Data.Ring.Value = nil
	DefendingPlayer.Backpack.Data.Ring.Value = nil
	Attacker.Value = nil
	Defender.Value = nil
	Occupants = 0
	Billboard.TextLabel.Text = Occupants.. "/2"
	for i, v in pairs(Corners) do
		v.Occupant.Value = nil
	end
end


PP.Triggered:Connect(function(Player)
	local Found = false
	for i, v in pairs(Corners) do
		if v.Occupant.Value == Player.Character then
			Found = true
		end
	end
	if Found then return end
	Occupants = Occupants + 1
	local Corner = Corners[Occupants]
	Corner.Occupant.Value = Player.Character
	Player.Backpack.Data.Ring.Value = script.Parent

	Billboard.TextLabel.Text = Occupants.. "/2"

	if Occupants == 2 then
		coroutine.wrap(function()
			wait(1)
			Billboard.Enabled = false
		end)()
		PP.Enabled = false
		local RandomNumber = math.random(1,2)
		Attacker.Value = Corners[RandomNumber].Occupant.Value
		Defender.Value = Corners[((RandomNumber == 1) and 2) or 1].Occupant.Value

		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Attacker.Value))
		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Defender.Value))
		wait(3)
		StartFight()
		PP.Enabled = true
		Billboard.Enabled = true
	end
end)

for i, v in pairs(Corners) do
	v.Occupant.Changed:Connect(function()
		if not v.Occupant.Value then
			Occupants -= 1
			return
		end
		local Char = v.Occupant.Value
		local Hrp:Part = Char:FindFirstChild("HumanoidRootPart")
		if not Hrp then return end
		Char.Humanoid.WalkSpeed = 0
		Hrp.AssemblyLinearVelocity = Vector3.new()
		Hrp.CFrame = v.CFrame
		Hrp.Anchored = true
		wait()
		Char.Humanoid.WalkSpeed = 16
	end)
end
1 Like
PP.Triggered:Connect(function(Player)
	local Found = false
	for i, v in pairs(Corners) do
		if v.Occupant.Value == Player.Character then
			Found = true
		end
	end
	if Found then return end
	Occupants = Occupants + 1
	local Corner = Corners[Occupants] -- Replace it here
	Corner.Occupant.Value = Player.Character
	Player.Backpack.Data.Ring.Value = script.Parent
1 Like

How would I make a simple leave button incase no one joins them?

1 Like

You can create a button that sends a signal to the server.
The server receives this signal, and finds the player in the corners, then set it’s value to nil, like this:

yourRemoveEvent.OnServerEvent:Connect(function(Player)
	for _, i in ipairs(Corners) do
		if i.Occupant.Value == Player.Character then
			i.Occupant.Value = nil
			return
		end
	end
end)
1 Like

So create a button in starter gui, paste that into a local script and thats it?

1 Like

Yes, you create the button, but the script isn’t what I mean. I mean like this:
LocalScript in the button

script.Parent.MouseButton1Down:Connect(function()
	yourRemoveEvent:FireServer()
end)

Somewhere in the main server script:

yourRemoveEvent.OnServerEvent:Connect(function(Player)
	for _, i in ipairs(Corners) do
		if i.Occupant.Value == Player.Character then
			i.Occupant.Value = nil
			return
		end
	end
end)
1 Like

So just paste that anywhere in the server after I make the remote event. It doesnt matter where?

1 Like

It doesn’t matter where, as long as it isn’t behind a while loop.

1 Like

I think I put it wrong somewhere could you just make a comment on where to

1 Like

Also when they join the ring, how would I make that button visible to show them

1 Like

You can put the event detection anywhere in the main thread, outside any functions, if statements, and loops.

After if Found then return end, add this line to show the leave button:
Player.PlayerGui.YourScreenGui.YourButton.Visible = true

To hide the button after leaving, In the LocalScript in the button, add this before firing the event:
script.Parent.Visible = false

1 Like

It seems to not be working.

local PP = script.Parent.Proximity.ProximityPrompt
local Billboard = script.Parent.Billboard.BillboardGui

local Rep = game:GetService("ReplicatedStorage")
local Event = Rep.Client.LeaveEvent

local MPS = game:GetService("MarketplaceService")

local Attacker = script.Parent.Attacker
local Defender = script.Parent.Defender

local Corners = {script.Parent.Corner1, script.Parent.Corner2}
local Occupants = 0


local function StartFight()
	
	local AttackingPlayer:Player = game.Players:GetPlayerFromCharacter(Attacker.Value)
	local DefendingPlayer:Player = game.Players:GetPlayerFromCharacter(Defender.Value)

	AttackingPlayer.Backpack.Data.CurrentLives.Value = 20
	DefendingPlayer.Backpack.Data.CurrentLives.Value = 20

	game.ReplicatedStorage.Client.ChangeIcons:FireClient(AttackingPlayer, DefendingPlayer.UserId)
	game.ReplicatedStorage.Client.ChangeIcons:FireClient(DefendingPlayer, AttackingPlayer.UserId)

	local Switch = false
	local Rows = {}
	while (DefendingPlayer.Backpack.Data.CurrentLives.Value > 0) do

		if Switch then
			local TempPlayer = AttackingPlayer
			AttackingPlayer = DefendingPlayer
			DefendingPlayer = TempPlayer
			Switch = false
		end

		AttackingPlayer.Backpack.Data.State.Value = "Attack"
		DefendingPlayer.Backpack.Data.State.Value = "Defend"

		repeat task.wait() until (AttackingPlayer.Backpack.Data.ChosenMove.Value ~= "") and (DefendingPlayer.Backpack.Data.ChosenMove.Value ~= "")
		local AttackerChose = AttackingPlayer.Backpack.Data.ChosenMove.Value
		local DefenderChose = DefendingPlayer.Backpack.Data.ChosenMove.Value

		print("Attacker Chose", AttackerChose)
		print("Defender Chose", DefenderChose)
		local PlayedAnimation = false
		if AttackerChose == DefenderChose then
			print("Defender Loses a life, Total:", DefendingPlayer.Backpack.Data.CurrentLives.Value)
			DefendingPlayer.Backpack.Data.CurrentLives.Value -= 1

			print(Rows)
			table.insert(Rows, DefendingPlayer.Backpack.Data.ChosenMove.Value)
			for i, v in pairs(Rows) do
				PlayedAnimation = true
				AttackingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Attack"..v]):Play()
				DefendingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Defend"..v]):Play()
				wait(0.4)
			end
			if #Rows == 3 then
				DefendingPlayer.Backpack.Data.CurrentLives.Value = 0
			end
			game.ReplicatedStorage.Client.HideButton:FireClient(AttackingPlayer, "Attack", AttackerChose)
			game.ReplicatedStorage.Client.HideButton:FireClient(DefendingPlayer, "Defend", DefenderChose)
		else
			Rows = {}
			Switch = true
		end
		if not PlayedAnimation then
			AttackingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Attack"..AttackingPlayer.Backpack.Data.ChosenMove.Value]):Play()
			DefendingPlayer.Character.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations["Defend"..DefendingPlayer.Backpack.Data.ChosenMove.Value]):Play()
		end
		
		Event.OnServerEvent:Connect(function(Player)                  <-------------- Script you added
			for _, i in ipairs(Corners) do
				if i.Occupant.Value == Player.Character then
					i.Occupant.Value = nil
					return
				end
				Player.PlayerGui.ShadowBoxing.LeaveMatch.Visible = true
			end
		end)
		
		wait(1)
		AttackingPlayer.Backpack.Data.ChosenMove.Value = ""
		DefendingPlayer.Backpack.Data.ChosenMove.Value = ""
	end
	DefendingPlayer.Character.Humanoid.Health = 0
	AttackingPlayer.Character.HumanoidRootPart.Anchored = false
	AttackingPlayer.Backpack.Data.State.Value = ""
	DefendingPlayer.Backpack.Data.State.Value = ""
	AttackingPlayer.Backpack.Data.Ring.Value = nil
	DefendingPlayer.Backpack.Data.Ring.Value = nil
	Attacker.Value = nil
	Defender.Value = nil
	Occupants = 0
	Billboard.TextLabel.Text = Occupants.. "/2"
	for i, v in pairs(Corners) do
		v.Occupant.Value = nil
	end	
end

PP.Triggered:Connect(function(Player)
	local Found = false
	for i, v in pairs(Corners) do
		if v.Occupant.Value == Player.Character then
			Found = true
		end
	end
	if Found then return end
	Occupants = Occupants + 1
	local Corner = Corners[1]

	if Corner.Occupant.Value ~= nil then
		Corner = Corners[2]
	end
	Corner.Occupant.Value = Player.Character
	Player.Backpack.Data.Ring.Value = script.Parent

	Billboard.TextLabel.Text = Occupants.. "/2"

	if Occupants == 2 then
		coroutine.wrap(function()
			wait(1)
			Billboard.Enabled = false
		end)()
		PP.Enabled = false
		local RandomNumber = math.random(1,2)
		Attacker.Value = Corners[RandomNumber].Occupant.Value
		Defender.Value = Corners[((RandomNumber == 1) and 2) or 1].Occupant.Value

		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Attacker.Value))
		game.ReplicatedStorage.Client.Countdown:FireClient(game.Players:GetPlayerFromCharacter(Defender.Value))
		wait(3)
		StartFight()
		PP.Enabled = true
		Billboard.Enabled = true
	end
end)

for i, v in pairs(Corners) do
	v.Occupant.Changed:Connect(function()
		if not v.Occupant.Value then
			Occupants -= 1
			return
		end
		local Char = v.Occupant.Value
		local Hrp:Part = Char:FindFirstChild("HumanoidRootPart")
		if not Hrp then return end
		Char.Humanoid.WalkSpeed = 0
		Hrp.AssemblyLinearVelocity = Vector3.new()
		Hrp.CFrame = v.CFrame
		Hrp.Anchored = true
		wait()
		Char.Humanoid.WalkSpeed = 16
	end)
end
1 Like