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"

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

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"

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

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.