Player leaving stops code

So, I have a code that runs a round system. In the round 2 players have a duel and the winner gets teleported back to his corresponding seat.

I made a script that constantly checks if a player left, and if he did, which one and assigns a value to a variable.

The problem is that the code continues if either one player has 0 health or if he left which leaves me with something like this (This is an example if player1 died or if he left)

if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then  --wpl is the player who left and _G.jmp1 is the character of the player
							_G.jmp1.Humanoid:UnequipTools()
							duelfinish:FireAllClients(pla1)
							Players:GetPlayerFromCharacter(_G.jmp2).leaderstats.Kills.Value = Players:GetPlayerFromCharacter(_G.jmp2).leaderstats.Kills.Value + 1
							script.Parent.DuelRoundScript.Disabled = true    --stop round timer
							wait(2.5)
							died:FireClient(pla2)   --DOES NOTHING, ADD A DEATH GUI
							wait(0.5)
							_G.jmp2:WaitForChild("Humanoid").Health = 0         --kill the winner, add a victory animation later or something also learn how to instantly reset a character!!!!!!!!!!!
							wait(1.6)
							duel2.Character.HumanoidRootPart.CFrame = duelseat2.CFrame  --Teleport the winner back to his seat
							status.Value = "The duel has been decided!"
							wait(2)
							status.Value = duelist2 .. " is the winner of duel " .. rounds .."!"
							number = number - 1
							wait(5)
							break                                            --Stop the duel round
						end

Now I’m not entirely sure what to add to this to make sure the code continues if both players leave. I tried checking if the player2 (in this case the one who won) is nil and doing a break the code. If I do that the code just simply skips over the part where I teleport the player to his seat.

Has anybody had an issue like this? Or does anybody know how to go about fixing this part of the code

Edit: Breaks are here because this is in a while loop. If you have any questions about the code please ask

Just a little tip to make your code better: Instead of _G or shared, please use ModuleScripts to store game state.

1 Like

I only use _G to store the 2 players that are “dueling” so that I can continuously check what is happening with them. If that’s what you mean by game state then my bad

im finding it pretty difficult to understand what your problem is…

I tried checking if the player2 (in this case the one who won) is nil and doing a break the code. If I do that the code just simply skips over the part where I teleport the player to his seat.

i presume you mean that the problem is that the player2 isnt teleporting to their seat?

you could more reliably wait for the character to respawn by doing

_G.jmp2:WaitForChild("Humanoid").Health = 0
Players:GetPlayerFromCharacter(_G.jmp2).CharacterAdded:Wait()
--[[ remainder of code goes here]]--

instead of using wait(1.6)

if you could elaborate on what your exact problem is, that would be great!

Yea sure, no problem!
So the problem I am facing is that when player2 leaves the game the code bugs out and stops working.

I have tried to counter this by doing this code after every wait:

if Players:GetPlayerFromCharacter(_G.jmp2) == nil then
      break
end

When I did this, the code did work, but the player wasn’t getting teleported.

Edit: So after seeing that the code above isn’t working well, I am searching for suggestions as for what might be the correct way of going about this

1 Like

Ok so I no longer have a problem with teleportation. I declared a variable which is equal to the player as duel1 and now have the following code:

if duel1 == nil then
    break
end

But the problem is that the code breaks when player2 leaves

Edit: The error begins when the game tries to teleport the player who left


Heres a short recording of the problem I am facing

you could try using the coroutine library to cancel the code while its running if player 2 leaves

RoundCoroutine = coroutine.create(function()
	--[[ While loop ]]--
	if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then  --wpl is the player who left and _G.jmp1 is the character of the player
		Players.PlayerRemoving:Once(function(leavingPlayer)
		    if leavingPlayer.UserId == Players:GetPlayerFromCharacter(_G.jmp2).UserId then -- Player 2 has just left
		        coroutine.yield(RoundCoroutine) -- You need to yield a coroutine before closing it
		        coroutine.close(RoundCoroutine)
		    end 
		end)
        --[[ Rest of code goes here ]]--
    end
end)

coroutine.resume(RoundCoroutine)

you can look at the coroutine documentation here if you would like to.

btw, your game looks really cool!

1 Like

Thanks for the reply and the documentation, never heard of coroutines so I’m gonna spend some time on it haha.
Also thanks for the compliment! I’m making it for a final high school project which I hope to get a really good grade on and I plan to add a lot more things since I have over a year to work on it!

Oh so basically how this works is we declare a coroutine and keep checking if a player left and if he left we just stop and close the coroutine so the rest of the code can continue? Thats really useful then!

Ok so this is perfect and works, but is there a way to stop the rest of the code until the coroutine is finished? After the players get teleported to the duel and the coroutine is made, the game realizes there’s only 1 player left at the table and gets sent to the win() function.
So I need the rest of the code to stop until the coroutine is finished

Never mind I just had to wait until the coroutine status is dead with this

repeat wait(0.5) until coroutine.status(RoundCoroutine) == "dead"
2 Likes

yup!

we declare a coroutine and keep checking if a player left

now that you mention it, for performance, it would probably to change how the event is handled, because you only need to check if the player has left once.

also, setting it to PlayerRemoving:Once() will make the function not fire if Player 1 dies and then leaves, so that NEEDS to be changed!

RoundCoroutine = coroutine.create(function()
	local PlayerLeaveConnection -- Connection that will be assigned later
	--[[ While loop ]]--
	if _G.jmp1.Humanoid.Health == 0 or wpl.Value == 1 then  --wpl is the player who left and _G.jmp1 is the character of the player
        if PlayerLeaveConnection == nil then -- PlayerLeaveConnection has not been assigned to..
            PlayerLeaveConnection = Players.PlayerRemoving:Connect(function(leavingPlayer)
		        if leavingPlayer.UserId == Players:GetPlayerFromCharacter(_G.jmp2).UserId then -- Player 2 has just left
		            PlayerLeaveConnection:Disconnect() -- Players leaving will no-longer do anything
		            coroutine.yield(RoundCoroutine) -- You need to yield a coroutine before closing it
		            coroutine.close(RoundCoroutine)
		        end 
		    end)
        end
        --[[ Rest of code goes here ]]--
    end
end)

coroutine.resume(RoundCoroutine)
1 Like

Yea, its a good thing you spotted that. Because if player1 left before player2 then the coroutine wouldn’t play out how we want it to be. Thanks a lot man!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.