How can i make a placement system like this?

I’ve been making a type of race system in roblox studio, and I’ve been having trouble on how to making the end results of each round
So each player has a points int value in them, and it can be increased during the race, and i want to make it so at the end of each race round, it checks all of the players in the server’s points value, and places them depending on it, like the person with the most points is shown to be 1st, the person with the 2nd most is shown to be 2nd, and so on


I want this placement to be shown with a gui, and each player in the server it makes a new template of it and gives them their placement in the game depending on their points intvalue
Screenshot 2024-09-08 173554

(i made 3 just for the uigridlayout to show)
I want a new template to be made for each player in the server, showing their points value at the end of the race and places them depending on it
this is the intermission/race round systme script in serverscriptservice

local LobbyMinutes = 0
local LobbySeconds = 10

local GameMinutes = 0
local GameSeconds = 15

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinEvent = game:GetService("ServerStorage"):FindFirstChild("CoinEvent")
local deletecoinsevent = game:GetService("ServerStorage"):FindFirstChild("DeleteCoinsEvent")
local TimerValues = ReplicatedStorage:WaitForChild("TimerValues")
local gameTimer = TimerValues.GameTimer
local lobbyTimer = TimerValues.LobbyTimer

local TweenService = game:GetService("TweenService")
local FadeInfo = TweenInfo.new(1.3,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

function teleportPlayers(RP,SpawnPart)
	if RP ~= nil then
		if SpawnPart ~= nil then
			RP.CFrame = SpawnPart.CFrame
		end
	end
end

while true do
	lobbyTimer.Minutes.Value = LobbyMinutes
	lobbyTimer.Seconds.Value = LobbySeconds

	repeat wait(1)
		if lobbyTimer.Seconds.Value > 0 then
			lobbyTimer.Seconds.Value -= 1
		else
			if lobbyTimer.Minutes.Value > 0 then
				lobbyTimer.Minutes.Value -= 1
				lobbyTimer.Seconds.Value = 59
			end
		end
	until lobbyTimer.Minutes.Value == 0 and lobbyTimer.Seconds.Value == 0
	
	local MapstoCoins = {
		["SnowMap1"] = "CoinSpawnSnow",
		["DesertMap1"] = "CoinSpawnDesert"
	}

	local mapHolder = game:GetService("ServerStorage").MapHolder
	local coinsHolder = game:GetService("ServerStorage").CoinsHolder
	local Children = mapHolder:GetChildren()
	local CoinChildren = coinsHolder:GetChildren()
	local Index = math.random(1,#Children)
	local randomInt = Children[Index]

	local finalMap = mapHolder:FindFirstChild(randomInt.Name):Clone()  
	for _,coinmaps in pairs(CoinChildren) do
		if coinmaps.Name == MapstoCoins[randomInt.Name] then
			local finalcoinMap = coinmaps:Clone()
	finalcoinMap.Parent = workspace.ChosenCoinMap
	coinEvent:Fire(coinmaps)
	print("coineventfired")
	finalMap.Parent = workspace
	

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('HumanoidRootPart') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local NewValue = Instance.new("BoolValue")
				NewValue.Name = "Ingame"
				NewValue.Parent = LocalPlayer.Character
				NewValue.Value = false

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					teleportPlayers(LocalPlayer.Character.HumanoidRootPart,finalMap:FindFirstChild('SpawnPart'))
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
					end)
				end)
			end
		end
	end

	wait(1.6 + 2)

	gameTimer.Minutes.Value = GameMinutes
	gameTimer.Seconds.Value = GameSeconds

	repeat wait(1)
		if gameTimer.Seconds.Value > 0 then
			gameTimer.Seconds.Value -= 1
		else
			if gameTimer.Minutes.Value > 0 then
				gameTimer.Minutes.Value -= 1
				gameTimer.Seconds.Value = 59
			end
		end
	until gameTimer.Minutes.Value == 0 and gameTimer.Seconds.Value == 0

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('Ingame') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					LocalPlayer:LoadCharacter()
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
					end)
				end)
			end
		end
	end

	wait(1.6)
	deletecoinsevent:Fire()
	finalMap:Destroy()
	finalcoinMap:Destroy()
	wait(2)

		end
	end
end
s

how can i make a placement system like that? since i dont evne know where to even start

1 Like

Since you’re using a ui list layout, you could make it so that you have a really high number and then you minus the player’s points value from that high number.
Then use the new number that has been calculated and set the layout order of the guiObjects to that and this will create the ordering effect you’re looking for:
showcase.rbxm (10.1 KB)
this model uses a table to display points but you can edit it to use your player’s points system.

Let me know if you need help explaining what I did.

• Place the model from the rbxm file into the startergui.

1 Like

(Note : Just make one template place frame visible and delete the rest. Move that one frame under startergui). Lets say you have the finish line part. You could have a table that stores the name and pos of the racer. Once they touch it then fire a remote event to all clients to show the racer’s position

local finishline = workspace.Track.FinishLine -- Change this
local placements = {}
local placeevent = game.ReplicatedStorage.Events.PlacementEvent
finishline.Touched:Connect(function(hit)
   if not hit.Parent:FindFirstChild('Humanoid') then return end
   local name = hit.Parent.Name
   if table.find(placements,name) then return end
   table.insert(placements, name)
   if #placements <= 3 then placeevent:FireAllClients(name,table.find(placements, name)) end
end)

Then on the client… (local script under the screen gui)

local placeevent = game.ReplicatedStorage.Events.PlacementEvent
local template = script.Parent.Parent.Template
local splacemapping = {
   [1] = '1st',
   [2] = '2nd',
   [3] = '3rd'
}
placeevent.OnClientEvent:Connect(function(name,pos)
   local placeplate = template:Clone()
   placeplate.Name = name
   placeplate.PositionLabel.Text = splacemapping[pos]
   placeplate.PlayerNameLabel.Text = name
   placeplate.Parent = script.Parent.Results.ScrollingFrame -- You have a list layout so np here :)
end)
1 Like

How can i make it so instead of the event firing when a player touches the finish line, it fires when the round ends and checks all the players in the server and places them depending on their points value?

Sorry that I didn’t read your topic properly

local placements = {
 [1] = {
     ['Player'] = 'Test',
     ['Points'] = 0
   }
}
for i,plr in pairs(game.Players:GetPlayers()) do
   if plr.Points.Value > placements[1].Points then
      table.insert(placements,1,{['Player'] = plr,['Points'] = plr.Points.Value})
   end
end
placeevent:FireAllClients({placements[1],placements[2],placements[3]})

Client

local splacemapping = {
   [1] = '1st',
   [2] = '2nd',
   [3] = '3rd'
}
placeevent.OnClientEvent:Connect(function(top3table)
   for i,postable in ipairs(top3table) do   
      local placeplate = template:Clone()
      placeplate.Name = postable.Player
      placeplate.PositionLabel.Text = splacemapping[i]
      placeplate.PlayerNameLabel.Text = postable.Player
      placeplate.PointsLabel.Text = postable.Points
      placeplate.Parent = script.Parent.Results.ScrollingFrame -- You have a list layout so np here :)
   end
end)

i tried the scripts, and got this
Screenshot 2024-09-09 200054
did i do anything wrong?
Screenshot 2024-09-09 200126


Does the scrolling frame have a UIGridLayout inside of it? You should insert one inside of the scrolling frame.

theres already a uigridlayout inside the scrolling frame

You’re supposed to do it after the rounds end… But that doesn’t explain why it doesn’t account for yoi

its inside the map handler script and is fired each time the round ends, but still doesnt seem to work

Do you have more than 0 points when the round ends? Try giving yourself some points on the server and using print statements, because the code looks fine

I gave myself points when the round ended, and it still didnt work, it just shows the test name and the 0 points template like before

That’s weird, because it should work if you have more points. Try adding some print statements in the loop about the table and the plr

i tried printing the arguments, this is what i got
Screenshot 2024-09-10 205922


i think the problem is how the players information about their name and points value is taken

Ok how are you changing your points? Do you just directly go to your player and change or do you press the current-client button to switch to server and then change it?

i change my points by switching to the server after pressing play then changing the players points

I’m really confused, bc then it should work. Is it smth to do with the indexing?

placements[1][“Points”]

i tried that too and it just comes up with a script error

Ok I’m completely reworking the system after some thinking


local placements = {}
for i,plr in pairs(game.Players:GetPlayers()) do
   table.insert(placements,{['Player'] = plr,['Points'] = plr.Points.Value})
end
table.sort(placements,function(a,b)
   return a.Points > b.Points
end)
placeevent:FireAllClients({placements[1],placements[2],placements[3]})

the part of the players name being taken works, but their points value being taken is still 0 even when its not
Screenshot 2024-09-10 225523