The Instant Games Lifecycle and You

This is the content a GDC 2019 talk on best practices for Instant Games. This talk was also recorded for the GDC Vault, and the URL will be added here when it is uploaded.

The Instant Games lifecycle begins when a game is tapped on. The game will load, initialize and be played. Once the game is over it will leave behind custom updates and shares so that other players can find it and start the cycle all over again.

Loading is a time to make some early decisions. Currently it is not possible to access the player's locale on load, but we will soon be changing this to enable you to only load content that is localized in the right language.

You can also stream a lot of content while the player is playing to avoid upfront loading cost.

Every incremental second of loading time means that fewer players will see your game. An average of 4% of players (in the first 12 seconds) drop per second.

When a game starts, the first thing it should do is determine which context it is being played in.

Games that are played in a solo context should provide a single player experience and potentially upsell options to play with friends.

Games that are played in a thread context are already social, so they should get straight into the action.

switch (FBInstant.context.getType()) { ... 

Link contexts are unique. Everyone who visits the same URL will be in the same context. Here, try it: fb.gg/play/thedropgame/gdc

if (FBInstant.context.getType() == 'LINK') { ... 

Use getSupportedAPIs to tell you which APIs you can use without having to worry about which specific device you're playing on. If a player is playing on Android or web, you'll find that the In App Purchase APIs are available.

Whenever you start a game you should check for any unconsumed purchases. This ensures that if any previous purchases failed or the game crashed previously for any reason, the user will still get their items. Obviously only do this for items you intend to be consumable.

if (FBInstant.getSupportedAPIs().indexOf("payments.onReady") >= 0) {
  setupPayments();
}

function setupPayments() {
  FBInstant.payments.onReady(function () {
    console.log('Payments Ready!');
    // Other initialization (e.g. get the catalog)
    return FBInstant.payments.getPurchasesAsync();
  }).then(function(purchases) {
    return Promise.all(purchases.map(function (purchase) {
      return FBInstant.payments.consumePurchaseAsync(purchase.purchaseToken);
    }));
  }).catch(function(error) {
    // Handle error
  });
}

The Instant Games SDK allows you to preload up to three ads that you can show the user. Select these strategically — rewarded videos are the most effective to cache, as the player may trigger them at any time.

function preloadAds() {
  placementIds.forEach(placementId ==> {
    FBInstant.getRewardedVideoAsync(
      placementId,
    ).then(function(rewarded) {
      // Load the Ad asynchronously
      adsCache[placementId] = rewardedAd;
      return rewardedAd.loadAsync();
    }).then(function() {
      console.log('Rewarded video preloaded')
    }).catch(function(err){
      console.error('Rewarded video failed to preload: ' + err.message);
    });
  });
}

You can reduce upfront loading cost by streaming assets in as they're required. Animation or offline gameplay give the player something to do while they're waiting, and can hide the fact that you're downloading content entirely.

Custom updates are the breadcrumbs left behind from every gameplay session. These are critical for reengagement and retention. You can provide localized custom updates that will show up in the correct language for the user. If you do not localize your custom updates, we will use a localized default message. Updates show up in Messenger as well as on the Games Tab in Facebook.

FBInstant.updateAsync({
  action: 'CUSTOM',
  cta: 'Play',
  image: base64Picture,
  text: {
    default: 'Edgar just played BASH for 9 points!',
    localizations: {
      en_US: 'Edgar just played BASH for 9 points!',
      pt_BR: 'Edgar jogou BASH por 9 pontos!',
    }
  }
  template: 'WORD_PLAYED',
  data: '{ myReplayData: {...} }',
  strategy: 'IMMEDIATE',
}).then(function() {
  console.log('Message was sent successfully');
});

Instant Games have no way of knowing when they're nearing the end of their life, so remember to always save progress as you go. If you're using the in-built player data we will handle retries for you and ensure that the data is saved even if the game is quit. If you're using your own backend, however, you will need to make sure that you're handling this logic yourself.

FBInstant.player.setDataAsync({ ... }).then(...)

Facebook Analytics allows you to analyze data for your Instant Game. In addition to basic metrics, you can slice your data by platform events, such as where the player came from.

You can also compare multiple segments of your audience to look at behavior between different users, and convert a segment into a custom audience for retargeting via user acquisition campaigns.

  • When an Instant Game is loading, make sure to load the smallest set of assets possible.
  • Check the locale, and only load localized resources.
  • Finally, report progress so that the player knows how long to wait.
  • When a game is starting up, think about the context.
  • Where is the player coming from? What did they just click? Instant Games don't just have one home screen icon, they are uniquely contextual.
  • Check for any unconsumed in app purchases, in case an unclean exit messed something up.
  • And preload any ads you might need — especially rewarded videos.
  • When the player is playing, make sure you're only calling supported APIs. Load progressively, but if you can: make it stealthy so the user doesn't feel like they're waiting.
  • Always localize your custom updates. People message in their native languages and they expect games to message in their native language too.
  • Finally, save as you go. You don't know when someone will get a phone call or have a sudden need to take a selfie. Make sure that no matter what happens the player doesn't lose progress.

More Resources