Designing a Matchmaker – Part 1

Matchmaking is one of those interesting topics I love to talk about. Matchmaking is both technically challenging and requires a large amount of creative design, touching both aspects of coding that I like. A basic matchmaker will take in a certain amount of people, pair them together and send them on their way. That’s it, nothing more. It’s simple really. It becomes significantly more complicated when you start to think about how you match people together.

If all you want to do is get a random group of people together, which is perfectly fine, then you can stop reading here. As mentioned above, simply take the first group of people that go in to matchmaking and then you’re done. However, most people don’t like being grouped together randomly. Most people seek out a balanced gameplay experience. What I mean by this is that most people like to be challenged, and equally so, they don’t like to be stomped all over in their matches.

So, you want to find a way to balance out a match. You want to give the player a challenge, but you don’t want to make it too easy or too hard. Equally so, you also don’t want the player to wait for hours for a match to be made. You need to balance out all these options and give the player a match within a reasonable timeframe that gives them the experience you are looking for. 

On top of this, maybe your game has multiple modes. Maybe it has a 1v1, 2v2, 3v3, etc. Maybe it has capture the flag mode, or defend the base mode. Perhaps you’ve given your users the ability to filter their matches by all these game modes, therefore limited the possibility of matching one person against another based on their filters alone. This won’t be a problem if you have millions of active players, but does become a limiting factor if you only have an active user base in the hundreds. These filters, unfortunately, limit the number of people actively looking for the same type of match, making matchmaking last longer or unable to find the right players for a match. While it may be great to say your game has 50 modes of play, that’s essentially separating your player base. That’s something to consider when designing the game as a whole.

Okay, so we want to match people based on skill, per their filter requests, and all within the timeframe specified. Okay, let’s prioritise. First of all, if they specify a filter, we should obviously abide by that filter, so let’s get that out of the way first of all. We can create a pool of users per each possible configuration. That matchmaking pool is what we have to work with.

Now, the naive approach is simply to sort the list of users based on skill, xp, or elo score, group them together and call it job done. Run this filter every 10 seconds and then you’re done, right? Wrong. Someone with level 10 could have entered in at the last moment and yet everyone in the pool is around level 100, so the user who just entered would be WAY outclassed. Further to this, maybe right after that match, another level 10 user enters in to matchmaking, causing him to also be matched with level 100s. That wouldn’t be fun for them, so how do you handle this?

Well, you could simply just enforce some sort of minimum time in the pool, and at the same time, use a simple envelope expansion filter. Every 10 seconds, it will sort by users in the matchmaking pool, and if two users skill envelop overlap, then they are matched together. Every iteration, you increase the envelope size of those still not in a match. Okay, starting to get a little more complex now.

So now you have a users skill(however you wish to measure it, more on this in a later blog post) and an envelope in which they are actively searching. If they are level 1,000, what happens when they are waiting for 5 minutes or more for a match? Well, their envelope would continue to grow until it finds a match that is suitable for them. It may not be the ideal match for them, but it keeps them playing, right? Sounds good to me, but this is yet another one of those design decisions that must be made for the matchmaker. Okay, we’re getting somewhere on the design of this matchmaker.

Okay, problem now is that players are constantly playing the same people over and over again because their envelop expansion only includes those closest to them, and odds are, when you finish a match, you will go right back into the matchmaking pool you just left, meaning the same people would be constantly matched over and over again. The player wouldn’t experience anything new and the game would become dull and predictable. Once again, we look at the filters. Perhaps we could tweak the filters so that they can’t be matched by the same people they just played(unless they are in a party together). Problem solved, right? Well, sortof, but maybe they want to continue to play the same people.

Personally, I like the idea of shifting the envelope every few games. It’s my personal preference. The reason I do this is for a few reasons. Shifting the envelope forces the user up or down in the skill filter, which means once every 5 games or so, the user will be given an easy win, or a truly challenging loss. The other reason is because it breaks up the loop mentioned above, where users always play against the same users. 

Okay, so we’ve talked about how to match people together. As you can tell, there are many technical and design considerations to take into account. Yet, there are loads of remaining questions and design considerations to take into account. How do you deal with parties of players? What about dropouts and disconnections? How do you calculate the users skill? Skill is a huge topic in its own right, so we will start looking at that subject in next week’s article.

For now, I hope you learned something and please feel free to leave a comment or suggestion down below.

Cheers,
-Ken