Destinations and Rich Presence

This article introduces three concepts: Destinations, Deep Linking and Rich Presence, which work together to enable you to build experiences that are more discoverable and social.

Destinations enable you to define deep-linkable locations, levels, or game modes within your app with rich media such as images and translated descriptions, and metadata such as player limits. The Oculus Store can display these destinations on your app store page and on the parties page as recommended activities, and can aggregate users’ presence. Each destination will have an associated URL, which you can use to share new levels or game modes via social media.
The goal of destinations is enable you to create meetup places within an app that you can easily transport users to.

The Rich Presence API enables you to update the Oculus platform with a user’s current destination and status, whether they are joinable, and additional context that can help their friends know whether they can be joined in a social experience.

Whenever a user launches your app to join someone, or navigates to a destination, the Oculus Platform provides a deep-link message with this context, enabling you to take them to the right person or place in your app.

Using Destinations, Rich Presence and Deep Linking, you transport users to a specific destination, where they can play solo or join another user, or users can launch your app to the same destination for a shared social experience.

Data Use Checkup

Note that this feature accesses user data and may require you to complete the Data Use Checkup form prior to submitting your app to the Oculus Store. For more information, see Complete a Data Use Checkup.

User Experience

When users opt to share their Rich Presence, their friends can see whether they are in an app and looking for a match, playing a specific map, or participating in an event. Users control their online presence with an Activity privacy setting. A user can see a friend’s status, opt to join them, and be transported to the same destination as their friend.

For example, imagine a scenario where you add a new map to your game. With rich presence, destinations and deep linking:

  • A user can see their friend is playing the new map and launch your app to the new map to join their friend.
  • A user can see marketing for the new map and direct launch the app directly to the new map destination.
  • Two friends can group launch into your app at the same time to the new map destination and play together.

Implementation Overview

To implement Rich Presence, you define one or more Destinations for your app or app grouping that you can then deep link to.

A destination is a social gathering place within your app, which might be represented by a matchmaking pool, room, multiplayer server, or specific configuration of an activity.

Your app code sets destinations for users, which they can opt to share as their online presence with friends or with anyone.

When users opt to either join another user via their rich presence, or launch directly to a specific destination, deep linking is used to launch the app. You provide app code to check the launch status and transport the user to the correct destination.

Destinations can be configured to provide the most relevant context based on the user’s activity and whether they are joinable. For example, a destination can help users looking for a match in 1v1 game or provide a hub to direct users to an app lobby.

In summary, the steps to implement Rich Presence are:

  1. Create one or more destinations on the developer dashboard.
  2. The Oculus team approves the destination and it is then available for users.
  3. Implement code to enable users to share a destination as their status.
  4. Parse the app deep-linking URI to direct users to a specific destination.

Step 1 - Create a Destination in the Developer Dashboard

The first step to implement rich presence is to create a destination on the developer dashboard.

  1. Find your app or app grouping and then navigate to Platform Services > Destinations.
  2. On the Destinations page, choose Create Destination.
  3. In the Edit Destination page, enter:

    • Api Name - The name you will use in your code when referencing the destination. Can contain alphanumeric and underscore ( _ ) characters. Cannot contain spaces or other special characters.
    • Deeplink Message - A message that you will parse in order to navigate a user to the right place in your app. It can be formatted how you want, but must not contain any spaces. A Deeplink Message is used along with the Api Name to construct a deep link URI.

      Note: A specific deep link URL should always take users to the same destination.

    • Deeplink Type
      • ENABLED - default - Select ENABLED if this destination can be launched without a specific user being present at the destination, and your app correctly routes users to this destination. For example, deep linking a lobby destination should take a user to the lobby of the app. In addition, if enabled, the destination can be featured in the Oculus app based on its relevance or popularity.
      • DISABLED - Select DISABLED if the app cannot resolve a deep link to this destination, or if you do not want the destination to be featured. For example, a private room destination that allows friends to join one another, and shouldn’t be promoted, should not have Direct Deep Linking enabled.
      • TUTORIAL - Select TUTORIAL as the destination type if it is a tutorial destination and it does support direct deep linking.
    • Minimum Supported Group Launch (Optional): For a group launch, the minimum number of users required to launch together.
    • Maximum Supported Group Launch (Optional): Required for a group launch. Specifies the maximum number of users that can launch together. If you set this value, the app will shown as a recommendation for user events and coordinated app launches for Oculus Parties.
  4. In the Localizations section click the Modify Languages button to add languages and localized names for each language. The default is the default language you choose for the app on the Translations section of the Submit Your App page.
    • Choose a Language category, and enter:
      • A localized Display Name for that language. This name is used for display purposes, such as in a user’s status.
      • A localized Description for that language. This field is also used for display purposes.

    Repeat for each language you have entered.

  5. Finally, optionally enter the following:

    • Image - An image that represents your destination. The image must be a 2560 x 1440 PNG in 16x9 aspect ratio and 24 or 32 bit-depth. The image may be cropped, so you should leave whitespace around the edges.
  6. When finished, click Submit.

The following image shows an example of the Edit Destination page.

Edit Destination dialog

Manage and Share Destinations

  • You can edit or retrieve a sharable URL for your destinations by accessing the by context menu for a destination. To do so:
    1. Find your app, and navigate to Platform Services > Destinations.
    2. Find the destination you want to share or edit and click the ellipses (...) in the far right column.
    3. Choose Go to Destination to visit the destination and retrieve the URL from the address bar of your browser to share the destination in social media and marketing materials. This URL will be in the format:[someId].
    4. Choose View/Edit to view and edit the fields for this destination, or choose Delete to delete it.

    The following image shows an example.

    edit destination

  • You can also associate a destination with a leaderboard.

Step 2 - The Oculus Team Approves the Destination

The Oculus team must approve your destination before it will be available to users.

Destinations Criteria

  • All titles, descriptions, and images must fall within the Oculus community standard guidelines.
  • If externally deeplink is enabled, it’s expected that the user ends up at the destination within the app.
    • If it’s set to tutorial, then it’s expected that the user ends up at a tutorial.
  • If group launch is enabled, it’s expected that if a number of users within the min/max group size, then they should all end up at the destination and be together in the same instance.

Step 3 - Set the Presence for a User In-App

You define rich presence details for a user in your app by creating a RichPresenceOptions, a struct with several fields that describe a destination. The Oculus platform uses this information to display a status for the user.

The RichPresenceOptions struct has the following functions to set its fields:

  • SetApiName - Sets the api_name you specified for a destination in the developer dashboard.
  • SetCurrentCapacity - Sets the current capacity at that destination.
  • SetMaxCapacity - Sets the maximum capacity of the destination. Can be used with current capacity to see if a user can join. For example, when used with a room, set the max capacity of the destination to the max capacity of the room.
  • SetIsJoinable - Sets a boolean to indicate whether the destination is joinable. The app must determine whether the user is joinable, and if they are set this to true.
  • SetInstanceId - Set instance ID to track user presence in the same instance of the same destination. If the two users have the same instance ID and destination ID, those users have met on the Oculus Platform. This means they will be shown for each other on People You May Know in the Oculus Platform.
  • SetDeeplinkMessageOverride - Sets an optional message to override the deep-link message set in the developer dashboard. This is where you can specify the ID for a room, party, matchmaking pool or group server.
  • SetStartTime - Sets the time the current match starts or started.
  • SetEndTime - Sets the time the current match ends.
  • SetExtraContext - Sets extra information to set the user’s presence correctly.

As the user moves through your app, you can set their presence to destinations as they are applicable.

When To Mark a User as Joinable

Marking a user as joinable depends on the app you are trying to build. Following are a few examples of when to make a user joinable:

  • If a user is in an activity that enables drop-in gameplay, and there are available spaces
  • If a user is in a public lobby or matchmaking queue
  • If the user is in a room or private lobby, where their friends can launch the app to join them
  • When the user is in the main menu of an app that uses simple matchmaking, or a simple invite mechanism. In this case the user should not be in practice or solo mode.

Joinable, Extra Context and User Status

The following table shows how marking a user as joinable and providing extra context can affect the user’s status.

RichPresenceOptions and resultSample Status Displayed
  • is_joinable: true
  • ExtraContext: ovrRichPresenceExtraContext_Looking_For_Match
Status uses the value of is_joinable.
looking for match
  • is_joinable: true
  • ExtraContext: ovrRichPresenceExtraContext_CurrentCapacity
Status displays the results of comparing current_capacity to max_capacity.
  • is_joinable: true
  • end_time: 3 mins from now
  • ExtraContext: ovrRichPresenceExtraContext_EndingIn
Status displays the time remaining until end_time.
looking for match
  • is_joinable: true
  • start_time: 2 min ago
  • ExtraContext: ovrRichPresenceExtraContext_StartedAgo
Status displays the time elapsed since start_time.
looking for match

Once you’ve added a destination and set a user’s rich presence, the final step is to check for a deep link URI, which is passed in an application lifecycle update message, and navigate the user to the right place in your app.

  • Check for the Platform.ApplicationLifecycle.SetLaunchIntentChangedNotificationCallback, which is sent when a launch intent is received for both cold and warm starts.
  • Use the ApplicationLifecyle_GetLaunchDetails() method and check the LaunchType.
  • Use the ApplicationLifecycle.LogDeeplinkResult() method to report how successful the user’s deeplink launch was through a tracking ID for each intent.
  • If the app LaunchType is Deeplink, parse the LaunchDetails_DeeplinkMessage, Api_Name, UsersOptional, and RoomID fields, as follows:
ScenarioExample FieldsExample Action
Join a User: In headset, a user taps Go To on another user from the Friends List, Party panel, or Home feed."destination_api_name": "level3",
"deeplink_message":"deeplink message from the user's presence",
"users": [{"id":"123456789","alias":"otherUser"}]
Navigate this user to where the otherUser is at level3.
Direct Launch: Level 5 shows up in popular destinations based on a large number of people. A user accesses the destination from a deep link URL and remotely launches the app."destination_api_name":"level5",
"deeplink_message": "your deeplink to the destination",
"users": []
Launch the user into level5.
Group Launch: A party of 2 users choose Boss Level from a list of possible places and both users tap Launch."destination_api_name": "bossLevel",
"deeplink_message": "your deeplink to the destination",
"users": [{"id":"123456789","alias":"user1Joining"}, {"id":"67891234","alias":"user2Joining"}]
Create a room with the server API, and then launch the users into the same instance of boss_level using the room_id from the server call and the client Join2 method.

There are two recommended ways to test a deeplink in your app: using the developer dashboard, or by using the Group Launch.

The developer dashboard link will only navigate one user to the Destination. If you need to test with multiple users going to the same Destination, use the Group Launch method to test.

Create a Destination in the Developer Dashboard

You can create a Destination in the developer dashboard, and then use the link created to test deeplinks in your application.

  1. Navigate to the Developer Dashboard.
  2. Select your org, app, and then navigate to Platform Solutions > Destinations.
  3. Click Create Destination and then fill in the form.
  4. For the Destination you’re testing, click the three dot menu and then select Go to Destination.

Go to Destination on Developer Dashboard

Note: This will only navigate one user to the Destination. If you need to test with multiple users, see Use Group Launch below.

A new overview for the destination will open in a new tab. Use the url for testing deeplinks in your app.

Use Group Launch

You can use the Group Launch APIs to test Destinations.

Create a public Group Launch deeplink with the following format to create a group launch with a room. Adding the field url to the request will return a URL you can follow to verify that the Destination is working as intended.

Example curl request:

curl -X POST "<appid>/app_deeplink_public?access_token=<access-token>&destination_api_name=<api-name>&create_room=true&valid_for=<sec_as_int>&deeplink_message_override=<optional_string>&fields=url"

Example Return: {“url”:”https:\/\/\/vr\/012345678914\/”,”id”:”012345678914”}

That url can be used to test deeplinks in your app.

Test Destinations, Rich Presence and Deep Linking on Oculus Quest Devices

The following sections list some the implementation scenarios and how you might test these on an Oculus Quest and Quest 2.

#1. Join a User based on their Rich Presence

  • Users A and B should be in a party
  • Navigate User A to a joinable destination
  • With User B, open the lightweight party panel. User A should be shown with a Go To button
  • Tap this button to trigger an app launch
  • Verify the app is correctly putting User B into the same instance or room ID as User A.

#2. Direct Launch to a specific destination

  • Find your app or app grouping and then navigate to Platform Services > Destinations.
  • Click the ellipses (...) button for a specific destination and select View/Edit Destination
  • From the Edit Destination page, select Enabled for Deeplink Type.
  • From the Destinations list, click the ellipses (...) button and select Go To Destination. A new browser tab will open.
  • Preview your destination in the browser including the image, title and description
  • You will be able to see all of the Quest devices on which you’ve installed the app. Click ‘launch’ and you’ll be prompted to put on your headset.
  • Put on your headset, your app will launch.
  • Verify the app is correctly launching to the destination, with the desired behavior. For example, make sure the user is added to a matchmaking queue, if this is a matchmaking destination.

#3. Group Launch

  • Group Launch is not currently available for Oculus Rift.
  • You can test Group Launch using the Group Launch deeplink API or using the developer dashboard.
  • Ensure that your app is capable of handling race conditions if two users both launch the app at the same time, expecting to be paired with one another at a destination.

Best Practices for Destinations, Rich Presence and Deep Linking

Following are some best practices and things to consider when you incorporate destinations and rich presence in your apps.

  • Create meaningful destinations that users will be interested in. You want to create destinations that other users want to join.
  • If you get a destination, in-app, and you don’t know how to handle it:
    • Show a message that recommends the user update the app. It is possible they do not have that destination in their version.
    • Notify the user that you cannot connect the user to the destination and offer an alternative.
    • Land the user in in a joinable state if you can’t join them with another user. In other words, if a new user is trying to join an existing user at a destination, but the existing user is no longer joinable, make the new user joinable at the same destination by putting them in joinable single-player mode or in a waiting room for the game mode they were trying to join.
  • Provide UI to join users in-app. The Rich Presence API enables you to query the presence status of party members, friends and recently met users who are in your app. This makes it easy to show someone a UI to easily reconnect with their group, when they next become available.
  • Even if your app is social (joinable) in only one destination, you can create multiple destinations for your app, and mark these additional destinations as non-joinable. For these destinations, use one of the ExtraContext fields such as EndingIn to report additional details. This can help lead to social experiences. For example, a user could see that their friend has just a few minutes left in their solo game, and decide to launch the same game.
  • Finally, try to create opportunities when things don’t go as planned. For example, if a group of people wants to join a game mode destination that requires 6 to play, and for some reason only 5 people join, you still to enable the group to play together. You could move the group to a different game mode or put them into a matchmaking queue for an additional person.