Multiplayer
August 8, 2025 ยท View on GitHub
This showcase aims to demonstrate how to quickly integrate key multiplayer features from the platform, enabling easy interaction with others and friends.
Player to Arena Options
You can join or create a game in several ways. From the Main Menu, there are four options: Quick Match, Host Match, Watch Match, and Friends.

Quick Match
The Quick Match button attempts to join a random room as a client using the Photon API. If no room is available, it creates a new room as a host. Anyone can join while space is available. Once full, a new room is created for additional players.
Host Match
This option creates a private Arena where only your friends can join as spectators or players. They can join via the friends menu or through an invitation.
Watch Match
Join a random arena created by Quick Match to spectate. You can cheer for your preferred team from the stands.
Friends
The friends menu lists all your friends available to join for play or spectating.

Clicking Watch or Join initiates the process to join the room as a client. The FriendsMenuController manages the navigation flow.
Navigation Flow
The NavigationController manages the navigation flow. It uses various APIs to navigate the application, starting the connection flow through the NetworkLayer and setting the new GroupPresence via the PlayerPresenceHandler. This setup allows other users to see where the player is and if they can join.
Once connected, the NetworkStateHandler manages network state changes, handling player connections and disconnections. The SceneLoader navigates to the correct scene, synchronizing it between users using the Netcode scene manager.
Group Launch and Invitation
The UGBApplication handles group launches to an Arena or user invitations to an existing arena. It processes the intent information, such as the Destination API and lobbySessionId, to trigger the appropriate navigation flow. The lobbySessionId serves as the room name, while the Destination API indicates the region to join. The navigation controller then directs users to the correct arena and sets group presence.
VoIP
The VoipController sets up the VoIP speaker and recorder for players. It records the local player's voice and transmits it over the network, where other clients play the sound. It also checks for audio recording permissions.
The VoipHandler tracks the recorder or speaker of an entity, simplifying muting and unmuting or starting and stopping recording.
Blocking Flow and Muting
Players may encounter annoying users or blocked users in Quick Match. The BlockUserManager integrates the platform API for blocking. It fetches the list of blocked users and manages block and unblock flows, tracking blocked users' states.
The UserMutingManager mutes users in-game without blocking them at the platform level. When a player's PlayerStateNetwork updates, it mutes the player if blocked. The blocking flow is also managed in the player menu, PlayerInfoItem.

Invite Flow
During the game or pre-game phase, a button invites players to join the Arena. This triggers the invite flow from GameManager.

Invites are sent through the platform and handled as described in the Group Launch and Invitation section.
Roster
In-game, players can meet others, including friends of friends. The Roster panel allows players to quickly become friends. The in-game menu's players section manages the Roster panel. See PlayersMenu for details.
Arena Approval
To ensure players join an arena with space, we use two methods. First, Photon room properties indicate if a room is available for players and spectators. If full, the flag is set accordingly. This prevents players from joining full arenas. The implementation is in PhotonConnectionHandler and ArenaApprovalController.
The ArenaApprovalController also implements Netcode approval checks, running on the host to track user types. If too many users try to connect, it disconnects them and provides a reason.
Group Presence
Group presence is set when users change scenes or networked rooms, allowing others to join easily. The main implementation is in GroupPresenceState, which manages the group presence API and maintains local state.
Photon with Netcode for GameObject
This project uses Photon and Netcode for GameObject. We enhanced an existing Photon wrapper to integrate it as a transport layer for Netcode, adding key Photon features. The package is here.
Key differences include:
- Connection intent as client, host, or lobby. PhotonRealtimeTransport
- Private room creation with a visible flag.
- Region override for changing regions.
- Support for random room join failure. PhotonRealtimeTransport
- Room creation with parameters, allowing full project control over room creation.