Help with queue system

having problems with queue system

The problems I’m facing:

  • If 3 players queueing at the same time 2 of them are teleported and the other alone is also teleported but to a separate server, which is not supposed to happen because if you are alone in the queue you are not supposed to be teleported.

(What I think is the problem, is that when two players queue and it is filled by 2 players the other tables are also being teleported regardless of whether they are filled or not.)

  • Another error (sometimes happens sometimes not) when 2 players queue they don’t teleport to the same server making them go separate

  • Last error, it is allowing teleportation of 4 players to the same match

I am really lost on how to fix this

Code:

local memoryStore = game:GetService("MemoryStoreService")
local queue = memoryStore:GetSortedMap("Queue")

local tpService = game:GetService("TeleportService")

local minimum = 2
local maximum = 2

local placeId = 13782072218

local re = game.ReplicatedStorage:WaitForChild("QueueRE")


--Functions to edit queue
function addToQueue(player)
	queue:SetAsync(player.UserId, player.UserId, 2592000)
end

function removeFromQueue(player)
	queue:RemoveAsync(player.UserId)
end


--Add and remove players from queue when they press the button
local cooldown = {}

re.OnServerEvent:Connect(function(player, inQueue)
	
	if cooldown[player] then return end
	cooldown[player] = true
	
	if inQueue == "NA FILA..." then
		pcall(addToQueue, player)
	elseif inQueue == "1V1" then
		pcall(removeFromQueue, player)
	end
	
	wait(1)
	cooldown[player] = false
end)


--Remove player from queue if they leave the server
game.Players.PlayerRemoving:Connect(removeFromQueue)


--Check when enough players are in the queue to teleport players
local lastOverMin = tick()

while wait(1) do
	
	local success, queuedPlayers = pcall(function()
		return queue:GetRangeAsync(Enum.SortDirection.Descending, maximum)
	end)
	
	if success then
		
		local amountQueued = 0
		
		for i, data in pairs(queuedPlayers) do
			amountQueued += 1
		end
		
		if amountQueued < minimum then
			lastOverMin = tick()
		end
		
		--Wait 20 seconds after the minimum players is reached to allow for more players to join the queue
		--Or instantly queue once the maximum players is reached
		local timeOverMin = tick() - lastOverMin
		
		if timeOverMin >= 20 or amountQueued == maximum then
			
			for i, data in pairs(queuedPlayers) do	
				
				local userId = data.value
				local player = game.Players:GetPlayerByUserId(userId)
				
				if player then
					local success, err = pcall(function()
						tpService:TeleportAsync(placeId, {player})
					end) 
					
					spawn(function()
						if success then
							wait(1)
							pcall(function()
								queue:RemoveAsync(data.key)
							end)
						end
					end)
				end
			end
		end
	end
end```

You have to teleport players to a reserved server. This can be done by calling TeleportService:ReserveServer(placeId) and then using TeleportService:TeleportAsync(placeId, players, teleportOptions) with teleportOptions having the reserved server access code. Article: Teleporting Between Places | Documentation - Roblox Creator Hub

3 Likes

I can think of a few potential problems that might be causing the issues you mentioned. Could be teleporting a single player when there are two players in the queue and could be players not teleporting to the same server when queuing together, try using this code as with these adjustments, players are correctly teleported based on the queue conditions and are transported to the same server when they are queuing together. Don’t forget to thoroughly test the updated code to make sure it works in the environment of your particular game xx

-- ...

if timeOverMin >= 20 or amountQueued == maximum then
    -- Check if there are enough players in the queue
    if amountQueued >= minimum then
        local playersToTeleport = {}
        
        for i, data in pairs(queuedPlayers) do    
            local userId = data.value
            local player = game.Players:GetPlayerByUserId(userId)
            
            if player then
                table.insert(playersToTeleport, player)
                
                if #playersToTeleport == maximum then
                    break  -- Limit the number of players to teleport
                end
            end
        end
        
        if #playersToTeleport == maximum then
            -- Check if players are already in the same server
            local sameServer = true
            local firstServerId = playersToTeleport[1].GameId
            
            for i = 2, #playersToTeleport do
                if playersToTeleport[i].GameId ~= firstServerId then
                    sameServer = false
                    break
                end
            end
            
            if not sameServer then
                -- Teleport players to the first player's server
                local firstPlayer = playersToTeleport[1]
                local success, err = pcall(function()
                    tpService:TeleportToPlaceInstance(placeId, firstPlayer.GameId)
                end)
                
                if success then
                    wait(1)
                    for i, player in ipairs(playersToTeleport) do
                        pcall(function()
                            queue:RemoveAsync(player.UserId)
                        end)
                    end
                end
            else
                -- Teleport players to the destination place
                local success, err = pcall(function()
                    tpService:TeleportAsync(placeId, playersToTeleport)
                end)
                
                if success then
                    wait(1)
                    for i, player in ipairs(playersToTeleport) do
                        pcall(function()
                            queue:RemoveAsync(player.UserId)
                        end)
                    end
                end
            end
        end
    end
end

-- ...

image

this is what i got after i replaced it

Omg! The GameId property I mentioned does not exist for the Player, that’s why that came up, try this boo x

-- ...

if timeOverMin >= 20 or amountQueued == maximum then
    -- Check if there are enough players in the queue
    if amountQueued >= minimum then
        local playersToTeleport = {}
        
        for i, data in pairs(queuedPlayers) do    
            local userId = data.value
            local player = game.Players:GetPlayerByUserId(userId)
            
            if player then
                table.insert(playersToTeleport, player)
                
                if #playersToTeleport == maximum then
                    break  -- Limit the number of players to teleport
                end
            end
        end
        
        if #playersToTeleport == maximum then
            -- Generate a unique identifier to group players
            local groupId = tostring(math.random(100000, 999999))
            
            -- Teleport players to the destination place with the same groupId
            local success, err = pcall(function()
                tpService:TeleportAsync(placeId, playersToTeleport, groupId)
            end)
            
            if success then
                wait(1)
                for i, player in ipairs(playersToTeleport) do
                    pcall(function()
                        queue:RemoveAsync(player.UserId)
                    end)
                end
            end
        end
    end
end

-- ...

You can’t do this. The third parameter has to be a TeleportOptions object. It should instead be like this:

local teleportOptions = Instance.new("TeleportOptions")
teleportOptions.ShouldReserveServer = true

local success, err = pcall(function()
    tpService:TeleportAsync(placeId, playersToTeleport, teleportOptions)
end)
1 Like

You’re right! My bad! Xx

Here’s an updated script

-- ...

if timeOverMin >= 20 or amountQueued == maximum then
    -- Check if there are enough players in the queue
    if amountQueued >= minimum then
        local playersToTeleport = {}
        
        for i, data in pairs(queuedPlayers) do    
            local userId = data.value
            local player = game.Players:GetPlayerByUserId(userId)
            
            if player then
                table.insert(playersToTeleport, player)
                
                if #playersToTeleport == maximum then
                    break  -- Limit the number of players to teleport
                end
            end
        end
        
        if #playersToTeleport == maximum then
            -- Generate a unique identifier to group players
            local groupId = tostring(math.random(100000, 999999))
            
            -- Create a TeleportOptions object with the VIP server groupId
            local teleportOptions = TeleportOptions.new()
            teleportOptions.VIPServerId = groupId
            
            -- Teleport players to the destination place with the same groupId
            local success, err = pcall(function()
                tpService:TeleportAsync(placeId, playersToTeleport, teleportOptions)
            end)
            
            if success then
                wait(1)
                for i, player in ipairs(playersToTeleport) do
                    pcall(function()
                        queue:RemoveAsync(player.UserId)
                    end)
                end
            end
        end
    end
end

-- ...

Will test it out with some friends, will let you know how it went!

What.

First off, you can’t create TeleportOptions this way because the global TeleportOptions doesn’t exist. So it’s only with Instance.new(). Second, VIPServerId isn’t a property of TeleportOptions.
Third. I literally provided what was needed to be changed.

1 Like

let me know if i’m wrong but is this how it should look?


local memoryStore = game:GetService("MemoryStoreService")
local queue = memoryStore:GetSortedMap("Queue")

local tpService = game:GetService("TeleportService")

local minimum = 2
local maximum = 2

local placeId = 13782072218

local re = game.ReplicatedStorage:WaitForChild("QueueRE")


--Functions to edit queue
function addToQueue(player)
	queue:SetAsync(player.UserId, player.UserId, 2592000)
end

function removeFromQueue(player)
	queue:RemoveAsync(player.UserId)
end


--Add and remove players from queue when they press the button
local cooldown = {}

re.OnServerEvent:Connect(function(player, inQueue)

	if cooldown[player] then return end
	cooldown[player] = true

	if inQueue == "NA FILA..." then
		pcall(addToQueue, player)
	elseif inQueue == "1V1" then
		pcall(removeFromQueue, player)
	end

	wait(1)
	cooldown[player] = false
end)


--Remove player from queue if they leave the server
game.Players.PlayerRemoving:Connect(removeFromQueue)


--Check when enough players are in the queue to teleport players
local lastOverMin = tick()

while wait(1) do

	local success, queuedPlayers = pcall(function()
		return queue:GetRangeAsync(Enum.SortDirection.Descending, maximum)
	end)

	if success then

		local amountQueued = 0

		for i, data in pairs(queuedPlayers) do
			amountQueued += 1
		end

		if amountQueued < minimum then
			lastOverMin = tick()
		end

		--Wait 20 seconds after the minimum players is reached to allow for more players to join the queue
		--Or instantly queue once the maximum players is reached
		local timeOverMin = tick() - lastOverMin

		-- ...

		if timeOverMin >= 20 or amountQueued == maximum then
			-- Check if there are enough players in the queue
			if amountQueued >= minimum then
				local playersToTeleport = {}

				for i, data in pairs(queuedPlayers) do    
					local userId = data.value
					local player = game.Players:GetPlayerByUserId(userId)

					if player then
						table.insert(playersToTeleport, player)

						if #playersToTeleport == maximum then
							break  -- Limit the number of players to teleport
						end
					end
				end

				if #playersToTeleport == maximum then
					-- Generate a unique identifier to group players
					local teleportOptions = Instance.new("TeleportOptions")
					teleportOptions.ShouldReserveServer = true

					-- Teleport players to the destination place with the same groupId
					local success, err = pcall(function()
						tpService:TeleportAsync(placeId, playersToTeleport, teleportOptions)
					end)
					if success then
						wait(1)
						for i, player in ipairs(playersToTeleport) do
							pcall(function()
								queue:RemoveAsync(player.UserId)
							end)
						end
					end
				end
			end
		end
	end
	end

		-- ...
1 Like

Your code is nearly perfect. There is only one small correction that needs to be made. Instead of creating an instance of "TeleportOptions" , you should create an instance of "PrivateServerTeleportOptions"

1 Like

?!
PrivateServerTeleportOptions isn’t a real thing.

1 Like

STOOPP I am so confused with lua and Roblox Lua :sob: thanks for correcting me, I’ll try one last time

PlaceTeleportSetup maybe?

You sound like chatgpt lmao, what are you on about

Bye what i literally am just trying to help? Like lord

you gotta actually be trolling, you’re either using chat gpt or you’re just spouting misinformation on purpose.

Neither, sorry for trying to help lxl? Like I literally got confused with roblox lua and lua cuz i didnt script in months… u dont gotta be rude

It’s nice to try to help, but you mention a ton of properties that don’t exist or ever have existed. Your wording when you make a mistake is nearly exactly like what I’ve seen when chatgpt makes one.

What do you mean you get confused by lua vs roblox lua? Like… lua doesn’t have game related properties that could confuse you. You’re confusing me here

1 Like

I dont even know how to explain myself chile I just got confused with a lot of stuff as I have the studio open myself and I try to script different codes, I thought I could help but I guess I sound like a bot so i wont be replying to this thread anymore! good luck finding a solution @ddenyz

Your extreme over the top defensive reaction just tells me that I was probably right.

1 Like