Global Matchmaking System with MemoryStoreService

So I used HowToRoblox’s global matchmaking system and it worked great when I tested it in my game. When I published my update, I tested it with thousands of people and it seemed to not teleport me at all. I looked at the developer console and it repeated:

MemoryStoreService: RequestThrottled: Recent MemoryStores requests hit one or more limits. API: SortedMap.GetRange, Data Structure: Queue.

My game has around 4-8k players, so that might be the problem. The thing is, I’ve seen other games like Bedwars achieve a matchmaking system.

So how would I approach this?

I haven’t looked at that tutorial you followed, but maybe a leader election system would help you avoid calling an api too many times? Here’s a sample from Roblox of a leader election implementation https://create.roblox.com/store/asset/13595031529/Leader-Election (found on this page)

1 Like

I found a way around my original problem, but I’ve run into another one. The players are able to be teleported, but the queuing doesn’t work correctly.

Ex: The player queues up, but get teleported immediately into a server with little to no people.

Is there anything wrong with this code?

local queue = mss:GetSortedMap("BattleRoyaleQueue-0")

local cooldown = {}
local minPlayers = 10
local maxPlayers = 100
local placeID = 14934765043

--//Functions

local function addToQueue(player)
	queue:SetAsync(player.UserId, player.UserId, 2592000)
end

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

--//Events

local matchmakingEvent = rs.Events.Matchmaking

--//Script

matchmakingEvent.OnServerEvent:Connect(function(player, queueType)
	if cooldown[player] then
		return
	end

	cooldown[player] = true
	
	if queueType == "Enter" then
		pcall(addToQueue, player)
	elseif queueType == "Exit" then
		pcall(removeFromQueue, player)
	end

	task.wait(1)

	cooldown[player] = false
end)

game.Players.PlayerRemoving:Connect(removeFromQueue)

local lastOverMin = tick()

while task.wait(3) do
	local success, queuedPlayers = pcall(function()
		return queue:GetRangeAsync(Enum.SortDirection.Descending, maxPlayers)
	end)

	if success then
		local amountQueued = 0

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

		if amountQueued < minPlayers then
			lastOverMin = tick()
		end
		
		local timeOverMin = tick() - lastOverMin
		
		if timeOverMin >= 60 or amountQueued == maxPlayers then
			local reservedServerAccessCode = tps:ReserveServer(placeID)
			
			for i, data in pairs(queuedPlayers) do	
				local userId = data.value
				local player = game.Players:GetPlayerByUserId(userId)

				if player then
					local success, result = pcall(function()
						tps:TeleportToPrivateServer(placeID, reservedServerAccessCode, {player})
					end)
					
					task.	spawn(function()
						if success then
							task.wait(.25)
							
							pcall(function()
								queue:RemoveAsync(data.key)
							end)
						end
					end)
				end
			end
		end
	else
		warn("Matchmaking error: ".. queuedPlayers)
	end
end

running into the same issue !!

It may be teleporting less than the minimum number of players due to this line having an or instead of an and.

if timeOverMin >= 60 or amountQueued == maxPlayers then

Correct me if I’m wrong though.

Sorry for the late reply. I’m also creating a global match making system.

It worked great until a lot of players started joining the game.

I also kind of used this layout for global matchmaking, but the whole logic makes 0 sense to me. If you are communicating across servers how can each server have a while loop that creates a reserve server code? To counteract this, I made the key the reserve server code.

However, there are now many bugs including more than the max amount of players being tp’d to the matchmaking game.

Does anyone know how to make a match making system?