Hi! I am currently making a game called Minigame Frenzy! Though, I need some help on making a timer script. What I want is a timer that counts down to 0, but if all players die it changes to Game Over! Or if multiple players are still alive they all get teleported to the spawn, and if one person is left, the text changes to …plr.Name"Wins!" I know this feels like a request, but I’ve been trying, and I couldn’t accomplish it. Could anyone atleast lead me in the right direction for this? Thanks!
-Aztralzz
You’re looking for multiple, already made systems mashed together. For the timer itself it would be something like the following:
-- Server Script
local TimeLeft = 120 -- 2 minutes
while wait(1) and TimeLeft > 0 do
TimeLeft = TimeLeft - 1
end
print'Timer ran out!'
Then for the other things, like for “if all players die” you could do something like this
-- Server Script
local PlayersInGame = {} -- This will store all the players in the game still, pre-game
for _, v in pairs(game.Players:GetPlayers())) do
local Character = v.Character or v.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild'Humanoid'
table.insert(PlayersInGame, v.Name) -- Add them to the list of players playing
Humanoid.Died:Connect(function() -- The player died
table.remove(PlayersInGame, v.Name) -- Remove them so the game knows
if #PlayersInGame == 0 then -- Check if there's any alive players
print'Game Over!' -- All players are dead, end the game
elseif #PlayersInGame == 1 then -- One player survived
print(('%s Wins!'):format(v.Name)
end
end)
end
Read more API references for more help:
Humanoid.Died, Tables
Or for a full tutorial practically all about your question to an extent, use this tutorial made by Roblox.
Timers and Custom Events
Sorry in advance, the code toggle font that does stuff like this
was being a little finicky, so it might be formatted a little weird.
Hello,
I have a game called Frenzy Sprint (Ironically the two games share a word) but I have a timer script that essentially works the same way. I also added an AFK option for players who want to temporarily go AFK, but I’m not gonna get into that. If you want to implement an AFK button, the stuff I’m talking about should work seamlessly with a feature like that. If you want to see how it works you can play my game Frenzy Sprint, as I have implemented that feature.
If you want to see how I implemented the AFK feature, look here:
- There’s a
BoolValue
under the player calledIsAFK
. When you click on a button, it fires a RemoteEvent and tells the server to toggle the value. - I used the following code to teleport only players who are AFK:
local function tpAllPlayers() for i, player in ipairs(game.Players:GetChildren()) do if player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.IsAFK.Value == false then -- If the player's Character exists and it's not marked as AFK then... player.Character.HumanoidRootPart.CFrame = target + Vector3.new(0, i * 5, 0) --Teleports players to the round end end end
- Look at the next part to see how I make it not count AFK players.
Back to how I checked if the players are playing and how I made a timer:
- When the server is created, create a stat under
player
calledPlayedThisRound
or something along the lines of that. I’ll usePlayedThisRound
for reference. Note that you can put this under leaderstats, but if you don’t want it to be seen on the leaderboard just put it straight under the player’s object. You would create this the same way you create leaderstats, but obviously it’s not under that folder. - At the beginning of the round, loop through all players in the game by using the following code:
local playersThisRound = {} local tableIndex = 1 for _, player in ipairs(game.Players:GetPlayers()) do if player.IsAFK.Value == false then player.PlayedThisRound.Value = true playersThisRound[tableIndex] = player tableIndex = tableIndex + 1 end end
Basically what it does is it checks to see if the player is not AFK, and if it’s not then it makes that player’s PlayedThisRound.Value
to true.
- Now for the countdown. I did the following:
local roundTime = 120 --Your number here, I made a separate variable because depending on the maps in my game, there's different amounts of time left for timeLeft = roundTime, 1, -1 do game:GetService("ReplicatedStorage"):FindFirstChild("YourRemoteEvent"):FireAllClients(timeLeft) wait() end
I did game:GetService("ReplicatedStorage")
vs game.ReplicatedStorage
because I’ve been told that the latter is prone to exploits from players in the event that a hacker changes the name of ReplicatedStorage. If the hacker does, all of a sudden everything that references will throw an error… and that’s that.
This is the code in my LocalScript that displays the timer to all players:
local gameStatement = "Round time left: "
game:GetService("ReplicatedStorage"):FindFirstChild("GameCountdown").OnClientEvent:Connect(function(timeInSecs)
if timeInSecs >= 10 then -- It will display something like 0:10
script.Parent.Text = gameStatement .. "0:" .. timeInSecs
end
if timeInSecs <= 9 then -- It will display something like 0:9 if I don't make this simple fix
script.Parent.Text = gameStatement .. "0:0" .. timeInSecs
end
end)
That’s the timer. Now, if you want to count the players it’s quite a bit of code, so I’ll just list out the functions in bullet points.
- When the player dies, set their
PlayedThisRound
value to false to designate that they’re not playing anymore. - Now, create yet another table within the
for timeLeft = roundTime, 1, -1 do
statement, so that it recreates itself every time that is run. - Create a variable called
num
in that samefor
loop. - Use another enhanced
for
loop that runs through the first table you made, which I had namedplayersThisRound
. If the player’sPlayedThisRound
value is still true, run the following code:num = num + 1
- At the end of that loop, use an
if
statement. Ifnum
’s value is still 0, then you can safely say that no players are in the round anymore and you can go on with starting the next round.
Sorry for writing so much, but I tried to maintain clarity as I’ve gotten some responses on my own questions that were… vague… to say the least. Hopefully you found this useful! If you have any questions, feel free to let me know!
Didn’t notice you already put pretty much the same stuff, my bad. Some of your stuff was more efficient when it came to the table, so probably just use @Warriorfoox’s method to the PlayersInGame
table.
Well you could add players to the table when the game starts and then remove them from the table when they die. When there is no players in the table then the game ends.
My code isn’t known for being the most efficient, it might work but it’s generally pretty bulky, I’ve been working on cutting down how much I use. Thanks !
It’s alright, it’s always nice to see people put this effort in helping the people who don’t quite understand it yet!
Hello there! A way I can think of to accomplish this would be to use a numeric for loop, as well as teams. Allow me to explain.
For Loop
You could use the for loop to count down the time, but also check the amount of players in or out of the minigame.
The Teams
You could place the players within teams such as Playing
or Waiting
, indicating which team they’re on. To note, a Team
object also has a GetPlayers
method, which returns the players on that team.
The Downsides Of Doing This
As pointed out by @ActiveFrenzy (thanx again btw), the Roblox chat would be spammed with constant messages saying You're now on team X
. It could also be slower to do this since you’d have to constantly call the GetPlayers
method, and compare the number of items to a number.
Another to note’s that you also need to insert the Teams
service. I managed to find a page on the devhub which can be found here
.
The Duo In Action
With these two combinations, you could check the number of players on the Playing
team, and when a player dies they’re set to the Waiting
team. An example of this would be…
local WaitingTeam = game.Teams.Waiting;
game.Players.PlayerAdded:Connect(function(Player)
Player.Team = WaitingTeam; -- When they first join the server, set the player to waiting
Player.CharacterAdded:Connect(function(Character) -- Listens for a new character
local Humanoid = Character:WaitForChild("Humanoid"); -- Waits for the Humanoid
Humanoid.Died:Connect(function() -- Listens for when the Humanoid dies
Player.Team = WaitingTeam; -- Sets the player's team back to WaitingTeam
end);
end);
end);
Wala! We have something set to change the player to the Waiting
team when they die.
Now, you might be wondering about the for loop. It’s actually quite simple. We just need the Playing
team to accomplish this, and have it work together with the for loop to make the ultimate duo!
local PlayingTeam = game.Teams.Playing;
local GameEnded = false; -- A bool determining whether the game ended during the match or not
...
for Count = 120, 1, -1 do
wait(1);
if (#PlayingTeam:GetPlayers() < 2) then -- Is there 1 or less players standing?
GameEnded = true; -- The match has ended
break; -- Break the for loop, stopping the countdown
end
end
local NumPlayers = #PlayingTeam:GetPlayers(); -- Get the number of players on the team
if (GameEnded) then -- Did the game end during the match?
if (NumPlayers == 1) then -- Was there 1 player standing?
-- Code
elseif (NumPlayers == 0) then -- Did everyone lose?
-- Code
end
elseif (NumPlayers > 1) then -- The countdown had ended without being stopped, so was there more than 1 player standing?
-- Code
end
And tada, we have a system set up to check for any winning player(s)! …Or for those who lost.
References
If you have any questions, please don’t hesitate to ask. I hope this helped.
He should just use tables not teams.
Agreed, it’ll probably flood the players’ chats with “You have joined team [xyz].” If you do this every single second, for two minutes that’ll be an easy 120 messages happening in two minutes, so players trying to communicate with each other won’t even be able to see their own messages.
I feel like teams also take longer to sort, while tables would just do it instantly without the player even needing to see.
Edit: I realized that it wouldn’t flood them with 120 messages but it could still be considered inconvenient because after just a couple rounds they could approach a large amount of server messages.
I hadn’t thought about the message saying about team change. Tbh, I forgot about that message lol. I’ll note that in my post, thanx for letting me know.
EDIT
Alright, I made the edits.
I mean, I did that code, and this error showed up.
Teams is not a valid member of DataModel
So, any help?
Apologies for the late response. That could be because the Teams
service wasn’t inserted into the game. It’s quite simple to add, simply go to the MODEL
ribbon and look for the service icon located under the Advanced
section . When you click on that a window should pop up with a list of service(s), prompting to select and insert one.
Once you click on the service you want and click insert, it’s added into the game. I hope this helped.
EDIT
I noted the inserting of the Teams
service in my original post.
K, thank youuu! (30char))))))))