[BETA] SimpleMatchmaking | A simple and customizable matchmaking module


GitHubV4 · DocsV1 · RobloxMarketplaceV3 · RobloxTestPlaceV3


SimpleMatchmaking is a module built with ease of use and customizability in mind using ROBLOX’s MemoryStoreService.

Warning: this module has not been tested in a production environment. If you encounter any issue please let me know.

The name is wip


  • Consistent API: all the core functions in the module are named after the built-in MemoryStoreService and DataStoreService functions.
  • High customizability: the module offers an options parameter with many customizable options.
  • Decentralization: every server is able to assign a team to a match without needing a central server.

How it works

SimpleMatchmaking makes use of MemoryStoreService SortedMaps to publish the match info (such as players and the credentials to join) to all servers. Every server can then read and modify the entry they need to add players to a match. The matching process starts by looking in the sorted map for any existing game. If one or multiple games are found the module loops through the results until it finds a game with enough slots for the given players. If no suitable game is found the module will create an empty game, add the players, publish it to the SortedMap and teleport the players.

Warning: currently the module doesn’t stop the same player from queueing more than one time.

Use guide

ⓘ For anyone that wants to snoop in the original script, the test place linked under the title is uncopylocked.

- Lobby Server
Start by downloading the module from either the ROBLOX Marketplace, the Github page or the uncopylocked place and drop the module in ServerStorage. Follow up by requiring the module from a ServerScript and then call the GetQueue function by passing the queue name and the queue options. To start the matchmaking simply call the QueuePlayers function.

Code sample using a proximity prompt
local ServerStorage = game:GetService('ServerStorage')

local SimpleMatchmaking = require(ServerStorage.SimpleMatchmaking)

local QueuePrompt = workspace.TestQueue.BoundingBox.ProximityPrompt

local qSuccess, matchCredentials

local newOptions = SimpleMatchmaking:NewOptions()
newOptions.MatchPlaceId = 13609839542
newOptions.NumberOfTeams = 8
newOptions.MaxPlayersPerTeam = 1
newOptions.MatchExpirationTime = 600

local newQueue = SimpleMatchmaking:GetQueue("newQueue", newOptions)

	local players = {}
	table.insert(players, interactingPlayer)
	qSuccess, matchCredentials = newQueue:QueuePlayers(players)

- Match server
Put a copy of the module in ServerStorage and require it in a ServerScript. Connect a function to the PlayerAdded event and then get a new queue with the same options as in the lobby server. After that call the GetPlayerTeam function and pass the player parameter. The function will return if the operation was successful and the team of the player (if they are in one).

Code Sample
local ServerStorage = game:GetService('ServerStorage')

local SimpleMatchmaking = require(ServerStorage.SimpleMatchmaking)

local newOptions = SimpleMatchmaking:NewOptions()
newOptions.MatchPlaceId = 13609839542
newOptions.NumberOfTeams = 8
newOptions.MaxPlayersPerTeam = 1
newOptions.MatchExpirationTime = 600

local newQueue = SimpleMatchmaking:GetQueue("newQueue", newOptions)

	local cSuccess, team = newQueue:CheckPlayerTeam(player)
	if not cSuccess or not team then
	player.Team = game.Teams[team]

Updates roadmap

  • An option to not save UserIds when queueing for games with teams of 1 player each.
  • Make requests scale with the amount of players passed in QueuePlayers.
  • Add a way to support rank and map selection (I don’t know how to describe this but I have some sort of idea on how to do it).

Feel free to ask any questions and leave suggestions.


Conflicting names with the pre-existing MatchmakingService.

1 Like

I tried to change the name while keeping the reference to the purpose of the module, is it good or does it still create confusion?
(still have to change the marketplace and test place names)

1 Like

The module’s name is probably the smallest of concerns. Just be creative with it.

Personally, I’d pick a name that sounds unique. I think it makes your project sound cooler.

For example, Fusion, Hana, Iris, React, Wally, Cargo, Rust, etc. (p.s. don’t actually use these specific names), instead of, well, MatchmakingService (which isn’t necessarily bad, but it could be improved).

It’s up to you, though. It’s not like this decision matter. (someone might beg to differ)


What about ‘Match’?
or ‘MatchS’?
What about maybe ‘Mascherr’?


New update

Bug fixes

  • TeleportPlayers function will no longer spam errors

New Features

  • [+] Added option to disable the built in teleport function
  • [+] Implemented SortKeys
  • [+] Added checks to not make CreateMatchAsync and TeleportPlayers functions error in studio


1 Like

Well compared to MatchmakingService, this one looks like its more understandable and developer friendly. :happy1:

1 Like

Please make a documentation for this module.

I’m currently learning how to use github pages and mkdocs and it’s going pretty smoothly so I don’t think it will be long before I complete it


I finished a bare bones version of the docs (which can be found here or in one of the card under the main title).
I’m planning on polishing the docs and adding more stuff to them (like an icon and code samples) but it’s not my main priority rn.

Looks great! I appreciate you taking the time to make a documentation. :slight_smile:

New Update - v1.0.0-beta

ⓘ Note
If a changes is marked with [:warning:] it means it will break the code if left untouched.
Right now the documentation does NOT include the changes made with the new update and will be updated in the future.

General changes

  • [:warning:] CreateMatchAsync will no longer automatically add the created server to the queue
  • The server returned by CreateMatchAsync and ReadAsync now uses a new server managment API (see new features)
  • [:warning:] AddAsync will no longer create a new server if the server argument is empty
  • GetRangeAsync will now ignore empty servers
  • The utility functions (in the Util module) CompileDefaultServer, AddPlayersToMatch and IsPlayerInMatch are now deprecated and should be replaced by the new server API (NOTE: these functions are not usable by default unless the Util module is required)

Bug fixes

  • Fixed GetRangeAsync erroring and not working when using the players argument

New Features

  • Created a new API to better manage and edit servers (ServerUtil module) (the new API can be accessed by calling CreateMatchAsync)
  • CheckPlayerTeam function now accepts a callback function as an optional argument (not passing a callback function will make the function work the same as before)
  • UpdateAsync player parameter has been replaced by the following parameters: playersToAdd and playersToRemove (both parameters are optional and leaving both arguments empty will cause in the function to not run)
  • [:warning:] AddAsync now accepts a server as a parameter instead of match credentials
1 Like