Skip to content

Advertising

Advertising is how most games on Y8 earn. The SDK shows two kinds of break: interstitials, which you request at natural pauses in play, and rewarded ads, which the player chooses to watch in exchange for something.


Pause in the callback, not before the call

This is the one thing to get right, because getting it wrong strands players in a paused game.

An ad break does not always show an ad. It may be skipped because none was available, or because the previous ad was too recent. When that happens the SDK does not fire the "ad started" and "ad finished" callbacks at all — there was no ad to start or finish.

So pause your game inside the before-ad callback and resume it inside the after-ad callback. If you instead pause before requesting the break, a skipped break leaves the game paused with nothing to un-pause it.

Tip

Mute your audio in the same place you pause, and restore it in the same place you resume.


Showing an interstitial

y8Sdk.showAd({
    type: "next",
    name: "level-complete",

    beforeAd: () => {
        pauseGame();
    },

    afterAd: () => {
        resumeGame();
    },

    adBreakDone: (info) => {
        console.log(info.breakStatus);
    },
}).catch((error) => {
    console.error(error);
});

Every field is optional. type defaults to "start" and name to "start-game".

name is a label for your own reporting — it appears in the Y8 dashboard so you can tell your level-complete breaks from your menu breaks. Keep it stable.

JsResponse<AdBreakInfo> response =
    await Y8.Instance.ShowAdAsync(AdType.next, "level-complete");

if (response.IsSuccess)
{
    Debug.Log(response.Data.Status);
}

type defaults to AdType.start; name is optional and appears in the Y8 dashboard for your own reporting.

Pause and resume by subscribing to the SDK's events rather than doing it around the call — they fire only when an ad actually appears, which is the behaviour described above:

private void OnEnable()
{
    Y8.Instance.OnAdPauseGame  += PauseGame;
    Y8.Instance.OnAdResumeGame += ResumeGame;
}

private void OnDisable()
{
    Y8.Instance.OnAdPauseGame  -= PauseGame;
    Y8.Instance.OnAdResumeGame -= ResumeGame;
}

private void PauseGame()  => Time.timeScale = 0f;
private void ResumeGame() => Time.timeScale = 1f;

Subscribe once, at startup — not per ad request.

Call showAd
    type: "next"
    name: "level-complete"

Calling showAd from an event sheet

The integration pauses and resumes the game around the break for you.

Pause and resume around the ad break

Y8.showAd(pauseGame, resumeGame);
Parameter Type Description
pauseGame Void->Void Called before the ad is displayed. Pause and mute here.
resumeGame Void->Void Called after the ad finishes or closes. Resume here.

Both callbacks are required, and they are the pause/resume pair described above — the wrapper does not call them when a break is skipped.


Placements

The placement describes when the break happens. Pick the one that matches what the player is actually doing; the ad system uses it to decide what to serve.

Placement When to use
start The game has loaded, before play begins.
pause The player paused the game.
next Between levels, rounds or stages.
browse The player is in menus, not playing.
reward The player chose to watch an ad for a reward.

Never request preroll

preroll is a placement the Y8 platform runs itself, before your game's UI appears. Requesting it from the SDK is not supported.

The method is showAd, not adBreak

adBreak is the name Google's own ad API uses, and it is easy to reach for by mistake — but it does not exist on the Y8 SDK, and calling it fails silently with no ad and no error. If ads are not appearing, check the method name first.


Rewarded ads

A rewarded ad is player-initiated: they press a button offering something in exchange for watching. Grant the reward only when the ad was actually watched through to the end.

y8Sdk.showAd({
    type: "reward",
    name: "extra-life",

    beforeAd: () => pauseGame(),
    afterAd: () => resumeGame(),

    beforeReward: (showAdFn) => showAdFn(),

    adViewed: () => {
        grantExtraLife();
    },

    adDismissed: () => {
        // Watched only part of it — no reward.
    },

    adBreakDone: (info) => {
        console.log(info.breakStatus);
    },
}).catch((error) => {
    console.error(error);
});

beforeReward must call the function it is given

beforeReward runs when a rewarded ad is ready and receives a function that displays it. Nothing is shown unless you call that function.

It is the hook for asking "Watch an ad for an extra life?" — show your own prompt, then call showAdFn() if the player accepts. If you do not need to ask, pass it straight through as above.

It is not where you grant the reward. Grant in adViewed.

Callback When it runs
beforeReward(showAdFn) A rewarded ad is available. Call showAdFn() to play it.
adViewed The player watched it through. Grant the reward here.
adDismissed The player closed it early. Grant nothing.

beforeReward, adViewed and adDismissed are ignored for every placement other than reward.

JsResponse<AdBreakInfo> response =
    await Y8.Instance.ShowAdAsync(AdType.reward, "extra-life");

if (!response.IsSuccess)
{
    return;
}

switch (response.Data.Status)
{
    case AdBreakStatus.Viewed:
        GrantExtraLife();
        break;

    case AdBreakStatus.Dismissed:
        // Closed early — grant nothing.
        break;

    case AdBreakStatus.NoFill:
        // Nothing available right now; tell the player to try later.
        break;

    case AdBreakStatus.Error:
        break;
}

There is no separate "offer the ad" hook — show your own prompt before calling ShowAdAsync, and call it only if the player accepts.

RewardAd → On clicked
         → Call showRewardAds
            functionName: "addCoinsReward"

Requesting a rewarded ad Rewarded ad configuration

The named function runs only when the ad was watched through, so grant the reward there and nowhere else:

On function addCoinsReward
    → Grant the player their reward

Granting the reward

Y8.showRewardAd(
    pauseGame,
    resumeGame,
    function():Void {
        coins += 100;
        trace("Reward granted");
    },
    function():Void {
        trace("No rewarded ad available");
    }
);
Parameter Type When it runs
pauseGame Void->Void Before the ad is displayed.
resumeGame Void->Void After it finishes or closes.
onReward Void->Void The ad was watched through. Grant the reward here.
onUnavailable Void->Void No rewarded ad was available.

onReward does not run when the player closes the ad early, so granting there is safe.


Knowing what happened

The ad-break-done callback runs for every break, whether or not an ad was shown, and describes the outcome.

adBreakDone: (info) => {
    // {
    //   breakType:   "next",            the type you asked for
    //   breakName:   "level-complete",  the name you asked for
    //   breakFormat: "interstitial",    or "reward"
    //   breakStatus: "viewed",          what actually happened
    // }
}
breakStatus Meaning
viewed Shown and watched.
dismissed Shown, closed early.
noAdPreloaded Nothing available to show.
frequencyCapped Skipped — the previous ad was too recent.
notReady The ad system had not finished starting up.
timeout The request took too long.
error The request failed.
ignored The placement was declined by the ad system.
other Anything else.

Only viewed and dismissed mean an ad appeared. Treat every other value the same way — carry on with the game.

JsResponse<AdBreakInfo> response = await Y8.Instance.ShowAdAsync(AdType.next);
AdBreakStatus status = response.Data.Status;
AdBreakStatus Meaning
Viewed Shown and watched.
Dismissed Shown, closed early.
NoFill No ad appeared.
Error The request failed.

NoFill is deliberately broad: it covers nothing being available, the break being skipped by frequency capping, and other non-display outcomes alike. All of them mean the same thing for your game — no ad was shown, carry on.

The integration reports the outcome through the callbacks described above: the reward function runs only on a completed rewarded ad, and play resumes automatically either way.

The wrapper reports the outcome through the callbacks described above: onReward for a completed rewarded ad, onUnavailable when none was available, and resumeGame once the break is over either way.


Frequency capping

Interstitials are paced. By default Y8 allows one roughly every 180 seconds, configurable per game. Rewarded ads are never capped, though watching one does restart the interval for interstitials.

Call the SDK at every natural break anyway. You do not need to do the counting — when a request lands inside the interval, the SDK skips it and reports the outcome as capped without showing anything.

A capped break behaves exactly like one where no ad was available: the before-ad and after-ad callbacks do not run, so a game that pauses inside them is never paused in the first place. Handle it the same way you handle an empty break — which, if you followed the advice at the top of this page, means doing nothing at all.


Testing

While your game is in review, the platform serves Google's test creatives automatically. There is nothing to switch on, and no configuration to remember to remove — real ads begin serving once the game is approved and released.

Before submitting, check that:

  • Gameplay pauses and audio mutes when an ad appears.
  • Gameplay resumes afterwards.
  • A break that shows no ad leaves the game running normally. Ads are capped after the first one, so requesting two breaks in quick succession is an easy way to see this path.
  • Rewards are granted only after an ad is watched through, never when it is closed early.