server | v3 switch to v4  

Matchmaking & Room Properties

Getting into a room to play with (or against!) someone else is very easy with Photon. The workflow described here gets players into rooms without asking them to pick one (randomly) from a long list of rooms.

Random Matchmaking

If you just want to get some players into a room quickly, do the following:

  • Try "Join Random". This is an operation (named OpJoinRandom or JoinRandomRoom, depending on the API / platform).
    • In best case, that's it. Your client will join a room successfully.
    • In worst case, no room is existing or no space is left in any room.
  • If this doesn't find a room instantly, create one!
    • If you never show room names (and why should you), don't make up a name. Let the server do this! Set null or "" as "room name" when calling OpCreateRoom. The room gets a guid which is unique.
    • Apply a value for "max players". This way, the server eventually stops adding players.
  • If your client is alone in the room (players == 1): Wait. Show a screen you're waiting for opponents.
  • When enough players are in the room, you might "start" the game. To keep new players out, "close" the room. The server stops filling up the room, even if it's not full yet.
    • Note: When you close the room, there is a short time where players maybe are already on the way in. Don't be surprised if someone joins even after closing.

Using this workflow, you can skip joining any lobby and speed up things. Each client API offers a way to turn off "autoJoinLobby" on connect.

Back To Top

Not So Random Matchmaking

Totally random matchmaking is not always something players will enjoy. Sometimes you just want to play a certain map or mode (two versus two, etc.).

In Photon Cloud and Loadbalancing, you can set arbitrary room properties and filter for those in JoinRandom.

Back To Top

Room Properties And The Lobby

Room properties are synced to all players in the room and can be useful to keep track of the current map, round, starttime, etc. They are handled as Hashtable with string keys. Brief names are better, so use "gm" instead of "GameMode" as example.

By default, properties are not sent to the lobby to keep things lean. To make "map" and "game mode" available for for matchmaking, you can set a list of "room properties shown in the lobby" when you create a room.

string[] roomPropsInLobby = { "map", "ai" };
Hashtable customRoomProperties = new Hashtable() { { "map", 1 } };
CreateRoom(roomName, true, true, 4, customRoomProperties, roomPropsInLobby);

Note that "ai" has no value yet. It won't show up in the lobby until it's set in the game via Room.SetCustomProperties. When you change the values for "map" or "ai", they will be updated in the lobby with a short delay, too.

Keep the list short to make sure your clients performance doesn't suffer from loading the list.

Back To Top

Filtering Room Properties In Join Random

In JoinRandom, you could pass a Hashtable with expected room properties and max player value. These work as filters when the server selects a "fitting" room for you.

Hashtable expectedCustomRoomProperties = new Hashtable() { { "map", 1 } };
JoinRandomRoom(expectedCustomRoomProperties, 4);

If you pass more filter properties, chances are lower that a room matches them. Better limit the options.

Make sure you never filter for properties that are not known to the lobby (see above).

Back To Top

SQL Lobby

Simply put, this lobby type drops sending room-lists to clients in favour for more complex matchmaking filters for the operation JoinRandomRoom. This can be used for a sophisticated server-side skillbased matchmaking that's completely client-driven.

Internally, SQL-lobbies list rooms in a SQLite table with up to 10 special "filtering-properties". Currently, the naming of those is fixed as: "C0", "C1" up to "C9". Only integer-typed and string-typed values are allowed and once a value was assigned to any column in a specific lobby, this column is locked to values of that type.

Despite the fixed filtering-property names, clients have to define which ones are needed in the lobby. As always, values for these room properties can be set anytime. Other properties can be set (as usual) but can't be used in matchmaking.

Queries can be sent with a new parameter in Op JoinRandomGame. The filtering queries are basically SQL statements based on the "C0" .. "C9" values.

Examples:

  • "C0 = 1 AND C2 > 50"
  • "C5 = \"Map2\" AND C2 > 10 AND C2 < 20"

Back To Top

Skillbased Matchmaking

You can use lobbies of the SQL-type to implement your own skillbased matchmaking.

First of all, each room gets a fixed skill that players should have to join it. This value should not change, or else it will basically invalidate any matching the players in it did before.

As usual, players should try to get into a room by JoinRandomRoom. The filter should be based on the user's skill. The client can easily filter for rooms of "skill +/- X".

JoinRandomRoom will get a response immediately as usual but if it didn't find a match right away, the client should wait a few seconds and then try again! You can do as many or few requests as you like. Best of all: The client can begin to relax the filter rule over time.

It's important to relax the filters after a moment. Granted: A room might be joined by a player with not-so-well-fitting skill but obviously no other room was a better fit and it's better to play with someone.

You can define a max deviation and a timeout. If no room was found, this client has to open a new room with the skill this user has. Then it has to wait for others doing the same.

Obviously, this workflow might take some time when few rooms are available. You can rescue your players by checking the "application stats" which tell you how many rooms are available. You can adjust the filters and the timing for "less than 100 rooms" and use different settings for "100 to 1000 rooms" and again for "even more".

To Document Top