Help on fixing queue system teleport

making a queue system.

this code does teleport players to a different place, but it is very inconsistent in terms of them being teleported to the same server, I would like to ask for help to improve the teleport part and also in terms of code if needed.

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

local tpService = game:GetService("TeleportService")

local minimum = 1
local maximum = 2

local placeId = x

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 == "IN QUEUE" then
		pcall(addToQueue, player)
	elseif inQueue == "QUEUE" 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```
1 Like

I was in the middle of writing a response for the last post you made but it appears you deleted it for whatever reason.

Make sure to read TeleportService | Documentation - Roblox Creator Hub for a better grasp at what TeleportAsync represents.

The part that is tripping you up, if I am under the impression that you trying to teleport all the players into the same server, is the fact that you are using TeleportAsync without TeleportOptions.
(Visit TeleportOptions | Documentation - Roblox Creator Hub to learn more about those)

The only way you can do it this way is by Reserving a server and setting it in those teleport options. Stay with me here.

Let’s start with an Indicator:

local queueReserve = memoryStore:GetSortedMap("QueueReserve")
if not queueReserve:GetAsync("Token") then
     queueReserve:SetAsync("Token", eleportService:ReserverServer(placeId), 2592000)
end

Now we have a common interest between all the servers communicating at once.
Next, we can get started on scanning the data and teleporting:

for i = 1, 20 do -- "while wait(1) do" is a bad practice!
    task.wait(1)
	local success, queuedPlayers = pcall(function()
		return queue:GetRangeAsync(Enum.SortDirection.Descending, maximum)
	end)

	if success then

		if #data < 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 #data --[[gets the number of elements in the table.--]] == maximum then

			for _, data in queuedPlayers do -- for "i" is only needed if you are using i. Instead, you can just void it by putting a "_". This as well goes for in "pairs(queuedPlayers)". It works better if you just do in queuedPlayers. It is a good practice.

				local userId = data.value
				local player = game.Players:GetPlayerByUserId(userId)

				if player then
					local success, err = pcall(function()
                        local teleportOptions = Instance.new("TeleportOptions")

                        teleportOptions.ReservedServerAccessCode = queue:GetAsync("Token")

  
						tpService:TeleportAsync(placeId, {player}, teleportOptions)
                        queue:RemoveAsync(data.key)
                        if #queue:GetRangeAsync(Enum.SortDirection.Descending, maximum) == 0 then
                             queueReserve:RemoveAsync("Token")
                        end
					end) 
				end
			end
		end
	end
end 

Let me know how it rolls.

1 Like