RetiPie

SDK Reference

The RetiPie creator SDK — ads, game lifecycle, analytics, and tips. Injected into every published game. No install required for vanilla JS.

The RetiPie SDK is injected into every game automatically. You call it from your game's JavaScript; the platform handles loading, displaying, consent, frequency limits, pause/resume, and revenue attribution.

Everything lives on a single namespace: window.retipie.

Quick start

// Grant an extra life after the player watches a rewarded ad
const result = await retipie.ads.showRewarded({ placement: 'continue' });
if (result.rewardGranted) {
  grantExtraLife();
}

// Submit the final score at the end of a run
retipie.analytics.submitScore(score);

// Pause your own game when the player opens a menu
retipie.game.pause();

That's the whole contract. Show an ad, submit a score, pause your game. Everything else — consent dialogs, frequency limits, payout attribution, automatic pause when the player swipes to a different card — the platform handles.

API surface

window.retipie = {
  ads: {
    showRewarded(opts?: { placement?: string }): Promise<RewardResult>,
    showInterstitial(opts?: { placement?: string }): Promise<ShowResult>,
    onAdReady(handler: (available: boolean) => void): () => void,
    onConsentChanged(handler: (hasConsent: boolean) => void): () => void,
    isAvailable(): boolean,
    hasConsent(): boolean,
  },
  game: {
    pause(): void,
    resume(): void,
    onPause(handler: () => void): () => void,
    onResume(handler: () => void): () => void,
  },
  analytics: {
    submitScore(score: number): void,
    trackEvent(name: string, data?: Record<string, string | number | boolean | null>): void,
    loadingProgress(percent: number): void,
    gameplayStart(): void,
    gameplayStop(): void,
  },
  tips: {
    prompt(opts?: { message?: string; suggestedAmountCents?: number }): Promise<TipResult>, // Phase 2
  },
  version: string,
};

Ads

Rewarded and interstitial only. Ads are rendered natively outside your game WebView — you never have to paint pixels or reserve screen space. The platform freezes your game automatically while an ad is on screen and resumes it when dismissed.

Banner ads are not supported and will not be added. The platform's rule is that game surface belongs entirely to the creator.

ads.showRewarded(opts)

Shows a rewarded video. The returned promise resolves when the ad is dismissed.

type RewardResult = {
  completed: boolean;           // true if the player watched to the end
  rewardGranted: boolean;       // true if you should grant the reward
  errorCode: AdErrorCode | null;
};

Only grant the reward when rewardGranted is true. Any other outcome (skipped, no ad available, consent missing, etc.) means no reward.

placement is a free-text tag for your own analytics ("continue", "extra_life", "daily_bonus"). The platform stores it with the impression for creator reporting.

ads.showInterstitial(opts)

Shows a full-screen interstitial at a natural break — typically between levels.

type ShowResult = {
  completed: boolean;
  errorCode: AdErrorCode | null;
};

No reward. Pure revenue. Safe to call aggressively — the platform paces interstitials for you and returns rate_limited instead of flooding the player.

ads.onAdReady(handler)

Keep a "watch for reward" button in sync with actual ad inventory.

const unsubscribe = retipie.ads.onAdReady((ready) => {
  rewardButton.disabled = !ready;
});
// call unsubscribe() when the button leaves the UI

Error codes

When completed is false, errorCode tells you why:

CodeWhat it meansWhat to do
rate_limitedPlatform frequency limit reachedDon't retry immediately. Hide the button or wait for a natural moment.
consent_missingPlayer hasn't granted ad consent yetCheck retipie.ads.hasConsent() before showing the button.
capability_disabledThis ad type is not enabled for your gameEnable it in your game's Monetization settings.
self_playThe creator is playing their own gameImpressions are blocked for self-play; this is a fraud safeguard, not a bug.
load_timeoutNo ad loaded in timeRetry later with backoff.
show_timeoutAd didn't close cleanlyRare. Treat as dismissed.
load_failedNetwork or inventory errorRetry with backoff.
dismissedPlayer closed the ad before rewardDo not grant the reward.
not_availableThe API returned no adContinue without the reward.

Game lifecycle

Your game is automatically frozen during platform events — when the player swipes to another game, when the app goes to the background, when an ad is on screen. Timers, requestAnimationFrame, and AudioContext are all suspended for you. You don't subscribe to those events; they just work.

The retipie.game namespace is for your own pause/resume — pause menus, cutscenes, settings modals.

game.pause() / game.resume()

pauseButton.addEventListener('click', () => {
  retipie.game.pause();
  showPauseMenu();
});

Calling pause() freezes the same primitives the platform freezes. Calling resume() unfreezes them. Idempotent — calling pause() twice is safe.

game.onPause(handler) / game.onResume(handler)

Subscribe to your own pause/resume transitions — useful for syncing UI to engine state.

retipie.game.onPause(() => muteMusic());
retipie.game.onResume(() => unmuteMusic());

Platform-initiated pauses (swipe, backgrounding) do not fire these handlers. Your game is frozen, but your code isn't notified — you don't need to be, because timers and audio are already suspended. If you need awareness of platform visibility, use the standard document.visibilityState.

Analytics

All analytics calls are fire-and-forget. No acknowledgement, no response.

analytics.submitScore(score)

Report the player's final score at the end of a run. Used for leaderboards and anti-fraud qualification.

retipie.analytics.submitScore(finalScore);

analytics.trackEvent(name, data?)

Record a creator-defined event. Use this for retention funnels, feature adoption, A/B variants.

retipie.analytics.trackEvent('level_complete', { level: 4, hintsUsed: 2 });

Payload values must be primitives (string, number, boolean, or null). Nested objects are not supported.

analytics.loadingProgress(percent)

Report asset loading progress (0–100). The platform shows a loading indicator while progress is less than 100 and your game hasn't yet called gameplayStart().

preloadAssets((loaded, total) => {
  retipie.analytics.loadingProgress((loaded / total) * 100);
});

analytics.gameplayStart() / analytics.gameplayStop()

Mark the beginning and end of active gameplay. Used for session duration and qualified-play accounting (impacts creator payout).

function startRun() {
  retipie.analytics.gameplayStart();
  // … game loop runs …
}
function endRun() {
  retipie.analytics.gameplayStop();
  retipie.analytics.submitScore(finalScore);
}

Tips (Phase 2)

retipie.tips.prompt({ message?: string; suggestedAmountCents?: number }): Promise<TipResult>

Opens a platform-native tip flow. Currently returns { tipped: false, errorCode: 'not_available' } until payment integration ships. The API is stable — you can wire your UI to it now and it will start working when the integration lands.

Using the SDK from your game

Vanilla JS / Phaser / Construct runtime

Nothing to install. Just call window.retipie.* once your page loads.

if (window.retipie) {
  await window.retipie.ads.showRewarded();
}

TypeScript

Install the npm package to get full typings on window.retipie:

npm install @retipie/sdk
import '@retipie/sdk'; // augments the Window interface

const result = await window.retipie.ads.showRewarded({ placement: 'revive' });
if (result.rewardGranted) respawn();

You don't need to call any init — the zone server installs the runtime for you. The npm package is types-only at consumer time.

Godot 4

Use the @retipie/godot plugin from the Godot Asset Library or drop the addons/retipie/ folder into your project.

func _on_revive_button_pressed():
    var result = await RetiPie.ads.show_rewarded({ "placement": "revive" })
    if result.reward_granted:
        respawn()

See the Godot package README for installation and full API reference.

Unity WebGL

Import the RetiPie.unitypackage from the Unity Asset Store or Git URL.

using RetiPie;

public async void OnReviveClicked() {
    var result = await RetiPieAds.ShowRewarded("revive");
    if (result.RewardGranted) Respawn();
}

See the Unity package README for installation and C# bindings.

Construct 3 (Phase 2)

A dedicated .c3addon is planned. Until then, use the JavaScript action with window.retipie.*.

Capability gates

Each ad type is gated by a capability flag on your game. Enable the ones you actually call:

  • ads.rewarded gates showRewarded()
  • ads.interstitial gates showInterstitial()

Toggle these on your game's detail page in the creator dashboard. Calling a gated method without enabling its capability returns { errorCode: 'capability_disabled' }.

Migration from other platforms

Their APIRetiPie equivalent
PokiSDK.rewardedBreak()retipie.ads.showRewarded()
PokiSDK.commercialBreak()retipie.ads.showInterstitial()
sdk.showAd('rewarded', cb)await retipie.ads.showRewarded()
Callback-style (err, reward) => …await retipie.ads.showRewarded() and check result.rewardGranted
sdk.gameplayStart()retipie.analytics.gameplayStart()
sdk.submitScore(n)retipie.analytics.submitScore(n)

All RetiPie calls are Promise-based where they return a value, and synchronous for fire-and-forget analytics. Replace the SDK init and the call sites — nothing else in your game needs to change.

On this page