# Interstitial Ads


Interstitial ads are full-screen advertisements that cover the entire game view and are shown at natural transition points in your game.

## When to Use Interstitial Ads

The key to effective interstitial ads is **timing**. Show them at moments when the player expects a pause in the action:

- **Between levels** — After completing a level and before the next one begins.
- **After game over** — On the game-over screen, before returning to the main menu.
- **During screen transitions** — When switching between major sections of your game (e.g., from the shop back to the menu).
- **After completing an objective** — When the player finishes a challenge, mission, or quest.
- **On app resume** — When the player returns to the game after being away (use with caution).

### When NOT to Show Interstitial Ads

- **During active gameplay** — Never interrupt a player mid-action. This is the fastest way to drive players away.
- **Immediately at game start** — Let the player engage with your game before showing any ads. Showing an ad before the first play session is a very poor experience.
- **Too frequently** — The platform enforces a minimum 30-second interval between interstitial ads. Even if the platform allows it, showing ads every 30 seconds will frustrate players. Aim for natural breaks that occur every 1-3 minutes at most.
- **During time-sensitive moments** — Do not show ads right before a boss fight, during a countdown, or at any moment where the interruption would feel disrespectful of the player's investment.

## Creating an Interstitial Placement

Set up your interstitial placement in Monetization Manager:

1. Go to the [Monetization Manager](https://www.facebook.com/audiencenetwork/).
2. Select your app.
3. Click **Create Placement**.
4. Choose **Instant Games** as the platform.
5. Select **Interstitial** as the ad format.
6. Give the placement a descriptive name (e.g., "Between Levels Interstitial" or "Game Over Interstitial").
7. Save and note the **Placement ID**.

Consider creating separate placements for different locations in your game (e.g., one for between levels, another for game over). This lets you track performance per location and optimize your strategy.

## SDK Integration

Interstitial ads follow the **create, preload, show** pattern.

### Creating an Ad Instance

```javascript
var interstitialAd = null;

FBInstant.getInterstitialAdAsync('YOUR_PLACEMENT_ID')
  .then(function (interstitial) {
    interstitialAd = interstitial;
    console.log('Interstitial ad instance created.');
  })
  .catch(function (error) {
    console.error('Failed to create interstitial instance:', error.code);
  });
```

### Preloading the Ad

Once you have an ad instance, preload it so it is ready to display immediately:

```javascript
interstitialAd.loadAsync()
  .then(function () {
    console.log('Interstitial ad preloaded and ready to show.');
  })
  .catch(function (error) {
    console.error('Failed to preload interstitial:', error.code);
  });
```

**Preload as early as possible.** The best time to preload your first interstitial is during game initialization, right after `FBInstant.startGameAsync()`. Preloading can take several seconds (especially for video ads), so you want the ad ready well before you need it.

### Showing the Ad

When the player reaches a natural break, show the preloaded ad:

```javascript
interstitialAd.showAsync()
  .then(function () {
    console.log('Interstitial ad shown successfully.');
    // The ad instance is now spent - preload a new one
    preloadNextInterstitial();
  })
  .catch(function (error) {
    console.error('Failed to show interstitial:', error.code);
  });
```

### Important: Ad Instance Lifecycle

Each ad instance can only be shown **once**. After calling `showAsync`, the instance is consumed and cannot be reused. You must create and preload a new ad instance for the next impression.

```
Create instance --> Preload --> Show --> [Instance is spent]
                                              |
                                              v
                                    Create new instance --> Preload --> Show --> ...
```

## Complete Integration Example

Here is a full implementation showing how to manage interstitial ads throughout a game session:

```javascript
var interstitialAd = null;
var isInterstitialReady = false;
var lastAdShownTime = 0;
var MIN_AD_INTERVAL = 60000; // Show at most one interstitial per 60 seconds

// Preload an interstitial ad
function preloadInterstitial() {
  isInterstitialReady = false;

  FBInstant.getInterstitialAdAsync('YOUR_PLACEMENT_ID')
    .then(function (interstitial) {
      interstitialAd = interstitial;
      return interstitialAd.loadAsync();
    })
    .then(function () {
      isInterstitialReady = true;
      console.log('Interstitial ready.');
    })
    .catch(function (error) {
      isInterstitialReady = false;
      handleInterstitialError(error, 'preload');
    });
}

// Show an interstitial if one is ready and enough time has passed
function showInterstitialIfReady() {
  var now = Date.now();

  // Enforce a minimum interval between ads
  if (now - lastAdShownTime < MIN_AD_INTERVAL) {
    console.log('Too soon since last ad. Skipping.');
    return;
  }

  if (!isInterstitialReady || !interstitialAd) {
    console.log('Interstitial not ready. Skipping.');
    return;
  }

  isInterstitialReady = false;
  lastAdShownTime = now;

  interstitialAd.showAsync()
    .then(function () {
      console.log('Interstitial shown successfully.');
      // Immediately preload the next ad
      preloadInterstitial();
    })
    .catch(function (error) {
      handleInterstitialError(error, 'show');
      // Try to preload again for next time
      preloadInterstitial();
    });
}

// Handle errors
function handleInterstitialError(error, phase) {
  switch (error.code) {
    case 'ADS_NO_FILL':
      console.log('No interstitial ad available. Will retry later.');
      setTimeout(preloadInterstitial, 30000);
      break;
    case 'ADS_FREQUENT_LOAD':
      console.log('Interstitial load too frequent. Backing off.');
      setTimeout(preloadInterstitial, 60000);
      break;
    case 'ADS_TOO_MANY_INSTANCES':
      console.log('Too many interstitial instances.');
      break;
    default:
      console.error('Interstitial ' + phase + ' error:', error.code, error.message);
      setTimeout(preloadInterstitial, 30000);
  }
}

// --- Game lifecycle integration ---

// Call during game initialization
function initializeGame() {
  FBInstant.startGameAsync().then(function () {
    // Start preloading the first interstitial immediately
    preloadInterstitial();
    // ... rest of initialization
  });
}

// Call when the player completes a level
function onLevelComplete(levelNumber) {
  showResults(levelNumber);

  // Show an interstitial at this natural break
  showInterstitialIfReady();

  // Continue to the next level after a short delay
  setTimeout(function () {
    startLevel(levelNumber + 1);
  }, 2000);
}

// Call on game over
function onGameOver() {
  showGameOverScreen();

  // Show an interstitial at this natural break
  showInterstitialIfReady();
}
```

## Frequency and Timing

Getting the frequency right is critical. Too many interstitials drive players away; too few leave revenue on the table.

### Platform Enforcement

The Instant Games platform enforces a **minimum 30-second interval** between interstitial ad impressions. If you attempt to show an interstitial less than 30 seconds after the previous one, the `showAsync` call will fail.

### Recommended Frequency

While the platform minimum is 30 seconds, most successful games use a longer interval:

| Game Type | Recommended Interval | Rationale |
|-----------|---------------------|-----------|
| Casual / Hyper-casual | 60-90 seconds | Short sessions mean fewer natural breaks, so each one should count. |
| Mid-core / Puzzle | 90-120 seconds | Longer levels mean more time between ads. Players are more invested and more sensitive to interruptions. |
| Story / RPG | 2-5 minutes | Deep engagement means interruptions are more disruptive. Show ads at chapter or scene boundaries. |

### Frequency Capping Strategy

Implement your own frequency cap on top of the platform minimum:

```javascript
var adShowCount = 0;
var MAX_ADS_PER_SESSION = 10; // Cap total interstitials per session

function shouldShowAd() {
  if (adShowCount >= MAX_ADS_PER_SESSION) {
    return false; // Player has seen enough ads this session
  }
  if (Date.now() - lastAdShownTime < MIN_AD_INTERVAL) {
    return false; // Too soon since last ad
  }
  return isInterstitialReady;
}
```

## Preloading Strategy

Effective preloading ensures ads are ready exactly when you need them. Here is the recommended strategy:

1. **Preload during initialization.** Start preloading your first interstitial as soon as the game starts.
2. **Preload the next ad immediately after showing one.** When an ad is shown, the player will be in a menu/transition screen for a few seconds — use that time to start preloading the next ad.
3. **Preload during gameplay.** While the player is actively playing, preload the next interstitial in the background. The preload happens asynchronously and does not affect game performance.
4. **Retry failed preloads.** If preloading fails (e.g., no fill), retry after 30-60 seconds. Do not retry immediately in a tight loop.

## Error Handling

| Error Code | Meaning | What To Do |
|------------|---------|------------|
| `ADS_NO_FILL` | No interstitial ad is available. | Retry after 30-60 seconds. This is normal and not a bug. |
| `ADS_FREQUENT_LOAD` | You are requesting ads too quickly. | Wait at least 30 seconds between load requests. |
| `ADS_TOO_MANY_INSTANCES` | Too many ad instances have been created. | Only maintain one interstitial instance at a time. Discard old instances before creating new ones. |
| `ADS_NOT_LOADED` | You called `showAsync` before the ad finished loading. | Check that `loadAsync` resolved successfully before calling `showAsync`. Use a flag like `isInterstitialReady`. |
| `INVALID_PARAM` | The placement ID is invalid. | Verify the placement ID in Monetization Manager. |
| `RATE_LIMITED` | Ads are being shown too frequently. | Increase the interval between ad impressions. |

## Best Practices

### Respect the Player's Time

- Always show interstitials at **natural breaks** — moments where the player is already expecting a pause.
- Never interrupt active gameplay, even for a brief moment.
- After showing an ad, give the player a clear and immediate return to the game. Do not stack multiple ads.

### Signal the Ad

- Consider showing a brief "Loading..." or transition screen before the interstitial. This manages expectations and prevents the jarring feeling of content suddenly disappearing.
- After the ad completes, return the player to exactly where they were before the ad appeared.

### Do Not Punish Players

- Never make the game harder or slower to force more ad opportunities.
- Do not create artificial waiting periods just to show ads.
- If a player's session is going well (long play time, high engagement), they are generating more ad opportunities naturally — do not undermine that positive experience.

### Track Performance

- Create separate placement IDs for different locations (between levels, game over, etc.) so you can compare eCPM and engagement across placements.
- Monitor your retention metrics alongside ad revenue. If retention drops after increasing ad frequency, dial it back.

### Combine with Rewarded Ads

- Interstitials and rewarded ads complement each other well. Show interstitials at mandatory break points and offer rewarded ads as an optional, player-initiated action at different moments.
- Do not show an interstitial and then immediately offer a rewarded ad — space them out.

## Next Steps

- **[Rewarded Ads](https://developers.facebook.com/documentation/games/monetize/in-app-ads/rewarded-ads)** — Implement player-opted ads that grant in-game rewards.
- **[Banner Ads](https://developers.facebook.com/documentation/games/monetize/in-app-ads/banner-ads)** — Add passive banner revenue to menus and non-gameplay screens.
- **[In-App Ads Overview](https://developers.facebook.com/documentation/games/monetize/in-app-ads/overview)** — Return to the ads overview for general guidance.
- **[Monetization Best Practices](https://developers.facebook.com/documentation/games/monetize/best-practices)** — Strategic advice for optimizing your ad monetization.