1st Place Tutorial?

How can I make a 1st place system like arsenal? I have a timer, and when the timer ends, I would like the server to look through all the players (no matter which team they are on.) Also, a frame that shows all the players who got in 1st place, and then reward the 1st place winner. Where is the right tutorial? Because I can’t find one.

1 Like

You can get a table of the players and use table.sort.

local standings = game.Players:GetPlayers()

table.sort(standings, function(a,b)
    return a.Kills.Value > b.Kills.Value --change this to leaderstats.Kills, or whatever determines standings
end)

print(standings[1].Name.." got first place!")
print(standings[2].Name.." got second place!")
print(standings[3].Name.." got third place!")

Also, the print will error if there is no 2nd or 3rd place

3 Likes

attempt to index nil with ‘Name’ - Server - Test1stPlaceSystem:7

It gave me this error

I’m assuming you used this as the whole script itself. This isn’t meant to be a whole script, but a part of the script that will determine the rankings. You will need to put this into a function and return the standings when the function is called.

function getStandings()
    local standings = game.Players:GetPlayers()
    
    table.sort(standings, function(a,b)
        return a.Kills.Value > b.Kills.Value --change this to leaderstats.Kills, or whatever determines standings
    end)

    return standings
end

--call function later on when needing to check standings

Yes, thank you! I’ll code the rest of the round system, and I’ll let you know how it goes.

It works, thank you!!! but how can I make a UI that is cloned, and put into all the players, to show who got first place? I thought about putting the 1st place winner’s name on the UI, with their avatar as an image, and their total kills they got in the round. How can I do that?

The UI:

Here is the script btw that I want to clone:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Status = ReplicatedStorage.RoundStatus
local InRound = ReplicatedStorage.InRound

function getStandings()
	local standings = game.Players:GetPlayers()

	table.sort(standings, function(a,b)
		return a.leaderstats.Kills.Value > b.leaderstats.Kills.Value --change this to leaderstats.Kills, or whatever determines standings
	end)
	
	print(standings[1].Name.." got first place!")
	print(standings[2].Name.." got second place!")
	print(standings[3].Name.." got third place!")
	

	return standings
end


while true do
	local timer = Status
	local minutes = 1
	local seconds = 0

	repeat
		if seconds <= 0 then
			minutes = minutes - 1
			seconds = 59
		else
			seconds = seconds - 1
		end
		if seconds < 10 then
			timer.Value = tostring(minutes)..":0"..tostring(seconds)
		else 
			timer.Value = tostring(minutes)..":"..tostring(seconds)
		end
		wait(1)
	until minutes <= 0 and seconds <= 0
	
	if minutes <= 0 and seconds <= 0 then
		Status.Value = "End of Game!"
		
		getStandings()
	end
end
1 Like

Have the server send the standings to the client for the client to show. You don’t need to clone the GUI, but instead leave it invisible while it’s not being used.

How can I get the player in the server?

you would loop through the players in the game like this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Status = ReplicatedStorage.RoundStatus
local InRound = ReplicatedStorage.InRound

local SendStandings = --event to send the standings to client

function getStandings()
	local standings = game.Players:GetPlayers()

	table.sort(standings, function(a,b)
		return a.leaderstats.Kills.Value > b.leaderstats.Kills.Value --change this to leaderstats.Kills, or whatever determines standings
	end)
	
	print(standings[1].Name.." got first place!")
	print(standings[2].Name.." got second place!")
	print(standings[3].Name.." got third place!")
	

	return standings
end


while true do
	local timer = Status
	local minutes = 1
	local seconds = 0

	repeat
		if seconds <= 0 then
			minutes = minutes - 1
			seconds = 59
		else
			seconds = seconds - 1
		end
		if seconds < 10 then
			timer.Value = tostring(minutes)..":0"..tostring(seconds)
		else 
			timer.Value = tostring(minutes)..":"..tostring(seconds)
		end
		wait(1)
	until minutes <= 0 and seconds <= 0
	
	if minutes <= 0 and seconds <= 0 then
		Status.Value = "End of Game!"
		
		local standings = getStandings()

		for i,plr in pairs(game.Players:GetPayers()) do
			SendStandings:FireClient(plr, standings)
		end
	end
end

and on the client:

local GetStandings = --same as SendStandings on server script

GetStandings.OnClientEvent:Connect(function(standings)
	print(standings) -- just to show that it works
	
	--make GUI visible and show standings on GUI
end)

Also sorry for late reply

1 Like

It’s not working. Here is my scripts:

Server Script Service Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Status = ReplicatedStorage.RoundStatus
local InRound = ReplicatedStorage.InRound

local SendStandings = ReplicatedStorage.WinnerUI


function getStandings()
	local standings = game.Players:GetPlayers()

	table.sort(standings, function(a,b)
		return a.leaderstats.Kills.Value > b.leaderstats.Kills.Value --change this to leaderstats.Kills, or whatever determines standings
	end)
	
	print(standings[1].Name.." got first place!")
	print(standings[2].Name.." got second place!")
	print(standings[3].Name.." got third place!")
	

	return standings
end


while true do
	local timer = Status
	local minutes = 1
	local seconds = 0

	repeat
		if seconds <= 0 then
			minutes = minutes - 1
			seconds = 59
		else
			seconds = seconds - 1
		end
		if seconds < 10 then
			timer.Value = tostring(minutes)..":0"..tostring(seconds)
		else 
			timer.Value = tostring(minutes)..":"..tostring(seconds)
		end
		wait(1)
	until minutes <= 0 and seconds <= 0
	
	if minutes <= 0 and seconds <= 0 then
		Status.Value = "End of Game!"
		
		local standings = getStandings()

		for i,plr in pairs(game.Players:GetPayers()) do
			SendStandings:FireClient(plr, standings)
		end
	end
end

Client Script in the Screen UI, which the screen UI is in the StarterGui:

game.ReplicatedStorage.WinnerUI.OnClientEvent:Connect(function(standings)
	print(standings)
	
	script.Parent.Enabled = true
	script.Parent.Frame.ImageLabel = Enum.ThumbnailType.AvatarThumbnail
	script.Parent.Frame.TheName.Text = standings.Name
	script.Parent.Frame.TotalKills.Text = standings.leaderstats.Kills.Value
end)

The problem is that standings is a table, so you can’t just do standings.Name as it would be nil. Assuming you wanted to do the first place here, you would do this:

game.ReplicatedStorage.WinnerUI.OnClientEvent:Connect(function(standings)
	print(standings)
	
	script.Parent.Enabled = true
	script.Parent.Frame.ImageLabel = Enum.ThumbnailType.AvatarThumbnail
	script.Parent.Frame.TheName.Text = standings[1].Name
	script.Parent.Frame.TotalKills.Text = standings[1].leaderstats.Kills.Value
end)

It works now, thank you. How can I make the ImageLabel show an image of the player who got first place?

Sorry for the really late reply, but it would use :GetUserThumbnailAsync(). Here’s how it would look:

game.ReplicatedStorage.WinnerUI.OnClientEvent:Connect(function(standings)
	print(standings)
	
	script.Parent.Enabled = true
	local content = Players:GetUserThumbnailAsync(standings[1].UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
	script.Parent.Frame.ImageLabel.Image = content
	script.Parent.Frame.TheName.Text = standings[1].Name
	script.Parent.Frame.TotalKills.Text = standings[1].leaderstats.Kills.Value
end)

What would be the right size for a AvatarThumbnail?

Sry it took long to respond, I was busy.

I usually do 420x420 myself, but you can increase its size depending on the size of the image label you are using. So, it is up to you and whatever you think looks the best.

Ohhhh ok, thank you very much!

So it won’t work when another player joins.

Here is my Server Script:

wait(1.5)
-- Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--// Varibles
local GetPlayers = #Players:GetPlayers()
local InRound = ReplicatedStorage.InRound
local RoundStatus = ReplicatedStorage.RoundStatus
local SendStandings = ReplicatedStorage.WinnerUI

while true do
	InRound.Value = false

	if GetPlayers < 3 then
		print("Not Enough Players to start game.")
		RoundStatus.Value = "Not enough players in server! Please wait till there is 3 players in the game."
		repeat wait() until GetPlayers >= 3
		print("Enough players")
		RoundStatus.Value = "Ready to start Server!"
	else
		print("Enough players")
		RoundStatus.Value = "Ready to start Server!"
	end

	function getStandings()
		local standings = game.Players:GetPlayers()

		table.sort(standings, function(a,b)
			return a.RoundKills.Value > b.RoundKills.Value --change this to leaderstats.Kills, or whatever determines standings
		end)

		print(standings[1].Name.." got first place!")
		print(standings[2].Name.." got second place!")
		print(standings[3].Name.." got third place!")

		for i,plr in pairs(game.Players:GetPlayers()) do
			SendStandings:FireClient(plr, standings)
		end


		return standings
	end

	if RoundStatus.Value == "Ready to start Server!" then
		RoundStatus.Value = "Intermission"
		wait(30)
		RoundStatus.Value = "Ready to start!"
		wait(3)
		InRound.Value = true
		local timer = RoundStatus
		local minutes = 3
		local seconds = 0

		repeat
			game.ReplicatedStorage.InRound.Value = true
			if seconds <= 0 then
				minutes = minutes - 1
				seconds = 59
			else
				seconds = seconds - 1
			end
			if seconds < 10 then
				timer.Value = tostring(minutes)..":0"..tostring(seconds)
			else 
				timer.Value = tostring(minutes)..":"..tostring(seconds)
			end
			wait(1)
		until minutes <= 0 and seconds <= 0

		if minutes <= 0 and seconds <= 0 then
			RoundStatus.Value = "End of Game!"
			local standings = getStandings()
			wait(10)
			InRound.Value = false
			for i, v in pairs(Players:GetPlayers()) do
				v.RoundKills.Value = 0
			end
		end
	end
end

Don’t reference the amount of players in the beginning of the script, either move the variable into the loop or just don’t use a variable for it.

 wait(1.5)
-- Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--// Varibles
local InRound = ReplicatedStorage.InRound
local RoundStatus = ReplicatedStorage.RoundStatus
local SendStandings = ReplicatedStorage.WinnerUI

while true do
	InRound.Value = false

	if #Players:GetPlayers() < 3 then
		print("Not Enough Players to start game.")
		RoundStatus.Value = "Not enough players in server! Please wait till there is 3 players in the game."
		repeat wait() until #Players:GetPlayers() >= 3
		print("Enough players")
		RoundStatus.Value = "Ready to start Server!"
	else
		print("Enough players")
		RoundStatus.Value = "Ready to start Server!"
	end

	function getStandings()
		local standings = game.Players:GetPlayers()

		table.sort(standings, function(a,b)
			return a.RoundKills.Value > b.RoundKills.Value --change this to leaderstats.Kills, or whatever determines standings
		end)

		print(standings[1].Name.." got first place!")
		print(standings[2].Name.." got second place!")
		print(standings[3].Name.." got third place!")

		SendStandings:FireAllClients(standings)


		return standings
	end

	if RoundStatus.Value == "Ready to start Server!" then
		RoundStatus.Value = "Intermission"
		wait(30)
		RoundStatus.Value = "Ready to start!"
		wait(3)
		InRound.Value = true
		local timer = RoundStatus
		local minutes = 3
		local seconds = 0

		repeat
			game.ReplicatedStorage.InRound.Value = true
			if seconds <= 0 then
				minutes = minutes - 1
				seconds = 59
			else
				seconds = seconds - 1
			end
			if seconds < 10 then
				timer.Value = tostring(minutes)..":0"..tostring(seconds)
			else 
				timer.Value = tostring(minutes)..":"..tostring(seconds)
			end
			wait(1)
		until minutes <= 0 and seconds <= 0

		if minutes <= 0 and seconds <= 0 then
			RoundStatus.Value = "End of Game!"
			local standings = getStandings()
			wait(10)
			InRound.Value = false
			for i, v in pairs(Players:GetPlayers()) do
				v.RoundKills.Value = 0
			end
		end
	end
end

Also instead of using FireClient in a loop, use FireAllClients.

1 Like

It now works, thank you very much!

1 Like