Matchmaking Algorithm: Enabling Player Challenges

5 min read Michael Carroll on Aug 7, 2014
Matchmaking Algorithm-Enabling Player Challenges.jpg


We’ve updated our SDKs, and this code is now deprecated.

Good news is we’ve written a comprehensive guide to building a multiplayer game. Check it out!

challenge other playersLet’s chat about multiplayer matchmaking algorithms. In this blog post, we’ll cover how to enable multiplayer users to challenge other players. In our last two blog posts on multiplayer matchmaking, we showed you how to build random matchmaking and skill-based matchmaking.

We’ve now covered both building a multiplayer game lobby with a chatroom and the different ways we can use matchmaking to connect two different users. Here’s what we’ve covered so far:

This blog post is Part Six of PubNub Developer Evangelist Ian Jennings‘s series on creating a multiplayer game with JavaScript.

You’ll first need to sign up for a PubNub account. Once you sign up, you can get your unique PubNub keys in the PubNub Developer Portal. Once you have, clone the GitHub repository, and enter your unique PubNub keys on the PubNub initialization, for example:

One User Calls Another

Matchmaking is great, but what if you want to play against a specific opponent? Let’s add the ability to challenge another online user.

This “challenge” pattern will bring us the same synchronization functionality found in many applications. There are several uses for a matchmaking algorithm: pairing two parties on a phone call, pairing a driver and passenger, or pairing users to make edits to a document in a collaborative environment. For example, the same code we’ll write today could arrange a video call for Skype or Google Hangouts or hail a cab through Lyft or Sidecar.

challenge other players


How to Make Users Clickable

The first thing we’re going to do is add the ability to select a user from the list of#online-users. We’ll add a basic click handler to the user elements.

We’ll also add some additional CSS to show that the users are now clickable.

Handshake to Establish Communication

Great, now instead of just firing an alert() on click, we’ll pubnub.publish() our challenge. This will begin the handshake process.

challenge other players

Handshaking is an automated process of negotiation that dynamically sets parameters of a communications channel established between two entities before normal communication over the channel begins.

Message Types

Notice how the message object has changed yet again. It is now one level deeper.

In the previous chapters we only had one type of message, a chat message. Every chat message would be seen by every user so we didn’t need to do much filter.

Now we have multiple types of messages being broadcast over the same channel. There are chat messages, challenge requests, and challenge responses.

This is why we standardize the message object by adding a type property. This let’s us know how to act upon receiving different types of messages.

Message Payload

The next thing we do is add a payload property which will act as a bucket for the rest of our message information.

Making this change to the message packet means that we need to update our old chat code triggered when a message is received. Now instead of accessing for data.usernamewe check if(data.type =='chat') and then access data.payload.username instead.

Targeting Specific Users

Now that we’ve filtered our type: 'chat' messages, let’s handle our type: 'challenge' messages.

Notice the target and uuid properties in the message object from the $ function above.

Since all of our messages are sent over the same channel, how do we know who is challenging who? uuid will tell us who is sending the message, and target will tell us who is intended to receive the message.

In addition to filtering our message based on type: 'challenge', we only act on messages intended for us by ensuring == me.

Completing the Handshake

Once we receive a challenge, we’ve completed the first part of the handshake process. One user challenges another, and the other user receives the challenge.

However, it wouldn’t be fair to act upon the challenge so soon. We need to give the user who is receiving the challenge the ability to accept or deny it.

We filter upon the payload.action to divide the types of messages again. Now, messages with type: 'challenge' are also filtered between action: 'request' oraction: 'response'.

The action: 'request' message is the first message broadcast. It is sent from uuid totarget.

When the target user receives type: 'request', they are shown a prompt. The payload is then broadcast with type: 'response' and “action“` equal to the result of the prompt (boolean);

challenge other players

Handshake Code

Check out the request and response code below.

challenge other players


It’s also important to note that the values of uuid and target in the response are the reverse of values when the request is made. It could be represented simply as:

Because challenges are public we could log all challenges to the chat room if we wanted. In this case we simply choose to ignore any challenge that is not sent to us.

If we wanted challenges to remain private, we could create private channels for each user and send challenges through them. We’ll cover private user channels later in the guide.

Matchmaking Algorithm Demo

Check out the full matchmaking algorithm demo here or embedded below. We’ll begin organizing our code in the next chapter.

See the Pen Memewarz – Challenge by Ian Jennings (@ianjennings) on CodePen.0