How to make universal matchmaking?

  1. What do you want to achieve? Keep it simple and clear!
    The title is a little misleading. I have a game where you can start matchmaking and it will match you with players in the server, however, if you don’t match with players in your server within 5 minutes it will solo match you with bots and you can also choose to solo match. I have the problem of players not wanting to wait, and just choosing solo match. I would like a system where when in a solo match, if a match is made they are notified and prompted to join.
  2. What is the issue? Include screenshots / videos if possible!
    All I need to know is how to send reserved place ids across servers and names across servers. For example: local reservedid = 123456789 local playersinqueue = {player1.Name,player2.Name}
    I am not asking for an entire script, just want someone to point me in the right direction.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have looked around the developer hub and looked at the messaging service but I don’t really understand it.
3 Likes

Hopefully I’m understanding the question correctly! If so then messaging service should be perfect for this!

You would need two threads/scripts. One in the main hub place (where players join the queue), and the other where ever the “solo match” place is. Assuming they are separate places under the same universe.

Main Hub Place:

This is just an example but in the main hub you could do something along the lines of:

-- Services --
local PS = game:GetService("Players");
local MS = game:GetService("MessagingService");
local TSS = game:GetService("TeleportService");

-- Variables --
local QueueList = {68271724, 68271722} -- These are userIds!! It's better to use the players UserId instead of the players name in my opinion

-- This would be a seperate thread in the main lobby where the players were first put into queue --
function MatchIsReady(TableOfPlayers) -- Basically fire this function when the match is ready (this is an example)
	-- Send a table of player Ids (in this example it would be the QueueList)
	local ServerCode, ServerId = TSS:ReserveServer(game.PlaceId); -- This is an example "ReservedServer" that players get teleported to 
	
	local DataToSend = {
		MessageType = "MatchReady";
		AccessCode = ServerCode; -- The Access code so you can use TeleportToPrivateServer()
		PrivateServerId = ServerId; -- The PrivateServerId incase you want to use it for whatever
	};
	
	for _, PlayerId in pairs(TableOfPlayers) do -- Loop through all our queued players
		local Success, Error = pcall(function()
			-- Note that you could assign 1 topic for this specfic Queuelist and only fire 1 publish async with that topic
			-- but since this is just a simple example I'm going to loop through the QueueList
			-- As I stated this is just an example to help guide you so refer to MessagingService limits!!
			MS:PublishAsync(PlayerId, DataToSend); -- Send a message with the players UserId as the topic (this means only that specfic player will recieve this message).
		end);
	end;
end;

MatchIsReady(QueueList); -- Example of calling the function

Note that this only will work if the server that queued the players is still alive.

So if all players were to leave the main hub (and the server shutdown) then it wouldn’t really work because well the server shutdown. So you could either save the queue list to a datastore, etc if thats what you need to do, but if its like an 100 player queuing hub then you should be fine as I doubt it would suddenly drop to 0 players anytime soon.

Solo Match Place:
Now that we have our hub ready we just need our Solo-Match servers to listen for the message:

-- This would be a seperate thread that is in the solo matches (where the players get tp'ed to if they do solo) --
PS.PlayerAdded:Connect(function(Player)	
	local Connection;
	
	local Success, Error = pcall(function() -- Always wrap in a pcall
		Connection = MS:SubscribeAsync(Player.UserId, function(Content) -- We subscribe to the Players UserId so we can recieve the messages!
			-- Content will contain 2 arguments. One being the data we sent (Content.Data) and the other being the time it was sent (Content.Sent)
			if Content.Data then
              -- Do whatever here!! Either force them by teleporting them to the server or fire a remote and prompt them!
				print(Content.Data.MessageType);
				print(Content.Data.AccessCode);
				print(Content.Data.PrivateServerId);
			end;
			Connection:Disconnect(); -- Always disconnect when you don't need to subscribe anymore
		end);
	end);
	
	Player.AncestryChanged:Connect(function() -- Assume they dc'ed or left or already joined. So disconnect if connection existed
		if Connection then
			Connection:Disconnect(); -- Always disconnect when you don't need to subscribe anymore
		end;
	end);
end);

Note:
This is only an example to help guide and give you insight. It may have typos, or may not obey Messaging service limits or have “good” practices. So please make sure you read the api and double check everything:

Anyway, hopefully this helps and goodluck!!

8 Likes

Wow thank you so much for this, I read over your code and now I actually understand the messaging service. I have implemented my own version into my game.