"If" / "if not" to find lowest tag number

Hello everyone! I will try to say this is a simple way here, and in the replies I will give more details, just in case it is needed. Ok, so in my game every player will have a tag number, from “0” to “7”, according to how far they got in an obby. The beginning part gives the players the tag number 0, and the last part gives the players the tag number 7.

So, I want to eliminate the player with least progress in the obby, in other words, the player with the lowest tag number.

  • The issue is, I don’t know how to make script that. I wanted to say something like: "If there is a player with tag “0”, eliminate them. If there is not, do nothing. If there is a player with tag “1” eliminate them. If there is not, do nothing. If there is a player with tag “2” eliminate them. If there is not, do nothing. Etc. Until tag “7”.

I just want to eliminate 1 player, the one with lowest tag number.
By the way, “eliminate them” means “change team to Spectators”

How can I script that? I tried it but I could only write this:

for _, Player in pairs(Players:GetChildren())do
if cs:HasTag(Player.Character, “0”) then
Player.Team = Spectators
end
end

I don’t know what to write after that.

  • And also, what can I write in order to eliminate only 1 player in a round, if 2 players have the tag “0” for example?

In my game each round there is a random obby map, and there are some “checkpoints” (they are not really checkpoints) that give a tag to the players, when touched.
Also, I just want my players to have one tag at a time, so I scripted that too.

Here is the script for checkpoint0:

local cs = game:GetService(“CollectionService”)

script.Parent.Touched:Connect(function(part)
if part.Parent:FindFirstChild(“Humanoid”) and not cs:HasTag(part.Parent, “0”) and not cs:HasTag(part.Parent, “1”) and not cs:HasTag(part.Parent, “2”) and not cs:HasTag(part.Parent, “3”) and not cs:HasTag(part.Parent, “4”) and not cs:HasTag(part.Parent, “5”) and not cs:HasTag(part.Parent, “6”) and not cs:HasTag(part.Parent, “7”)then
cs:AddTag(part.Parent, “0”)
end
if cs:HasTag(part.Parent, “0”) then
print (“0”)
end
end)

Here is the script for checkpoint4:

local cs = game:GetService(“CollectionService”)

script.Parent.Touched:Connect(function(part)
if part.Parent:FindFirstChild(“Humanoid”) and not cs:HasTag(part.Parent, “4”) and not cs:HasTag(part.Parent, “5”) and not cs:HasTag(part.Parent, “6”) and not cs:HasTag(part.Parent, “7”)then
cs:RemoveTag(part.Parent, “3”)
cs:AddTag(part.Parent, “4”)
end
if cs:HasTag(part.Parent, “4”) then
print (“4”)
end
end)

You get the idea…

And also, here is my main script (that is going to be changed):

ServerStorage = game:GetService(“ServerStorage”)
ReplicatedStorage = game:GetService(“ReplicatedStorage”)
Players = game:GetService(“Players”)
local Team = game:GetService(“Teams”)
local Contestants = game.Teams.Contestants
local Spectators = game.Teams.Spectators
local Completed = game.Teams.Completed
local cs = game:GetService(“CollectionService”)

Maps = ServerStorage:WaitForChild(‘Maps’):GetChildren()
Status = ReplicatedStorage:WaitForChild(‘Status’)

while true do

--Intermission

local Countdown = 10 -- ten second intermission, make this as long as you want

repeat wait(1)
	Countdown = Countdown - 1

	Status.Value = 'Intermission : '..Countdown
until Countdown <= 0

--Choose the map.

Status.Value = 'Choosing Map...'

local ChosenMap = Maps[math.random(1, #Maps)]:Clone()
local Spawns = ChosenMap:FindFirstChild('Spawns'):GetChildren()
local RandomSpawn = Spawns[math.random(1, #Spawns)]
local LobbySpawns = game.Workspace.Lobby:FindFirstChild('LobbySpawns'):GetChildren()
local RandomLobbySpawn = LobbySpawns[math.random(1, #LobbySpawns)]

wait(5) -- little pause, make this as long as you want

ChosenMap.Parent = workspace
Status.Value =  'Next Map Is: '

wait(2) -- little pause, make this as long as you want

Status.Value = ChosenMap.Name

wait(2) -- little pause, make this as long as you want

--teleport the players

for _, Player in pairs(Players:GetChildren())do
	if Player.Character and Player.Character:FindFirstChild('Humanoid') then
		Player.Character.HumanoidRootPart.CFrame = RandomSpawn.CFrame
	end
end

for _, Player in pairs(Players:GetChildren())do
	Player.Team = Contestants
end

-- Reassign countdown based on chosen map's Duration value
Countdown = ChosenMap:FindFirstChild("Duration").Value

repeat wait(1)
	Countdown = Countdown - 1
	
	local minutes = math.floor(Countdown / 60)
	local seconds = math.floor(Countdown % 60)

	Status.Value = string.format("Time left : %.2d:%.2d", minutes, seconds)
until Countdown <= 0

--Teleport back to lobby

for _, Player in pairs(Players:GetChildren())do
	if Player.Character and Player.Character:FindFirstChild('Humanoid') and Player.Team == Contestants then
		Player.Character.HumanoidRootPart.CFrame = RandomLobbySpawn.CFrame
	end
end

for _, Player in pairs(Players:GetChildren())do
	Player.Team = Completed
end

for _, Player in pairs(Players:GetChildren())do
	if cs:HasTag(Player.Character, "0") then
		Player.Team = Spectators
	end
end

Status.Value = 'The eliminated player is: '

for _, char in pairs(cs:GetTagged("0")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "0")
end

for _, char in pairs(cs:GetTagged("1")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "1")
end

for _, char in pairs(cs:GetTagged("2")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "2")
end

for _, char in pairs(cs:GetTagged("3")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "3")
end

for _, char in pairs(cs:GetTagged("4")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "4")
end

for _, char in pairs(cs:GetTagged("5")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "5")
end

for _, char in pairs(cs:GetTagged("6")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "6")
end

for _, char in pairs(cs:GetTagged("7")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "7")
end

ChosenMap:Destroy()

end

I would suggest creating a table with the players in an numerical order. e.g. the player with tag 0 goes to players[1] and the player with the 7 tag goes to players[8]. Upon elimination, you don’t have to check what tag the player has, but elimiante the first index of the table. When a player reaches a checkpoint, you can remove their index from their table and add them to the table in the according index like:

local players = {}
local foundIndex = ""
local playerCount = game.Players:GetPlayers()
script.Parent.Touched:Connect(function(hit)
for i = 1, #game.Players:GetPlayers() do
if playerCount == hit.Parent.Name then
foundIndex = i
end
end
table.remove(players, foundIndex)
table.insert(players, script.Parent.Name) -- Assuming the checkpoint's name is an integer.
end)

-- Round passes

local playerToEliminate = players[1]
table.remove(players, 1)

Hope that helps out.

1 Like

Uh this sounds very complicated for me…Anyways I can try it.

But do you know if it is possible to do it just by saying if and if not in the main script?

To find the lowest tag number, use table.sort.

local allPlrTagNums = {1,7,2,3,0}

table.sort(allPlrTagNums, function(a,b)
	return a<b
end)

local result = print(allPlrTagNums[1]) -- prints 0
1 Like

Ok, but then how can I eliminate the player with lowest number after writing that?

To eliminate the player with the lowest number, I just move all player’s info into a specific table, then I sort those, then I go through the array again and detect if the player name matches with the player with the lowest tag number and putting the team if it matches or not.

Script (Haven't tested yet but should work, replace your current piece of code to this script)
local allPlrTagNums = {}

for _, Player in pairs(game:GetService("Players"):GetPlayers())do
	local tag = cs:GetTagged(Player)		
	if tag then
		table.insert(allPlrTagNums,{Player.Name,tag})
	end
end

table.sort(allPlrTagNums, function(a,b)
	return a[2] < b[2]
end)

for _, Player in pairs(game:GetService("Players"):GetPlayers())do
	if Player.Name == allPlrTagNums[1][1] then
		Player.Team = Spectators
	end
end
1 Like

I tested it with my other account in a server, and it didn’t work ):

I reached the “checkpoint3”, and my other account reached “checkpoint1” and none of us were eliminated. And also, the map was not destroyed…

I didn’t change the script of the “checkpoints”

Here is how my main script is right now:

ServerStorage = game:GetService(“ServerStorage”)
ReplicatedStorage = game:GetService(“ReplicatedStorage”)
Players = game:GetService(“Players”)
local Team = game:GetService(“Teams”)
local Contestants = game.Teams.Contestants
local Spectators = game.Teams.Spectators
local Completed = game.Teams.Completed
local cs = game:GetService(“CollectionService”)

Maps = ServerStorage:WaitForChild(‘Maps’):GetChildren()
Status = ReplicatedStorage:WaitForChild(‘Status’)

while true do

--Intermission

local Countdown = 10 -- ten second intermission, make this as long as you want

repeat wait(1)
	Countdown = Countdown - 1

	Status.Value = 'Intermission : '..Countdown
until Countdown <= 0

--Choose the map.

Status.Value = 'Choosing Map...'

local ChosenMap = Maps[math.random(1, #Maps)]:Clone()
local Spawns = ChosenMap:FindFirstChild('Spawns'):GetChildren()
local RandomSpawn = Spawns[math.random(1, #Spawns)]
local LobbySpawns = game.Workspace.Lobby:FindFirstChild('LobbySpawns'):GetChildren()
local RandomLobbySpawn = LobbySpawns[math.random(1, #LobbySpawns)]

wait(5) -- little pause, make this as long as you want

ChosenMap.Parent = workspace
Status.Value =  'Next Map Is: '

wait(2) -- little pause, make this as long as you want

Status.Value = ChosenMap.Name

wait(2) -- little pause, make this as long as you want

--teleport the players

for _, Player in pairs(Players:GetChildren())do
	if Player.Character and Player.Character:FindFirstChild('Humanoid') then
		Player.Character.HumanoidRootPart.CFrame = RandomSpawn.CFrame
	end
end

for _, Player in pairs(Players:GetChildren())do
	Player.Team = Contestants
end

-- Reassign countdown based on chosen map's Duration value
Countdown = ChosenMap:FindFirstChild("Duration").Value

repeat wait(1)
	Countdown = Countdown - 1
	
	local minutes = math.floor(Countdown / 60)
	local seconds = math.floor(Countdown % 60)

	Status.Value = string.format("Time left : %.2d:%.2d", minutes, seconds)
until Countdown <= 0

--Teleport back to lobby

for _, Player in pairs(Players:GetChildren())do
	if Player.Character and Player.Character:FindFirstChild('Humanoid') and Player.Team == Contestants then
		Player.Character.HumanoidRootPart.CFrame = RandomLobbySpawn.CFrame
	end
end

for _, Player in pairs(Players:GetChildren())do
	Player.Team = Completed
end

local allPlrTagNums = {0,1,2,3,4,5,6,7}

table.sort(allPlrTagNums, function(a,b)
	return a<b
end)

local result = print(allPlrTagNums[1]) -- prints 0

local allPlrTagNums = {}

for _, Player in pairs(game:GetService("Players"):GetPlayers())do
	local tag = cs:GetTagged(Player)		
	if tag then
		table.insert(allPlrTagNums,{Player.Name,tag})
	end
end

table.sort(allPlrTagNums, function(a,b)
	return a[2] < b[2]
end)

for _, Player in pairs(game:GetService("Players"):GetPlayers())do
	if Player.Name == allPlrTagNums[1][1] then
		Player.Team = Spectators
	end
end

Status.Value = 'The eliminated player is: '

for _, char in pairs(cs:GetTagged("0")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "0")
end

for _, char in pairs(cs:GetTagged("1")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "1")
end

for _, char in pairs(cs:GetTagged("2")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "2")
end

for _, char in pairs(cs:GetTagged("3")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "3")
end

for _, char in pairs(cs:GetTagged("4")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "4")
end

for _, char in pairs(cs:GetTagged("5")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "5")
end

for _, char in pairs(cs:GetTagged("6")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "6")
end

for _, char in pairs(cs:GetTagged("7")) do -- This removes all tags, for new map
	cs:RemoveTag(char, "7")
end

ChosenMap:Destroy()

end

Are there any errors? (You can check errors by dev console by pressing F9)

1 Like

I didn’t see… Wait I will test again.

Yes there were errors:

Captura de Tela (3853)

Remove this line (You can CTRL+F or find to find where this line is at)

local allPlrTagNums = {0,1,2,3,4,5,6,7}

	table.sort(allPlrTagNums, function(a,b)
		return a<b
	end)

	local result = print(allPlrTagNums[1]) -- prints 0
1 Like

Ok, so basically happened the same thing but now the error is in other lines

The lines 91 and 92 are:

Captura de Tela (3855)

Is there any deeper reason why you’re using tags to keep track of the player’s progress?
It seems like you’re wiping them after the round has ended anyways, so I see no benefit in using tags over a simple intvalue.

I’m using tags because I thought this was the most simple way to do it ):
I think it might work

Using tags would work, but unless you need to specifically know what checkpoints a player has touched, I advice against it.
Instead, I’d like to recommend inserting an intvalue into the player’s character. If the value of the current checkpoint is higher, you can set the value of the player’s current stage to that of the checkpoint. This accomplishes everything you are doing, and makes everything easier to manage. Adding more checkpoints to a level would also be easier.
So, instead of checking if a player has any of the tags from their current level to the maximum one, you’d do something like this:

local stageNumber = 1 -- Change this to whatever stage number you're using

script.Parent.Touched:Connect(function(hit)
 if hit.Parent:FindFirstChild("Humanoid") then
   if hit.Parent.Stage.Value > stageNumber then
     hit.Parent.Stage.Value = stageNumber
   end
 end
end)

Using this format will also more easily allow you to find the player at the lowest stage.
All you’d have to do, is loop through all player’s characters, and if their stage number is lower than the currently lowest stage number, make that player be the slowest.

local slowestPlayer = nil
local lowestStage = math.huge -- This will ensure that the first check will always pass

for _, player in pairs(players:GetPlayers()) do
  local char = player.Character
  if not char then continue end

  local stage = char.Stage.Value
  if stage < lowestStage then
    lowestStage = stage
    slowestPlayer = player
  end
end
2 Likes

Alright, this might help. I put together some code that lets you plug in the player tag value. I have little to no knowledge about CollectionService, but I have an idea of how it works. Replace PlayerNum and PlayerVal with values gotten from CollectionService. Alternatively, you could use IntValues or NumberValues.

wait(1)

local Players = game:GetService("Players"):GetChildren()
local FailedPlayers = {}
local PlayerPoints = {}


local pn = 3 -- delete this. just for test purposes

for i,v in pairs(Players) do
	local PlayerNum = pn -- replace pn with the location of the tag val
	
	if not table.find(PlayerPoints, PlayerNum) then
		table.insert(PlayerPoints, PlayerNum)
	end
	
end

--sorting
table.sort(PlayerPoints,function(a,b)
	return a>b
end)

local LosingNumber = PlayerPoints[1]

for i,v in pairs(Players) do
	-- the tag val here
	local PlayerVal = pn -- replace pn with the location of the tag val
	
	if PlayerVal == LosingNumber then
		table.insert(FailedPlayers,v)
	end
end

warn(#Players)
warn(#PlayerPoints)
warn(#FailedPlayers)
local RandomPlayer = FailedPlayers[math.random(1, #FailedPlayers)]

warn(RandomPlayer.Name.." has been eliminated!")
1 Like

Thank you I will try to test it and see how it works.

Thanks I will test to see how it works.

So, there was an error in the line 5 of every checkpoint:

Captura de Tela (3860)

And an error in the line 89 of the main script: