Match Players with Photon Realtime Custom Lobby Properties
Use custom room properties and JoinRandomRoom filters to match players into the right Photon Realtime room without listing every lobby entry.
06 May 2026, 19:14 UTC

Problem and useful takeaway
Photon Realtime lobbies show available rooms, but a client cannot efficiently find a room that matches a specific game mode, map, or skill bracket without checking each room individually. Custom room properties solve this by letting the server filter rooms before returning a match.
Useful takeaway: set custom room properties when creating a room, expose only the keys you need through customRoomPropertiesForLobby, and pass matching key-value pairs to JoinRandomRoom. Photon Realtime then returns only rooms that satisfy the filter.
How custom lobby properties work
RoomOptions.customRoomProperties is a string-to-object dictionary attached to a room at creation time. Every property in that dictionary is synchronized to clients that join the room, but only keys listed in customRoomPropertiesForLobby are visible to the lobby and usable as matchmaking filters.
When a client calls JoinRandomRoom with an expectedCustomRoomProperties hash table, Photon Realtime matches only rooms whose lobby-visible properties satisfy the supplied constraints. Properties left out of the lobby list are still synced to room members after joining, but they cannot narrow lobby search results.
Changing a lobby-visible property after creation sends a property update to joined clients. It does not reliably cause rooms already in the lobby to be re-evaluated for new joiners across every SDK, so treat lobby properties as relatively stable matchmaking attributes.
Worked configuration: C# client
Where to run: client-side code after the client has connected and authenticated with Photon Realtime, for example in a Unity project using the Realtime C# SDK. Required permissions: a valid Photon AppId and an active connection to the Photon Cloud region you are using.
The following example creates a ranked room and then attempts to join a random room matching its lobby-visible properties. Exact method signatures vary by SDK; inspect your SDK's API reference before copying.
using Photon.Realtime;
using ExitGames.Client.Photon;
using System.Collections.Generic;
public class LobbyMatchmaking : IMatchmakingCallbacks
{
private LoadBalancingClient client;
public void CreateRankedRoom(string roomName)
{
var roomOptions = new RoomOptions
{
MaxPlayers = 8,
IsVisible = true,
IsOpen = true
};
// Synchronized to joined members; only whitelisted keys are lobby-visible.
roomOptions.CustomRoomProperties = new Hashtable
{
{ "gameMode", "ranked" },
{ "map", "dust2" },
{ "maxSkill", 1500 },
{ "buildVersion", "1.2.3" }
};
roomOptions.CustomRoomPropertiesForLobby = new string[]
{
"gameMode", "map", "maxSkill"
};
client.OpCreateRoom(roomName, roomOptions, null);
}
public void JoinRandomRankedRoom()
{
var expectedProperties = new Hashtable
{
{ "gameMode", "ranked" },
{ "map", "dust2" }
};
client.OpJoinRandomRoom(expectedProperties, 8, MatchmakingMode.FillRoom, null, null, expectedProperties);
}
public void OnJoinRandomFailed(short returnCode, string message)
{
// No room matched the filter. Relax constraints or create a new room.
CreateRankedRoom("room_" + System.Guid.NewGuid().ToString("N")[..8]);
}
}
Expected checks: a successful match triggers the joined-room callback; a failed match triggers the join-random-failed callback with a return code and message. Risks: filters that are too strict return no room, so always implement fallback logic such as creating a new room or widening the property constraints.
Limits and what to verify
- Photon Cloud enforces limits on custom property count, total property size, and lobby property count. Exact values depend on your subscription tier; check the Photon Cloud dashboard for your AppId.
- Exceeding these limits causes room creation or join failures.
- Lobby-visible properties are visible to any client querying the lobby. Do not store passwords, authentication tokens, or player identifiers there.
- Use supported primitive types such as strings, numbers, booleans, or arrays of supported primitives. Unsupported or non-primitive values can cause serialization errors.
- Photon Realtime is not an authoritative server by default. Do not use custom properties to enforce authoritative game logic unless you are running Photon Server with custom plugins.
Common mistakes
- Exposing every custom property to the lobby. This increases lobby traffic and can leak data you intended to keep private.
- Assuming that changing a lobby property re-evaluates existing rooms for new joiners in every SDK.
- Calling
JoinRandomRoomwith strict filters and no fallback when no room matches. - Changing lobby properties frequently instead of batching updates, which can increase traffic and hit rate limits.
Practical verification
- Create two rooms with different values for the same lobby-visible key, such as
gameMode=rankedandgameMode=casual. - Call
JoinRandomRoomwithexpectedCustomRoomPropertiesset togameMode=ranked. - Confirm the client joins only the ranked room by inspecting the joined-room callback and room properties.
- Enable Photon client logging and record the return code and error message when a filter matches no available room.
- Open the Photon Cloud dashboard for your application and verify your tier's room property and lobby limits before deploying.
If room creation fails because of property limits, reduce the number of properties, shorten string values, or remove non-lobby keys; a failed creation leaves no room to delete, so there is no server-side rollback step.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.