Stopping a function when all players have died

This is a confusing one. I’ve looked at coroutines and decided they don’t support the thing I’m trying to do (although I could be wrong which would be an epic fail :stuck_out_tongue:)

Anyways, I have this chunk of code:

local function Init()
	
	print("Game dialogue initiated")
	
	wait(7.5) -- pregame wait
	
	ChatToPlayers(Dialogue[1], 10)
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[2], 10)
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[3], 10)
	ChatFinished.Event:Wait()
	
	-- OpenDoor(1)
	
end

I am also storing a table of all players who are considered currently alive as so. The table is refilled with players every time a new game starts, and once all players in the table have died, the game restarts.

CurrentlyAlive = {}

How would I go about so when #CurrentlyAlive reaches 0, Init() stops?
I don’t want to check if #CurrentlyAlive is 0 every time a piece of dialogue is finished; I’d preferably like the game to end as soon as the last player dies. I’ve read that functions cannot be truly stopped, but this could be wrong and there’s most likely a work around.
Anyone have any advice or pointers?
If anyone needs more info, please post and I’ll supply.

EDIT: prematurely posted before I actually finished the post >.<

EDIT2: So I’m thinking of moving the Init() function to a ModuleScript and creating a Game:Start() and Game:Stop() function; that way, I could repeatedly check when there are no players left. Would this be a viable method, and if so, how should I execute it?

2 Likes

what your trying to accomplish seems flawed, since your checking if all players have died, but haven’t considered the fact that if they respawn, this would break the whole entire thing your wanting to do.

Every time the game starts, the current players are added to the table.

Players aren’t added to this table when they join. If they die during the game, they are removed from the table. When the table is empty (all players have died), the game restarts, filling the table with the current players.

oh. didn’t realize you implemented that into it. in that note, you could add a tag to each player when they die, and if the number of players alive is equal to 0 and the number of tags is equal to how many players were added to the game(in this case; players:5, tags:0.). what you could do is get how many players are still alive, and minus it by one every player death, and record that player death to a tag(to demistate, -5 players is +5, so the total is; players:0, tags:5.).


if you need a better explanation of this, i can insert a illustration if needed.

Please illustrate. I can’t visualize how this method would stop the function

so you have 5 players, and you have 0 tags. you add +1 tag every player death. so if its 4 players left, it equals 1 tag. 3 players, 2 tags, 2 players, 3 tags, and so on. basicly you want something that makes it to where the current players alive and the total count of tags is oppisite of each other and in order for the game to end, the tags need to be equal to the amount of players that are in the game, and the players alive need to be equal to 0 in order for the game to end


note: the “tags” im refering to can be whatever you want as a varible that has a numbervalue in it.

I understand the method you’re using. I just don’t understand how to actually implement in a manner that would stop the Init() function from running.

I have a system to check when the game needs to end. That’s all good. My problem is stopping the Init() function from continuing once the game ends.

you can use a number of ways on checking the player’s charcter health, but the best way is doing a loop that checks if the players health is <= 0 or == 0
you should be able to find the players health by just checking the Humanoid inside of the player’s character.

Instead of checking the health, you could do something like:

Player.Character.Humanoid.Died:Connect(function()
    if player is in table then
          #table = #table - 1
          end
     end
end

You can check exactly when the player dies using .Died

didnt think of using that event. didnt come to mind at first.

1 Like

I don’t need to check the player’s health. I need to check if the CurrentlyAlive table is empty and stop the main function accordingly

then you could do this:

if table == not nil then
Init()
end

That doesn’t help. I need to stop the function while it’s running, not before it starts.

Let’s say, for example, we are at Dialogue 2 (I made a comment where the script currently is)

local function Init()
	
	print("Game dialogue initiated")
	
	wait(7.5) -- pregame wait
	
	ChatToPlayers(Dialogue[1], 10)
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[2], 10) -- we are here currently
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[3], 10)
	ChatFinished.Event:Wait()
	
	OpenDoor(1)
	
end

All of the player die during this dialogue. How would I stop the function from continuing?

you can loop it along with

like this:

local function Init()
	
	print("Game dialogue initiated")
	
	wait(7.5) -- pregame wait
	
	ChatToPlayers(Dialogue[1], 10)
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[2], 10) -- we are here currently
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[3], 10)
	ChatFinished.Event:Wait()
	
	OpenDoor(1)
	
end

while true do
if table == not nil then
Init()
end
wait()
end

the wait() at the end of the while loop prevents the loop from crashing the server, since its running infinitely. also when creating loops like these not in a function, its best to keep the loop at the very bottom of the script, or else any other functions or lines of code wont work since anything below the loop wont be run because its infinitely looping.

while true do
    if table then
        Init()
    end
    wait()
end

How would this stop the function from running? All this code does is check if the table exists (which it always will, since it’s defined at the start of the script) and run the function. Additionally, it will prevent any code below it from running

it will run the function until the table that contains the players still alive is empty.

also, another way of looping it is this:

local function Init()
	
	print("Game dialogue initiated")
	
	wait(7.5) -- pregame wait
	
	ChatToPlayers(Dialogue[1], 10)
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[2], 10) -- we are here currently
	ChatFinished.Event:Wait()
	
	ChatToPlayers(Dialogue[3], 10)
	ChatFinished.Event:Wait()
	
	OpenDoor(1)
	
end
repeat 
Init()
wait()
untill table == nil

note: i dont know how to space out the lines of code while posting a reply/topic using tab, and i refuse to use Space a million times cause it bugs me.

You should check, after each-and-every statement, if there are any players still “alive”, and if not then return out of the function.

Lets say you make a function called AnyPlayersStillAlive that return true or false depending on the amount of ‘players still alive’:

local function Init()
	-- ....

	if not AnyPlayersStillAlive() then
		return
	end

	ChatToPlayers(Dialogue[1], 10)
	if not AnyPlayersStillAlive() then
		return
	end
	ChatFinished.Event:Wait()
	if not AnyPlayersStillAlive() then
		return
	end
	
	ChatToPlayers(Dialogue[2], 10) -- we are here currently
	if not AnyPlayersStillAlive() then
		return
	end
	ChatFinished.Event:Wait()
	if not AnyPlayersStillAlive() then
		return
	end
	
	ChatToPlayers(Dialogue[3], 10)
	if not AnyPlayersStillAlive() then
		return
	end
	ChatFinished.Event:Wait()
	if not AnyPlayersStillAlive() then
		return
	end
	
	OpenDoor(1)
end
3 Likes

This is practically the same as what you previously posted.

Breaking out of the function is probably the best method you can use but that would require you put some checks after each dialog finishes which you specifically said you don’t want.

Oof, it seems like the only way to do this is to check after each dialogue. >.<
I would use coroutines, but I’ve heard there is no way to permanently stop coroutines, so this is probably not a solution either.

You could also write the code as such:

local function Init()
	-- ....

	if AnyPlayersStillAlive() then ChatToPlayers(Dialogue[1], 10) end
	if AnyPlayersStillAlive() then ChatFinished.Event:Wait() end
	
	if AnyPlayersStillAlive() then ChatToPlayers(Dialogue[2], 10) end -- we are here currently
	if AnyPlayersStillAlive() then ChatFinished.Event:Wait() end
	
	if AnyPlayersStillAlive() then ChatToPlayers(Dialogue[3], 10) end
	if AnyPlayersStillAlive() then ChatFinished.Event:Wait() end
	
	if AnyPlayersStillAlive() then OpenDoor(1) end
end