How would i go off creating a Matchmaking system?

Hello, i have been thinking about creating a matchmaking system for my “tower defense” game, and i was wondering which tools could i use and ofc keep it optimized. I do not think i’ll make it a “skill based” matchmaking however or just add a single person to a queue to a specific well queue

In context, my “matchmaking” system is within a party system, basically people can create a party with informations like which gamemode was chosen, what’s the level requirement, how much player can the match hold (1 to 4), if joining is locked behind “friend only” or a “code only”, current players in the party and finally modifiers (like idk “Enhanced Enemies” laking the enemies 2x strong and 1.5x faster and etc). What i planned on is that you create a party, once created you get teleported to a “lift” (which is heavily inspired from Tower Defense Simulator matchmaking beta test and Flood Escape 2 lift, both are great gaems!!)

(sorry for the video quality i just uploaded it to youtube!)

For now i have thought about using MemoryStoreService which seems to be dedicated for matchmaking system and other quick data saving api call stuff, and also use a little of MessagingService like to warn the server a party has been found and etc (if another party has found this match, i will get with an issue with that later on this message). However both of those do have a limit of 1kb per user. Which ofc means i’m technically large since it would moslty consists of 4 users for 1 party, which will be more like 4kb per party (theoretically speaking, since they be below 4 users). I have no idea if storing all the infos of my party will take too much or if i will be fine. Moreover i’m wondering i should save the player datas in the party itself, obtain data from the datastore or add those in a separate SortedMaps for “quick caching” and lessening datastore api calls. There are also the cases also known as “Race conditions” (" In the context of matchmaking in games, a race condition could occur when two teams simultaneously try to claim the same match or resource.", in my case 2 teams finding in the same time another party, causing due to syncing delay time to both of them join, causing more players to join than what there should be) that i have no idea how to handle.

I also have a bunch of other questions but i inconvinently forgot them while writting this.

Btw i’m also out of idea for my ui! so any suggestion by what should i replace this ui with would be appreciated!

Bumping that up, cuz well yes i’do like to have an answer please

You can curtail a lot of these problems by having a large server that hosts only matchmaking.

For example, the main game is simply the shop / loadout changer / matchmaking queue and you teleport players to the battlegrounds. Cross server parties and matchmaking sounds nice but why go through the hassle if you can have a 200 player lobby that handles it all in one server?

true but that may be too much on the cpu and wifi side

If your game is well optimized both in geometry and networking you don’t have to worry about that. You can always downsize server-size to 100 and the problem then would be non-existent.

true, but just players alone walking generate immense amount of recv and i’do prefer not create a custom movement just for that.

Another issue is that my lobby is quite demanding cuz i think i may have went overboard with the lighting on it, i can just remove demanding graphic stuff tho and disable shadows

I’ll try my best to answer your questions. So for the first part of how to actually go about saving the party information to memory store:

I suggest you keep the information you’re going to store to the bare minimum. Stuff such as the players level, gold, xp, towers and other random info can be accessed directly from the datastore and cached for future use (within the lift waiting room). You can get an estimate of the bytes your table contains by using JsonEncode on it.

Example of party info you might send:

-- Party Info --
local PartyInfo = { -- Try to only keep the data you actually need!!
	Name = "Party1"; -- Make sure you set a character limit for both the party name and code so players dont add more unnecessary bytes to memory!
	Code = "MyPassword"; -- You can have it set to "" or nil if you dont want a password
	FriendsOnly = false; -- Whether its restricted to friends only.

	Players = 3;  -- Size of party
	Level = 2; -- Required minimum level 
	Mode = "Hard"; -- This would represent the difficulty including whether mobs have 2x speed/health, etc
	
	Owner = 1234567; -- This is the userid of person who made party. Use userid instead of player name to save on charactersz
	ID = "This would be the reserved server id or where ever you plan to teleport the player, etc";	
};

-- Get bytes amount
-- You DONT need to use "JSONEncode" as roblox will automatically do this when saving to a datastore. 
-- I'm just doing this to give you a visual example of how many bytes you actually might be using.
local Encode = game:GetService("HttpService"):JSONEncode(PartyInfo);
local CurrentBytes = utf8.len(Encode);

print("You used "..CurrentBytes.." bytes. You have "..1000 - CurrentBytes.." bytes left."); -- We -1000 cause 1kb = 1000 bytes

As for saving the “modifiers” such as “2x strength, 1.5x speed”. You could either have the mode thats selected (easy, medium, hard, etc) be what determines the mob modifiers OR when players get teleported to the actual game → you can have them vote (or the party leader) choose any additional modifiers in game without having to store that information.

Lastly, for your issue regarding two players joining the same party at the same time (resulting in 5/4 players in a party). The easiest method would be → In your lift waiting room have a playerAdded connection → when a player joins if the party is already full (4/4) → teleport the extra player back to the queueing hub with information to auto-requeue. You could make this feel seamless by having a custom loading screen and display a simple “opps party is full”. Note that this method should only be as a failsafe. You should be doing checks to make sure the party isn’t already full.

Hopefully this helps. If you have any other questions feel free to ask!

1 Like

hmm interesting, i did intend into keeping only essential data on my matchmaking, since in this place it will only display the towers and level so those should be the only player data kept (along side their user id ofc)

technically modifiers could be saved on the host server and stuff, then once teleport could be sent well via teleport datas stuff so no need to save to the queue and etc,

race condition part idk what to say

btw one thing, isn’t 1kb technically 1024 bytes!!! but that won’t change that much.

Thanks for the help!

Yea, just try to keep the bare minimum info you need since you’re dealing within a very small memory limit.

You can send it as teleport data when the players are placed but I wouldn’t recommend saving it to memory store if you plan on having a lot of modifiers (Assuming you want players to be able to queue for specific modifiers as well, otherwise just send as teleport data and you’re good!)

What part are you confused on?

Yep, you’re right. I rounded down for simplicity.

You might find this useful:

1 Like

“race condition part idk what to say” I meant that i didn’t really had anything to say over that part my bad :pray:

Thanks for the help once again and i don’t have anything to say again over what you just said it’s good enough of a help :+1:

I should be looking into this ig thanks

1 Like

Yeah now i’m having an issue with handling the party owner, imagine 2 parties came together what do i do with those 2 owners? how do i make sure to keep only 1?

I think the issue here is my general approach being incorrect and i probably need to re think of that