Party Platform-specific Support

The Party plugin can integrate with platform-specific sessions/lobbies/parties and invitations.

Session

From here on, “platform-specific session” refers to a mechanism, provided by a platform’s online service, for grouping players together for online play. For instance, on Steam, these are called lobbies. On PS4, they are called sessions.

When a player on platform A joins a party, the party system checks if a platform A session already exists for this party. If there is one, the player joins the existing session, in addition to the party. If not, a session is created for the party, and the player joins it. All of this happens during the joinParty() or createParty() calls.

Currently, Stormancer has built-in party platform support for Steam and PS4 (on-demand).

Read on if you want to add support for another platform.

Implementing support for a new platform

The party system has extensibility points server-side and client-side that allow integration with any platform.

Client-side

To implement client-side support, you should subclass Party::Platform::IPlatformSupportProvider, and implement the methods that are relevant to your platform. Register the resulting class as a Party::Platform::IPlatformSupportProvider in the client’s dependency container. See Dependency Injection Mechanism for details on dependency management.

Note

IPlatformSupportProvider has a constructor that takes an InvitationMessenger object. Your subclass will have to provide this object through its own constructor. This object is available through the usual dependency resolution mechanism. Provide it when registering your class in the dependency container, along with your class’ own dependencies.

../../../_images/party.svg

Relationship between PartyApi, Party_Impl and IPartyPlatformSupport instances

PartyApi is the “surface” API of the party system. It is what the game interacts with.

Party_Impl contains the implementation of the methods of PartyApi.

IPlatformSupportProvider implementations are driven by Party_Impl. They have no direct relationship to PartyApi.

There can be multiple IPlatformSupportProvider implementations active at the same time on the same client.

class Stormancer::Party::Platform::IPlatformSupportProvider
std::string IPlatformSupportProvider::getPlatformName()

The name of the platform that this IPlatformSupportProvider implements support for. It should be unique across all IPlatformSupportProvider implementations.

pplx::task<void> IPlatformSupportProvider::createOrJoinSessionForParty(const std::string &sceneId)

Only relevant if your platform supports sessions

This method is called by the party system after a party’s scene has been joined.

In the implementation of this method, you should do one of two things:

  • If the party in question does not yet have a platform-specific session for the platform you are implementing the provider for, create such a session.

  • If such a session already exists, join it.

This method is called regardless of whether you are creating a party or joining an existing one. This is designed to support cross-play scenarios. For instance, if player b on platform B joins a party created by player a on platform A, you might still want to create a “B session” for the party.

If the platform supports it, sceneId should be stored in the metadata of the newly created session, so that it can be retrieved later when joining the session.

../../../_images/createparty.svg

Sequence diagram of a party creation, including the call to createOrJoinSessionForParty

struct Party::PartyId

A PartyId is an abstract way to identify a party, and contains information that can be used to join said party. It can refer to the Stormancer Scene Id of the party, or the Id of a platform-specific session associated with a party, for example.

When the game calls PartyApi::joinParty(const PartyId&), the party system asks the IPlatformSupportProvider that matches the PartyId’s platform to resolve the stormancer scene Id of the party, in order to join the scene.

std::string platform

The platform that this PartyId originates from. It must be the same as the value returned by IPlatformSupportProvider::getPlatformName().

std::string type

The platform-defined type of this Id. This is useful if a platform has more than one type of PartyId.

std::string id

The platform-specific id that identifies a party.

When implementing a new IPlatformSupportProvider subclass, you will probably want to also create a new type of PartyId for this new platform. Here is an example of what this might look like:

// File: MyPlatformSupport.hpp

const char* MY_PLATFORM_NAME = "myplatform";
const char* MY_PLATFORM_PATYID_TYPE = "mysession";

PartyId myPartyId;
myPartyId.platform = MY_PLATFORM_NAME;
myPartyId.type = MY_PLATFORM_PATYID_TYPE;
myPartyId.id = "<made-up mysession handle>";
pplx::task<std::string> IPlatformSupportProvider::getPartySceneId(const PartyId &partyId)

Obtain the Stormancer Scene Id of the party associated to the provided Party::PartyId.

This method is called by the party system when a request to join a party is made using a PartyId associated to the platform of your IPlatformSupportProvider implementation.

You must perform the necessary operations to retrieve the Id of the scene using the provided platform-specific partyId.

Building upon the previous example, if mysession provides the ability to store per-session metadata, the Stormancer Scene Id of the party could be stored there when the session is created by createOrJoinSessionForParty(). Assuming this session provides a way to retrieve the metadata without first joining the session, this metadata retrieval operation should be done inside this method.

../../../_images/joinparty.svg

Sequence diagram describing the process of joining a party through a PartyId

bool IPlatformSupportProvider::tryShowSystemInvitationUI()

Only relevant if your platform supports invitations

Show the platform’s generic UI that allows the player to send invitations to the current party.

If the UI was displayed successfully, you must return true. If not, or if your platform does not support this feature, you must return false.

Subscription IPlatformSupportProvider::subscribeOnJoinPartyRequestedByPlatform(std::function<void(const PartyId&)> callback)

Only relevant if your platform supports invitations

Listen to platform-specific ou-of-game events related to joining a party, and signal them to the party system through callback.

Such events may include:

  • Accepting an invitation from the platform’s out-of-game UI

  • Clicking a “join session” button from a friend’s profile or activity page on the platform UI.

The Party::PartyId argument to callback must be the Id of the party to be joined.

You IPlatformSupportProvider implementation must not join the party at this time. The decision to join the party or not will be left to the game, and handled by the higher-level party sytem.

../../../_images/joinfromplatform.svg

Sequence diagram outlining the interactions between the party system and a typical “join from system” platform functionality

If you want to support cross-platform invitations, you should also subclass Party::Platform::IPlatformInvitation for your platform. On the other hand, if you only need basic platform-specific invitation functionality and do not support cross-platform invitations, implementing IPlatformSupportProvider::tryShowSystemInvitationUI() and IPlatformSupportProvider::subscribeOnJoinPartyRequestedByPlatform() will be sufficient.

For more details, see the API reference for IPlatformSupportProvider and IPlatformInvitation.

For a sample implementation, see the Steam plugin’s SteamPartyProvider class.

Server-side

Server-side support can be implemented by subclassing IPartyEventHandler. OnJoining() should be where the platform-specific session is created, and players are added to the session. OnQuit() should be where players are removed from the session, and possibly where it is destroyed. Register the resulting class as a IPartyEventHandler in the host’s dependency container.

If you want the party API to integrate seamlessly with platform-specific invitations in cross-platform play scenarios, you should subclass IPartyPlatformSupport. Register the resulting class as a IPartyPlatformSupport in the host’s dependency container. Note that this class has no client-side equivalent. The platform-agnostic invitation API in Party requires this functionality to be server-side. If your platform can only send invitations from the client, and not from a 3rd party server, you should implement IPartyPlatformSupport.SendInvitation() as a server-to-client RPC, where the client performs the actual operation.

How to decide between client-side or server-side implementation

It depends on the capabilities offered by your platform.

On some platforms, you can only perform session operations (create, join, leave, update, etc.) from the client, or the options available for third-party servers are lesser. On such platforms, there is no choice but to implement party support client-side.

For platforms that allow session operations to be performed from a third-party server, the choice is more open.

We tend to prefer server-side implementations where possible (and practical).

Remember that it is possible to mix both. If a certain feature is implemented on the server in a IPartyEventHandler subclass, just leave the body of the corresponding method in your client-side IPlatformSupportProvider subclass empty, and vice versa.

Some functionalities, such as platform-specific UI support (invitation UI and joining a party from outside the game), can only be implemented on the client.