Netcode Series Part 6: Matchmaking Cross-Platform and Cross-Region

Nicola Geretti
6 min readSep 22, 2021

--

Tuning for perfect balance… or just good enough for most.

“This game has great matchmaking!” — said nobody, ever.

Let’s be honest, matchmaking is the one component of online gaming that never stops being criticized, even more so than netcode. And for good reason. Even when it functions just as you expect it, it will still not be good enough for some players.

The shuffle function on your favorite music player isn’t really random. People want a random song picked from their playlist, but they don’t really want true random. If you just listened to this one track out of 10, you probably don’t want to hear it next.

The best algorithms understand how users got to where they are, and try to deliver the best outcome to keep them going.

Matchmaking is no different, except your problem domain has more dimensions, and it has to account for the collective experience of users with different needs.

Do you even need a matchmaker?

Ok, hear me out: most multiplayer games need a matchmaker, but there are cases where your efforts are best focused on better onboarding and gameplay. Some games may not even require true matchmaking:

  • Party-based or couch co-op games
  • Drop-in, drop-out kind of games, where game sessions are flexible
  • Games where progression or skill gaps don’t have strong impact on the collective experience

When we first released ARMAJET, our mobile 4v4 PvP shooter, in closed Alpha, we knew we wanted to grow the game starting with a private invite system. We knew it would not provide enough liquidity to justify a true and fair matchmaking system.

So we didn’t make one. We created a system that allowed players to instantly join pre-generated rooms with AI, and people could drop-in and drop-out as they pleased. They could also park the room and continue playing with newly discovered friends match after match.

The result was that our audience really praised how fast and easy it was to join a game with no wait, and the social experience was incredibly strong, leading to very high retention rates among our testers.

Had we created a sophisticated matchmaking system during early access, it would’ve gated much of the experience in the interest of fairness, which wasn’t a priority at the time.

Instead, we made sure to allow anyone to create custom matches and invite whoever they pleased, which filled the need for experimentation, fairness and discovery of what the game could really become.

But ARMAJET is a twitch-based shooter where latency and skill-matching are central to competition, so we knew we would ultimately need the real deal for the open beta.

The matchmaking variables

This is applicable to so many things…

As the audience grows, so does the appetite for competition. Since most of our growth was on mobile, it was extremely important to balance the experience for wait times, especially since most matches ran for less than 5 minutes.

Today, our matchmaker takes into account quite a few variables. These are primary ones:

  • Party size
  • Criteria selected (game modes, number of players, etc.)
  • Device type (desktop, mobile)
  • Input system (controller, mouse+keyboard, touch)
  • Region latencies (pings)
  • Skill rating
  • Win/loss history

Once a request for a match is made, the Matcher API creates a new ticket in a document store for tracking, and spins up a new process. These processes tick each second to run queries against other tickets, and group tickets together based on general configurations and the criteria of the request being made.

New, independent processes allow matchmaking to scale horizontally to as many pods as needed, while running separate, context-aware heuristics that are only pertinent to that one ticket. If the user decides to cancel matchmaking, the process is killed and the ticket removed. If a match is considered made, the process locks the eligible tickets and requisitions a new server.

At a small-medium scale, the system would work file just as a single process staggering queries, but a glitch in the system could invalidate large amounts of matches, which is less likely to happen in the independent process scenario.

When tickets are compared, some variables are weighted more than others, and we generate a score to determine the affinity, like a dating service.

As logging events fires off, we are able to construct a top down view of what the status of the matchmaking process looks like, building graphs to inform of how and why players are being grouped together. Without some form of visual feedback, it would be very challenging to determine if the matching algorithm functioned as expected. It also gives us insight into how much a small configuration change may affect matching, enabling quick iteration.

Cross-platform, cross-region

Some players hate waiting, others would rather wait for a better match.

Some players hate bots, others enjoy slaughtering predictable AI.

Some players hate steamrolling noobs, others live for it.

I could go on and on, but the main variable here it time. It’s not a mystery that the more time you have to run matchmaking, the better a match will be. But there are limits, and especially on mobile, players have no interest in waiting 30 seconds for a match that lasts less than 5 minutes.

Depending on the active CCUs across the globe, our matchmaker adjusts itself to provide the best experience possible, with time being the core measure. With low traffic, we may prioritize sending players to servers sprinkling in some AI. Or if their latency is low enough, we may have 2 regions cross-play each other in the interest of getting more real players together to have fun.

Because we treat regions just like any other variable, it’s trivial to adjust thresholds based on current conditions and allow the matchmaking to do its magic. The hard part is finding the fluctuations that don’t break the game.

This is not ideal for all games, and we tested this at length. We’ve designed ARMAJET’s gameplay design, input systems parity and latency tolerance with as much care as we could, to allow players on any device or location to play fair.

We’ve been able to match EU and NA with success, but this tends to happen less as of late. Same goes for matching PC with mobile. We try and keep platforms and regions playing with their corresponding peers, but when the matching isn’t ideal at certain times of day, especially for a growing indie game, cross-platform/cross-regional play has been an incredibly useful tool to maintain social activity and make the game feel alive.

Players are really smart and they have plenty of choices for online games, so keeping them engaged is worth tweaking the matchmaker for.

Evolving Matchmaking

The way we see matchmaking evolving is by learning from its mistakes (drop Machine Learning keyword here).

We already use win/loss history as a means of artificially inflating or deflating skill rating. Consecutive losses will more likely land you playing on a powerful team or against one that’s probably going to lose, with consecutive wins doing the opposite, and it’s been an industry standard for many years across AAA games.

The next step for us is to analyze historical churn rates (players that stop playing the game) and predict churn based on the variables sent in to the matchmaker. The ultimate goal is to provide the best experience possible, which isn’t one that’s constant, but one that has its ebbs and flows based on what a player persona (data profile, if you will) is best suited for, without compromising the fairness of the matchmaking process and personal progression.

It’s not an easy task, but one that every game developer should strive for. Players want to feel the rush of winning, losing to someone more skilled, learning from their mistakes, and accelerating once again. That’s how you master a game — that’s what feels good.

Matchmaking is a big topic that we just scratched the surface of. Whether you build a system in-house or rely on the many off the shelf solutions (see the infrastructure article for some examples), the goal is to customize it to your needs, which vary depending on the stage of your game, the platform that’s being played on, and the audience you are targeting.

Don’t worry, your players will tell you if you’ve done a good job. Or at least they won’t complain as much if you did.

--

--

Nicola Geretti

Unreal Tournament world champ turned 🎮 game developer. Living the dream, fueled by multiplayer and love for engineering at scale.