Skip to content

In-game ads integration ​

Last updated: 2026-08-11

Integrate Banner, interstitial, and rewarded ads through the PlayNova host bridge. Your game runs in an iframe and talks to the host with postMessage — do not embed third-party ad SDKs inside the package.

How monetization works ​

PlayNova fills ads on the host side and shares revenue with certified creators (default 70% creator share). Games only request show/load; the host handles inventory, frequency caps, and impression/click reporting.

Envelope for every message:

json
{ "source": "...", "type": "...", "payload": { } }
  • Games must set source to playnova-game
  • The host replies with source playnova-host

Ad formats:

  • Rewarded — player opt-in (revive, double reward, free item). Grant rewards only after ads.rewarded_completed.
  • Interstitial — natural breaks (level complete / game over). Never mid-input.
  • Banner — host-owned strip; game only requests show/hide.

Always pass a stable placement string for analytics and caps. Prefer the platform names below:

PlacementUse case
reviveContinue after fail
double_rewardEnd-of-level bonus
free_item / unlockConsumable or content unlock
level_complete / level_start / game_over / pauseInterstitial moments
banner_bottom / banner_topBanner slots

Integration flow ​

  1. On a natural break, call ads.load_* with placement (and optional requestId).
  2. Wait for ads.*_loaded (or handle *_failed and continue without ads).
  3. Call ads.show_* with the same requestId / placement.
  4. For rewarded, mutate game state only on ads.rewarded_completed. On dismissed/failed, do not grant the reward.

Bridge message types ​

Canonical type strings are defined in playnova-web (ads-bridge). Keep your game package aligned with these exact values.

Game → host ​

typePurpose
ads.load_rewardedPreload rewarded inventory
ads.show_rewardedShow rewarded (grant only after completed)
ads.load_interstitialPreload interstitial
ads.show_interstitialShow interstitial at a break
ads.show_bannerRequest host banner visible
ads.hide_bannerHide host banner
ads.preloadPreload multiple formats
ads.get_banner_heightQuery banner height for layout

Host → game ​

typePurpose
ads.rewarded_loadedRewarded ready to show
ads.rewarded_failedRewarded load/show failed
ads.rewarded_completedUser finished rewarded — safe to grant
ads.rewarded_dismissedUser closed rewarded early — do not grant
ads.interstitial_loadedInterstitial ready
ads.interstitial_failedInterstitial failed
ads.interstitial_closedInterstitial closed
ads.banner_shownBanner is visible
ads.banner_hiddenBanner hidden
ads.banner_failedBanner failed

Copy-paste helper ​

Drop this into your index.html (or module). Replace reward grant with your own game logic.

js
function pnAds(type, payload) {
  parent.postMessage({ source: 'playnova-game', type, payload }, '*');
}
function onPnHost(handler) {
  window.addEventListener('message', (e) => {
    const d = e.data;
    if (!d || d.source !== 'playnova-host') return;
    handler(d);
  });
}
// Example: revive flow
pnAds('ads.load_rewarded', { placement: 'revive' });
onPnHost((msg) => {
  if (msg.type === 'ads.rewarded_loaded') {
    pnAds('ads.show_rewarded', {
      requestId: msg.payload && msg.payload.requestId,
      placement: 'revive',
      reward: { type: 'life', amount: 1 },
    });
  }
  if (msg.type === 'ads.rewarded_completed') {
    // grant reward ONLY here
  }
});

Production rules ​

  • Do not auto-click, force-loop, or obscure Close / Skip controls.
  • Do not grant rewards unless you received ads.rewarded_completed for that requestId.
  • Respect host failures: if inventory is empty, continue the game gracefully.
  • Prefer load ahead of show so players wait less at the trigger moment.
  • Keep packages free of third-party ad SDKs, trackers, or pop-under scripts.
  • Interstitial frequency is enforced by the host; spam show calls may be ignored.

FAQ ​

Can I use AdMob / Unity Ads inside the zip? ​

No. PlayNova aggregates demand on the host. Embedding other SDKs will fail review and breaks iframe sandbox assumptions.

What if the host does not answer? ​

Treat silence or *_failed as no-fill. Continue gameplay without blocking the player on an endless spinner.

Where do I see revenue? ​

After ads are live in production, impressions and revenue roll into creator analytics. Settlement follows the creator program terms.


Host bridge is live on the play page. Message types above are the production contract — implement against them now.

PlayNova creator documentation