Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to make it Destroy if everyone is dead?

I want to make the place destroy after everyone is dead. I did it once but I need itt a second time, but this ttime when everyone dies it's over. I tried an Ifelse statement, but that didn't work. Any suggestions?

LOF = game.Lighting.LOFgames:GetChildren()
h = script.Parent
f = script.Parent.Parent
gamePlayers = game.Players:GetPlayers()

while true do
	if game.Players.NumPlayers > 0 then
		wait(3)
		f.Visible = true
		h.Visible = true
		h.Text =  "Wait 10 seconds to get situated!"
		wait(10)
		h.Text = "Deciding which Leap of Doom- uh I mean Faith for you to do!"
		wait(10)
		ranGame = math.random (1, #LOF)
		gameChosen = LOF[ranGame]
		h.Text = "HAHAHAHA YOUR DOOM- I MEAN YOUR LEAP OF FAITH GAME:  " .. gameChosen.Name
		wait(10)
		gameChosenClone = gameChosen:Clone()
		gameChosenClone.Parent = game.Workspace
		thing = gameChosenClone.thing:GetChildren()
		--teleportation :D
		
		for i, v in pairs(game.Players:GetPlayers()) do
			name = v.Name
			check = game.Workspace:FindFirstChild(name)
			if check then
				checkHumanoid = check:FindFirstChild("Humanoid")
			
			if checkHumanoid then
			v.Character:MoveTo(thing[i].Position)
			end
			end
		end
		
		for i = 8, 1, -1 do
		h.Text = "FAITH WILL START IN " .. i
		end
		for i = 60, 1, -1 do
			wait(0.5)
			h.Text = "THE COUNTDOWN BEGINS, TIME:"  ..i
		end
		h.Text = "Game Ended hopefully you survived! :)"
		wait(5)
		gameChosenClone:Destroy()
		
	end
	wait(1)
end

I'm not sure if you need the whole code, but there you go. Also the script is in a gui in starter gui. My main problem is that everytime You die then the script restarts anyway to change it from restarting once you die? Here is my New script...

LOF = game.ServerStorage.LOFgames:GetChildren()
h = script.Parent
f = script.Parent.Parent
gamePlayers = game.Players:GetPlayers()
   local roundTime = 30

while true do
	if game.Players.NumPlayers > 0 then
		wait(3)
		f.Visible = true
		h.Visible = true
		h.Text =  "Intermission"
		wait(10)
		h.Text = "Deciding which Leap of Doom- uh I mean Faith for you to do!"
		wait(5)
		ranGame = math.random (1, #LOF)
		gameChosen = LOF[ranGame]
		h.Text = "HAHAHAHA YOUR DOOM- I MEAN YOUR LEAP OF FAITH GAME:  " .. gameChosen.Name
		wait(5)
		gameChosenClone = gameChosen:Clone()
		gameChosenClone.Parent = game.Workspace
		thing = gameChosenClone.thing:GetChildren()
				for i = 8, 1, -1 do
		h.Text = "FAITH WILL START IN " .. i
		end
		wait(8)
		local playersTeleported = {}
		--teleportation :D
		
		for i, v in pairs(game.Players:GetPlayers()) do
			name = v.Name
			check = game.Workspace:FindFirstChild(name)
			if check then
				checkHumanoid = check:FindFirstChild("Humanoid")
			
			if checkHumanoid then
				table.insert(playersTeleported, v)
			v.Character:MoveTo(thing[i].Position)
			end
			end
		end
		
		local function WaitForPlayersToDie(playersTeleported, maxTime) 
    local playersAlive = {}
    if #playersTeleported == 0 then return end 
    local allDead = true 
    for i = 1, #playersTeleported do
        local player = playersTeleported[i]
        local con
        local function disconnect()
           
            for i = 1, #playersAlive[player] do
                playersAlive[player]:disconnect()
            end
            
            playersAlive[player] = nil
            allDead = next(playersAlive) == nil 
        end
        playersAlive[player] = {
            player.AncestryChanged:connect(disconnect),
            player.CharacterRemoving:connect(disconnect),
            Disconnect=disconnect, 
        }
    end
    local start = workspace.DistributedGameTime
    while workspace.DistributedGameTime - start < maxTime do
        wait(1)
        if allDead then break end
    end
    for player, connections in pairs(playersAlive) do 
        connections.Disconnect()
    end
end
		



    local roundDone = false
    coroutine.resume(coroutine.create(function()
        for i = roundTime * 2, 1, -1 do
            wait(0.5) 
            if roundDone then return end
            h.Text = "THE COUNTDOWN BEGINS, TIME:"  ..i
        end
    end))
    WaitForPlayersToDie(playersTeleported, roundTime)
    roundDone = true
		h.Text = "Game Ended hopefully you won! :)"
		wait(5)
		gameChosenClone:Destroy()
		else
		end
	wait(1)
end

1 comment

0

you could try getting the number of people in the game area and when someone dies, it takes a number off and when it's 0, boom. btw i dont see a line for when everybody is dead. or i just read over it.

1 answer

Some minor notes about your current script:

  • The if game.Players.NumPlayers > 0 then is completely unnecessary as a roblox server will shut down when all the players have left. Remove this and the corresponding end.
  • You are supposed to put storage in either ReplicatedStorage (if you want everyone to have it from the start) or, better, ServerStorage. Putting it in ServerStorage means that clients will only download a game when they need it.
  • Open up the Script Analysis window and it'll tell you about certain variables you are using that should be made local, like ranGame. Either make it local near the top of the script or where you first use it.
  • You're making your players wait a long time - that's a lot of wait(10)s! Consider lowering the wait times.
  • You teleport your players into the game and then start a count-down. You should move the count-down to before you teleport the players.

Now, your script currently doesn't even attempt to do what you're asking. A proper implementation will do the following things:

  • Wait for everyone to die once and ignore repeated deaths
  • If someone leaves your place, don't wait for them to die anymore
  • Have a time limit
local function WaitForPlayersToDie(playersTeleported, maxTime) --playersTeleported must be the list of players who made it into the game. maxTime should be 60 or whatever the round length is.
	--First step is to create a dictionary of people who remain alive. The key will be the player and the value will be the list of connections we're going to care about.
	local playersAlive = {}
	if #playersTeleported == 0 then return end --No players teleported means we shouldn't wait at all
	local allDead = true --will become false when no players left
	for i = 1, #playersTeleported do
		local player = playersTeleported[i]
		local con
		local function disconnect()
			--disconnect the values
			for i = 1, #playersAlive[player] do
				playersAlive[player]:disconnect()
			end
			--set playersAlive[player] to nil to remove this player from the dictionary of alive players
			playersAlive[player] = nil
			allDead = next(playersAlive) == nil --next will return the next key and value of playersAlive. If this returns nil, there are no players alive, and so allDead should be true.
		end
		playersAlive[player] = {
			player.AncestryChanged:connect(disconnect),
			player.CharacterRemoving:connect(disconnect),
			Disconnect=disconnect, --this isn't part of the list, but allows us to disconnect later
		}
	end
	local start = workspace.DistributedGameTime
	--Now we wait. We could set up a custom event that would only fire when allDead becomes true or when the specified time expires, but a "polling loop" will suffice:
	while workspace.DistributedGameTime - start < maxTime do
		wait(1)
		if allDead then break end
	end
	for player, connections in pairs(playersAlive) do --remove any remaining connections
		connections.Disconnect()
	end
end

Now, to incorporate this script into the rest of what you have, we need to use a coroutine. Instead of the 60-second count-down, you'll need:

--Before the "for i, v in pairs(game.Players:GetPlayers()) do" loop you need:
local playersTeleported = {}

--After the "if checkHumanoid then" line you need:
table.insert(playersTeleported, v)

--Old stuff to replace:
        for i = 60, 1, -1 do
            wait(0.5)
            h.Text = "THE COUNTDOWN BEGINS, TIME:"  ..i
        end
--Replace it with:
	local roundTime = 30 --move this line only to the top of the script; it is the number of seconds to wait
	local roundDone = false
	coroutine.resume(coroutine.create(function()
		for i = roundTime * 2, 1, -1 do
			wait(0.5) --if you intend to change this back to wait(1), then remove the "* 2" on the previous line
			if roundDone then return end
			h.Text = "THE COUNTDOWN BEGINS, TIME:"  ..i
		end
	end))
	WaitForPlayersToDie(playersTeleported, roundTime)
	roundDone = true --tell the above coroutine to stop counting down

[Edit/Update]

You should never combine scripts that deal with the workspace and scripts that deal with the gui. See this Scripting Helpers guide. This script needs to be split into the server-side, which deals with the game, and the local-side, which deals with the gui.

I changed a few miscallaneous things in the script:

  • In your "FAITH WILL START IN" for loop, the wait should go inside the for loop, not after it (I fixed it).
  • I simplified the "can we teleport a player" if check.
  • I removed the gamePlayers variable at the beginning (which stored an old list of players for no reason)
  • I simplified my while loop in WaitForPlayersToDie
  • Instead of h.Text =, I set up a RemoteEvent to use via the function I wrote SendMessage.
  • I fixed a few things in the code I gave you earlier in this post

Client script (this can stay in the StarterGui; it should be in a LocalScript):

h = script.Parent
f = script.Parent.Parent
game.ReplicatedStorage:WaitForChild("SendMessage").OnClientEvent:connect(function(msg)
    local visible = msg and msg ~= ""
    f.Visible = visible
    h.Visible = visible
    h.Text = msg
end)

New server script (should be in game.ServerScriptService):

LOF = game.ServerStorage.LOFgames:GetChildren()
local roundTime = 30
local sendMessageEvent = Instance.new("RemoteEvent")
sendMessageEvent.Name = "SendMessage"
sendMessageEvent.Parent = game.ReplicatedStorage
function SendMessage(msg)
    pcall(function()
        sendMessageEvent:FireAllClients(msg)
    end)
end

while true do
    wait(3)
    SendMessage("Intermission")
    wait(5)
    SendMessage("Deciding which Leap of Doom- uh I mean Faith for you to do!")
    wait(5)
    local ranGame = math.random (1, #LOF)
    local gameChosen = LOF[ranGame]
    SendMessage("HAHAHAHA YOUR DOOM- I MEAN YOUR LEAP OF FAITH GAME:  " .. gameChosen.Name)
    wait(5)
    local gameChosenClone = gameChosen:Clone()
    gameChosenClone.Parent = game.Workspace
    thing = gameChosenClone.thing:GetChildren()
    for i = 8, 1, -1 do
        SendMessage("FAITH WILL START IN " .. i)
        wait(1)
    end
    --teleportation :D
    local playersTeleported = {}    
    for i, v in pairs(game.Players:GetPlayers()) do
        if v.Character and v.Character:FindFirstChild("Humanoid") then
            table.insert(playersTeleported, v)
            v.Character:MoveTo(thing[i].Position)
        end
    end

    local function WaitForPlayersToDie(playersTeleported, maxTime) 
        local playersAlive = {}
        if #playersTeleported == 0 then return end
        local allDead = false
        for i = 1, #playersTeleported do
            local player = playersTeleported[i]
            local con
            local function disconnect()
                for i = 1, #playersAlive[player] do
                    playersAlive[player][i]:disconnect()
                end
                playersAlive[player] = nil
                allDead = next(playersAlive) == nil
            end
            playersAlive[player] = {
                player.AncestryChanged:connect(disconnect),
                player.CharacterRemoving:connect(disconnect),
                Disconnect=disconnect, 
            }
        end
        local start = workspace.DistributedGameTime
        while workspace.DistributedGameTime - start < maxTime and not allDead do
            wait(1)
        end 
        --Remove any remaining connections
        for player, connections in pairs(playersAlive) do 
            connections.Disconnect()
        end
    end
    local roundDone = false
    coroutine.resume(coroutine.create(function()
        for i = roundTime * 2, 1, -1 do
            wait(0.5) 
            if roundDone then return end
            SendMessage("THE COUNTDOWN BEGINS, TIME:" .. i)
        end
    end))
    WaitForPlayersToDie(playersTeleported, roundTime)
    roundDone = true
    SendMessage("Game Ended hopefully you won! :)")
    wait(5)
    gameChosenClone:Destroy()
    wait(1)
end

One note: You might want to replace the line player.CharacterRemoving:connect(disconnect), with player.Character.Humanoid.Died:connect(disconnect) if you want the game to end the moment a player died rather than when the player's character respawned.

4 comments

0

I did everything you did, but once I died the whole script restarted and it said: "Wait Ten seconds..." but the thing wasn't destroyed. The script just restarted when I died I'm not sure if I put the first script in the right place, but I read what you wrote and understood most of it. Why would you need to disconnect though.. Thanks

0

I'd need to know what sort of error went into the output (if any) and I'd need to see the script as it currently stands. One should disconnect from events when done with them so that the memory can be reclaimed. But say you've connected to a Touch event in a Part, you needn't disconnect if you Destroy the part, as Roblox does it for you.

0

I updated my post with the new script

0

I updated my answer with working scripts (I tested them in a mostly blank place, just inserting models as needed to simulate games). See the segment after the '[Edit/Update]' line in the post.

This discussion is preserved as it was. New answers, comments, and votes are closed.