Earn13 min read

Ads and earnings

Where interstitials, rewarded ads and banners belong, the limits the app enforces, how your earnings are worked out (with a worked example), and what counts as fraud.

On this page7 sections

Twiddle Play is free for players. If you turn ads on for your game, the app shows Twiddle Play's ads at the moments your game asks for, and you earn a share of the money those ads make.

  • Ads only run in the Android app. Never on the website, and never your own ads or another network's.
  • Your game decides when to ask. The app decides whether an ad actually shows.
  • Ads on or off is your choice, per game, and you can switch it at any time in your game's Settings. With ads off, there are no ads and no earnings.

Three kinds of ads#

Interstitial Rewarded Banner
What it is A full-screen ad between parts of your game. A full-screen ad the player chooses to watch for a reward. A small strip-shaped ad below (or above) your game, on menus and between rounds.
Who starts it Your game, at a natural break. The player, by tapping your button. Your game, when a menu or results screen opens.
SDK call showInterstitial() → { shown } showRewarded() → { rewarded } showBanner() → { shown }, then hideBanner()
Limits Yes, strict (see below). Only one ad at a time. No timing limits, but never during play.

Every kind is optional. Use one, two or all three.

Where interstitials go#

An interstitial belongs at a natural break: a moment when the player has just finished something and is about to start the next thing.

Good places:

  • After the player taps Next level on a level-clear screen, before the next level starts.
  • After Try again on a game-over screen, before the new round starts.
  • When going back to the main menu after a run.

Never:

  • During play, or on a timer ("every 2 minutes").
  • When the game starts, before the player has played.
  • Right after the player taps something that means something else, like Pause or Settings. They'll tap the ad by accident.
  • In the middle of a level, or while a timer is running.
game.jsJavaScript
// Good: the player finished, saw their score, and tapped Next.
nextBtn.addEventListener('click', async function () {
  nextBtn.disabled = true;
  await TwiddlePlay.showInterstitial();   // shown or not, carry on
  startLevel(level + 1);
  nextBtn.disabled = false;
});

Call it at every natural break. You don't need to count or time anything: the app applies the limits and most calls simply return { shown: false }. That's normal.

Rewarded ads#

A rewarded ad is a deal: "watch an ad, get something." Players like these when the deal is clear and fair.

The rules:

  • Only on a tap. Show a button; call showRewarded() when the player taps it.
  • Say what they get on the button: "+10 seconds", "Double coins", "Continue".
  • Give exactly that, and only when the result is { rewarded: true }.
  • Hide the button when hasRewarded() is false.
  • Make it optional. The game must still be fun and fair without it.

Patterns that work:

Pattern Button Where
Continue "+10 seconds" or "Continue" Game-over or time-up screen. Once per round.
Double up "Double coins" Level-clear screen, next to Next.
Helping hand "Get a hint" A puzzle where the player is stuck.
Bonus "Free spin" A menu screen, a few times a day.
game.jsJavaScript
async function showTimeUp() {
  timeUpPanel.hidden = false;
  plusTenBtn.hidden = usedContinue || !(await TwiddlePlay.hasRewarded());
}

plusTenBtn.addEventListener('click', async function () {
  plusTenBtn.disabled = true;
  const { rewarded } = await TwiddlePlay.showRewarded();
  if (rewarded) {
    usedContinue = true;
    timeLeft += 10;
    timeUpPanel.hidden = true;
    resumeRound();
  } else {
    showToast('No ad right now. Try again soon!');
  }
  plusTenBtn.disabled = false;
});

Banners#

A banner is a small ad shaped like a strip: as wide as the screen and about 50 to 90 pixels tall. It isn't full-screen and the player doesn't have to do anything. It stays on screen until your game takes it away, and while it's up, Google swaps in a fresh ad every 30 to 120 seconds or so.

You turn it on and off yourself: showBanner() when a quiet screen opens, hideBanner() when play starts.

In the app, a banner never covers your game. It sits next to it: below your game by default, or above it if you ask for the top. To make room, your game's viewport (the part of the screen your page can draw in) gets shorter by the banner's height. The app picks that height to suit the phone's width, which is why it varies from about 50 to 90 pixels.

When the viewport changes size, your page gets a normal resize event, the same one it gets when a phone rotates. When you call hideBanner(), the viewport grows back to full size and your page gets another resize.

So your game must re-fit itself on every resize: read window.innerWidth and window.innerHeight (or the size of the element your game lives in), and size your canvas from them. If your game reads the screen size only once at startup, its bottom edge gets cut off when the banner appears.

Where banners go#

A banner belongs on a screen where the player is reading or choosing, not playing.

Good places:

  • The title screen or main menu.
  • A level select screen.
  • Between rounds: the level-clear screen, with its score and Next button.
  • The game-over or results screen.

Never:

  • During play, even in a corner. Hide it before play starts.
  • Next to your game's controls or buttons. A finger aimed at your button lands on the ad instead. Google calls those accidental clicks: they don't pay, they break Google AdMob's rules (AdMob is the Google service the app gets its ads from), and too many of them get your game flagged for click fraud.
  • Showing and hiding it every second or so, for example on each page of a menu the player flicks through. Show it once when the screen opens and leave it there until play starts.

Show the banner when a menu or results screen opens, hide it when play starts, and re-fit your game on resize:

game.jsJavaScript
// Fit the canvas to the window now, and every time the window changes size.
// A banner appearing or going away changes it too.
function fitCanvas() {
  const dpr = Math.min(window.devicePixelRatio || 1, 2);
  W = window.innerWidth;
  H = window.innerHeight;
  canvas.style.width = W + 'px';
  canvas.style.height = H + 'px';
  canvas.width = Math.round(W * dpr);
  canvas.height = Math.round(H * dpr);
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
window.addEventListener('resize', fitCanvas);
fitCanvas();

function showMenu() {
  state = 'menu';
  menuPanel.hidden = false;
  TwiddlePlay.showBanner();     // bottom by default; shown or not, the menu works the same
}

function roundOver() {
  state = 'results';
  TwiddlePlay.gameplayStop();
  resultsPanel.hidden = false;
  TwiddlePlay.showBanner();
}

// Every button that starts play (Play, Next, Try again) calls this.
function startRound() {
  TwiddlePlay.hideBanner();     // no banner during play
  menuPanel.hidden = true;
  resultsPanel.hidden = true;
  state = 'playing';
  TwiddlePlay.gameplayStart();
}

You don't need to await either call. Nothing in your game should wait for a banner. Calling showBanner() again while one is showing keeps the one banner, so it's fine to call it every time a menu opens. hideBanner() with no banner up does nothing.

Want it at the top instead? Call TwiddlePlay.showBanner({ position: 'top' }). Bottom suits most games; top is for games whose menu buttons sit low on the screen. Any other value means bottom.

  • Ads off: showBanner() returns { shown: false } and nothing appears, so your layout never changes.
  • No fill: sometimes Google has no banner to give (people in ads call this "no fill"). Then showBanner() returns { shown: false } too. That's normal; try again the next time a menu opens.
  • No limits, no pausing: banners have no timing limits, they don't count toward the interstitial limits, and they don't pause or mute your game.
  • Earnings: banner views earn you the same share as interstitials and rewarded ads, and go through the same daily checks. One banner view usually pays much less than a full-screen ad, so banners add a little on top rather than replacing an interstitial.
  • Testing: in the portal preview and on your own computer, a test bar labelled "Test banner — real ads only in the Twiddle Play app" stands in for the banner. In the preview, the game area shrinks for it like in the app. On your own computer, the bar is fixed to the bottom (or top) of the page and covers that strip of your game, because a web page can't make its own window smaller. Real banners only show in the app.

If a banner doesn't show, see Troubleshooting.

The limits the app enforces#

The app, not your game, decides whether an ad shows. These are the rules:

Interstitials

  • None in the first 60 seconds of a play session.
  • At least 90 seconds between two interstitials.
  • At most one per 3 minutes of play overall. The 2nd needs 3 minutes of play, the 3rd needs 6 minutes, and so on.

Rewarded ads

  • Only one ad on screen at a time. No other limit.

Banners

  • No timing limits. Where they go is up to you: menus and between rounds only (see Banners).

Ads off

  • showInterstitial() returns { shown: false }, showRewarded() returns { rewarded: false }, hasRewarded() returns false and showBanner() returns { shown: false }, every time.

These times count play time only. The clock stops while the app is in the background, while an ad is on screen and while the "Leave game?" dialog is open.

Here's a 10-minute session where the game calls showInterstitial() after every level:

Play time Result Why
0:45 { shown: false } Still in the first 60 s.
1:30 Ad shown (1st) Past 60 s, and it's the first one.
2:20 { shown: false } Only 50 s since the last ad. It needs 90 s.
3:10 Ad shown (2nd) 100 s since the last ad, and the 2nd ad needs 3:00 of play.
4:40 { shown: false } The gap is fine (90 s), but the 3rd ad needs 6:00 of play.
6:05 Ad shown (3rd) Past 6:00, and 175 s since the last ad.
7:50 { shown: false } The 4th ad needs 9:00 of play.
9:10 Ad shown (4th) Past 9:00, and 185 s since the last ad.

So a player who plays for 10 minutes sees at most about 4 interstitials, however often your game asks.

Why showInterstitial() returned { shown: false }#

Any of these:

  • Your game's ads are off.
  • It's too early in the session, too soon after the last ad, or over the 3-minute budget.
  • Another ad is already on screen.
  • No ad was loaded (ads come from Google AdMob, and there isn't always one ready).
  • The app was in the background or the "Leave game?" dialog was open.
  • The SDK got no answer within 60 seconds.

None of these are errors. Carry on with your game.

showRewarded() returns { rewarded: false } for the same reasons (except the interstitial timing), and also when the player closes the ad before earning the reward.

How you earn#

Your share#

For each game with ads on, you earn a share of the valid ad revenue that game makes. The share is set by Twiddle Play: the default is 50%.

Current settings, straight from the server

Your share of a game's valid ad revenue50%
Hold after the month ends30 days
Payout minimum₹500.00
CurrencyINR

These values may change. Your Earnings page always shows the current ones, and each month's row records the share used for it.

From ad views to money in your account#

  1. Ad views Players watch ads in your game. The app reports each view and the money it earned.
  2. Daily check Every day, invalid views are filtered out (see what counts as fraud).
  3. Estimate Your month's valid revenue × your share. Shown as estimated, updated daily.
  4. Reconcile After the month ends, Twiddle Play compares with what Google actually paid and adjusts every row by the same factor. The row becomes final.
  5. Hold Final earnings wait 30 days after the month ends.
  6. Payout Once your matured total reaches ₹500, you're paid by UPI or bank transfer and the row becomes paid.

A worked example#

Your game "Firefly Jar" has ads on. Here's March, with the default settings (50% share, 30 hold days, ₹500 minimum, INR).

1. Ad views in March. After the daily checks, the valid ad views are:

Ad type Valid views Average per view Revenue
Interstitial 3,000 ₹0.20 ₹600
Rewarded 1,000 ₹0.60 ₹600
Total ₹1,200

(Real amounts per view vary a lot by country, season and ad. These numbers are only for the example.)

2. The estimate. During March your Earnings page shows ₹1,200 × 50% = ₹600, estimated. It changes every day as new views come in.

3. Reconcile. In early April, Twiddle Play enters what Google actually paid for March across all games and compares it with what the phones reported. Say phones reported ₹80,000 of valid revenue, and Google paid ₹72,000. The factor is 72,000 ÷ 80,000 = 0.9. Every game's March row gets the same factor:

₹1,200 × 0.9 × 50% = ₹540, final.

(The factor can also be above 1 when Google pays more than reported.)

4. Hold. March's earnings become payable on 1 April + 30 days = 1 May.

5. Minimum. On 1 May your matured final total is ₹540. That's at least ₹500, so it's payable. Twiddle Play pays it to the UPI ID or bank account in the Payout details section of your Earnings page, then marks it paid with a payment reference.

If it had been less: say March was only ₹300 final. On 1 May, ₹300 is below ₹500, so it waits. April's earnings (say ₹260 final) mature on 31 May (1 May + 30 days); your matured total is then ₹560, and both months are paid together.

What counts as fraud#

Ad networks pay for real people seeing ads. Anything else is fraud, and it costs everyone: Google can stop paying the whole platform. So Twiddle Play checks every ad event, every day.

Ad views that simply don't count#

These views are quietly dropped from your revenue. You don't need to do anything; just know they're not counted.

Rule In plain words
Daily cap per device One phone counts for at most 15 interstitials, 30 rewarded ads and 300 banner views a day in your game. Each kind has its own count. Views past that don't count.
Interstitial gap An interstitial less than 30 s after the previous one on the same phone doesn't count. (The app already keeps them 90 s apart.)
No install Ad views only count from phones that installed your game through the app.
Revenue must match a view Revenue only counts if there's a matching ad view of the same kind (banner money needs a banner view) in the same session within 10 seconds. Each view pays once.
Too much per view Revenue above ₹2 for a single ad view isn't counted.
Ads off Ad events while your ads are off don't count.
Suspended or banned Nothing counts from a suspended game or a banned builder.

What gets your game flagged#

These patterns raise a flag for the Twiddle Play team to look at. They look at each day's numbers per game.

Flag Fires when (defaults) What it usually means
Single device One phone made over 30% of the game's ad views that day (with at least 20 views). Someone farming ads on their own phone.
Too few players 50+ ad views that day came from fewer than 5 different phones. Ads watched by a handful of people, not real players.
Click rate More than 10% of ad views were clicked (with at least 50 views). Click spam, or a layout that tricks players into tapping ads.
Rapid-fire ads Two interstitials closer together than the app allows. A tampered app. Real phones can't do this.
New-device spike At least 80% of the day's ad-watching phones were brand new, with 50+ phones. Bought or fake installs.
Revenue outlier The game earned over 5× the platform's typical revenue per ad view that day, comparing each kind of ad with its own kind (with 20+ valid views). Forged revenue reports.

The numbers above are the defaults and may change.

What happens after a flag#

A flag is a question, not a verdict. A person looks at it. Then they either:

  • dismiss it (for example, a weekend tournament with real players),
  • void that month's earnings for the game (the row is set to voided and is never paid),
  • suspend the game (it leaves the store and players' phones), or
  • ban the builder for repeated or serious fraud (all their games are suspended, and payouts stop).

How to stay safe#

  • Don't play your own game to watch ads, and don't ask friends or family to.
  • Don't buy installs or "traffic".
  • Don't put ads where players tap them by accident.
  • Don't change or wrap the app.
  • Testing is fine: the preview and your own computer show test ads, which never count.