Enable playing a multiplayer game with friends by using Multiplayer Manager

In a simple multiplayer scenario, a player of your game can play it online with friends. This topic describes the basic steps that you need to implement to support this scenario by using Multiplayer Manager.

Steps to send and accept an invite

The following steps use Multiplayer Manager to send an invite to a user's friend so that friend can join a game in progress.

  1. Initialize Multiplayer Manager
  2. Create the lobby session by adding local users
  3. Send invites to friends
  4. Accept invites
  5. Join a game session from the lobby

Steps 1, 2, 3, and 5 are done on the device that's performing the invite. Step 4 is typically initiated on the invitee's device, following app launch via protocol activation.

For more information, see Playing a game with friends (flowchart).

Initialize Multiplayer Manager

The lobby session object is automatically created when Multiplayer Manager is initialized with a valid session template name. Session templates are defined in the service configuration.

Note

The lobby session instance on the service isn't created until a user has been added.

Flat C API

HRESULT hr = XblMultiplayerManagerInitialize(lobbySessionTemplateName, queueUsedByMultiplayerManager);

For more information, see XblMultiplayerManagerInitialize.

Return to the top of this topic.

Create the lobby session by adding local users

Add the locally signed-in Xbox services users to the lobby session. A new lobby is hosted when the first user is added. All other users are added to the existing lobby as secondary users.

Multiplayer Manager advertises the lobby in the shell for friends to join. You can send invites, set lobby properties, and access lobby members via lobby() only after you've added the local user.

When a local user joins the lobby, we recommend setting their connection address and any custom properties.

You must repeat this process for all locally signed-in users.

Return to the top of this topic.

Add a single local user

Flat C API

HRESULT hr = XblMultiplayerManagerLobbySessionAddLocalUser(xblUserHandle);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set member connection address.
const char* connectionAddress = "1.1.1.1";
hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
    xblUserHandle, connectionAddress, context);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set custom member properties.
const char* propName = "Name";
const char* propValueJson = "{}";
hr = XblMultiplayerManagerLobbySessionSetProperties(propName, propValueJson, context);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}
...

For more information, see the following:

Return to the top of this topic.

Add multiple local users

Flat C API

std::vector<XblUserHandle> xblUsers;
for (XblUserHandle xblUserHandle : xblUsers)
{
    HRESULT hr = XblMultiplayerManagerLobbySessionAddLocalUser(xblUserHandle);

    if (!SUCCEEDED(hr))
    {
        // Handle failure.
    }

    // Set member connection address.
    const char* connectionAddress = "1.1.1.1";
    hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
        xblUserHandle, connectionAddress, context);

    if (!SUCCEEDED(hr))
    {
        // Handle failure.
    }

    // Set custom member properties.
    const char* propName = "Name";
    const char* propValueJson = "{}";
    hr = XblMultiplayerManagerLobbySessionSetProperties(propName, propValueJson, context);
    ...
}

For more information, see the following:

The changes are batched on the next XblMultiplayerManagerDoWork call. Multiplayer Manager fires a XblMultiplayerEventType::UserAdded event each time a user is added to the lobby session.

We recommend that you check the error code of the event to see if that user was successfully added. In case of a failure, an error message provides details of the reasons for the failure.

Multiplayer Manager performs the following functions to create the lobby session by adding local users.

  • Register Real-Time Activity and multiplayer subscriptions with the Xbox services multiplayer service.
  • Create the lobby session.
  • Join all local players as active.
  • Upload the secure device address (SDA).
  • Set member properties.
  • Register for session change events.
  • Set the lobby session as an active session.

Return to the top of this topic.

Send invites to friends

Display the standard Xbox UI where the player can select friends or recent players to invite to the game. When the player confirms their selection, Multiplayer Manager sends the invites to the selected players.

Games can also use the XblMultiplayerManagerLobbySessionInviteUsers method to send invites to a set of people who are defined by their Xbox services User IDs. This method is useful if you use your own in-game UI instead of the standard Xbox UI.

Flat C API

size_t xuidsCount = 1;
uint64_t xuids[1] = {};
xuids[0] = 1234567891234567;
HRESULT hr = XblMultiplayerManagerLobbySessionInviteUsers(
    xblUserHandle, 
    xuids, 
    xuidsCount, 
    nullptr,    // ContextStringId 
    nullptr     // CustomActivationContext
);

For more information, see XblMultiplayerManagerLobbySessionInviteUsers.

Multiplayer Manager performs the following functions to send invites to friends.

  • Displays the Xbox standard title-callable UI (TCUI)
  • Sends an invite directly to the selected players

Return to the top of this topic.

Accept invites

When an invited player accepts a game invite or joins a friend's game via a shell UI, the game is launched on their device.

On Microsoft Game Development Kit (GDK)-based games, after the game starts, listen to invite events by calling XGameInviteRegisterForEvent.

On Xbox One Software Development Kit and Universal Windows Platform (UWP)-based games, after the game starts, Multiplayer Manager can use the protocol-activated event arguments to join the lobby.

If the invited user isn't added via XblMultiplayerManagerLobbySessionAddLocalUser, XblMultiplayerManagerJoinLobby will fail and provide the xuid for which the invite was sent by calling XblMultiplayerEventArgsXuid with the JoinLobbyCompleted event.

After joining the lobby, we recommend setting the local member's connection address and any custom properties for the member. You can also set the host via XblMultiplayerManagerLobbySessionSetSynchronizedHost if one doesn't exist.

Finally, Multiplayer Manager auto-joins the user into the game session, if a game is already in progress and has room for the invitee. The title is notified through the JoinGameCompleted event, providing an appropriate error code and message.

Error or success results are handled via the JoinLobbyCompleted event.

Flat C API


void CALLBACK MyXGameInviteEventCallback(
    _In_opt_ void* context,
    _In_ const char* inviteUri)
{
    UNREFERENCED_PARAMETER(context);
    if (inviteUri != nullptr)
    {
        std::string inviteString(inviteUri);
        auto pos = inviteString.find("handle=");
        auto inviteHandleId = inviteString.substr(pos + 7, 36);

        // Now use inviteHandleId when calling XblMultiplayerManagerJoinLobby().  
        // See the example call as follows.
    }
}

XTaskQueueRegistrationToken token = { 0 };
HRESULT hr = XGameInviteRegisterForEvent(
    queue,
    nullptr,
    MyXGameInviteEventCallback,
    &token);

HRESULT hr = XblMultiplayerManagerJoinLobby(inviteHandleId, xblUserHandle);
if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set member connection address.
const char* connectionAddress = "1.1.1.1";
hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
    xblUserHandle, connectionAddress, context);

For more information, see the following:

Multiplayer Manager performs the following functions to accept invites.

  • Register Real-Time Activity and multiplayer subscriptions.
  • Join lobby session.
  • Existing lobby state cleanup.
  • Join all local players as active.
  • Upload the SDA.
  • Set member properties.
  • Register for session change events.
  • Set lobby session as the active session.
  • Join game session (if one exists).
  • Use a transfer handle.

Return to the top of this topic.

Join a game session from the lobby

After invites have been accepted, and the host is ready to start playing the game, you can start a new game that includes the members of the lobby session by calling XblMultiplayerManagerJoinGameFromLobby.

Error or success results are handled via the JoinGameCompleted event.

Flat C API

HRESULT hr = XblMultiplayerManagerJoinGameFromLobby(gameSessionTemplateName);
if (!SUCCEEDED(hr))
{
    // Handle error.
}

For more information, see XblMultiplayerManagerJoinGameFromLobby.

Multiplayer Manager performs the following functions to join a game session from the lobby.

  • Create game session.
  • Join all local players as active.
  • Upload the SDA.
  • Set member properties.
  • Register for session change events.
  • Advertise game via lobby session.

Return to the top of this topic.