RetiPie
SDK

Game Lifecycle

Use retipie.game to configure game capabilities, pause and resume play from your own UI, and understand how RetiPie freezes your game.

RetiPie runs games inside a sandboxed runtime — the same one used by the creator preview and by players. The lifecycle API lets your game coordinate with that host instead of guessing whether the player is actively playing.

Configure capabilities

Call retipie.game.configure() once when your game starts. Today the only capability is leaderboard support.

retipie.game.configure({
  leaderboards: {
    default: { order: 'desc', unit: 'points', precision: 0 },
  },
});

The analyzer can detect this declaration during upload processing and enable player-facing leaderboard UI for the current release. Leaderboards have a single fixed shape in V1 (higher is better, whole points), so the platform ignores any other values you pass.

How the platform pauses your game

When the player swipes to another game, puts the app in the background, or the platform shows something over your game, RetiPie freezes it for you. While frozen:

  • requestAnimationFrame callbacks, setTimeout and setInterval stop running. setTimeout keeps its remaining time and continues when the game resumes; setInterval restarts its full delay.
  • CSS animations (animation-play-state) are paused and every Web Audio AudioContext is suspended. HTML <audio> and <video> elements, CSS transitions, and clocks such as Date.now() and performance.now() are not covered, so pause media elements yourself if you use them.
  • document.hidden is true, document.visibilityState is 'hidden', and a visibilitychange event fires. It fires again when play resumes.

You don't need to write any code for this. A game also starts frozen: nothing in the game loop runs until the platform signals that play can begin.

onPause and onResume do not fire for platform pauses. This is deliberate: the platform freeze is transparent, so your game never has to run extra code while it is being hidden. If you need to react to a platform pause anyway — for example to save state — listen for visibilitychange and check document.hidden.

Pause and resume from your own UI

Use pause() and resume() when your own game UI changes play state, such as a pause menu or a cutscene.

retipie.game.pause();

// Later, when the player closes the pause menu:
retipie.game.resume();

pause() applies the same freeze as a platform pause, so animation frames, timers, and audio stop until you call resume(). Drive your pause menu from input events, not from requestAnimationFrame or timers. If the platform pauses the game while your own pause is active, the game stays frozen after the platform resumes until you call resume().

Listen for your own pauses

onPause and onResume are called when your game calls retipie.game.pause() and retipie.game.resume(), so independent parts of your code (audio, simulation, UI) can react to the same pause without sharing state.

const removePauseHandler = retipie.game.onPause(() => {
  showPauseMenu();
});

const removeResumeHandler = retipie.game.onResume(() => {
  hidePauseMenu();
});

Each call returns an unsubscribe function; call it when the handler is no longer needed. A handler that throws is ignored and does not stop other handlers.

Engine notes

Godot Web exports should rely on the RetiPie Godot addon for window.retipie access: RetiPie.game.pause() and resume(), with the paused and resumed signals firing for those calls only. Unity WebGL projects use the Unity package bindings: RetiPieGame.Pause(), Resume(), and Subscribe(onPause, onResume). The browser contract is the same in each wrapper.

On this page