---
name: ferret-platform-display
description: Use for how a Ferret game talks to OS Beroun or the browser: FerretPlatform (saved state, suspend, exit, screen, log), device class, Display, field of view, render scale and quality tiers. Read before saving state or laying out for phone, console and desktop.
---

# Platform and display

## When to use
Saving or loading game state, reacting to suspend, sizing for the screen, choosing a quality tier.

## The model
Games never touch OS Beroun or the page directly; they use `FerretPlatform`, picked by `detectPlatform`: `BerounPlatform` (OS), `BrowserPlatform` (localStorage under `storageKey`), `HeadlessPlatform` (tests, in memory, `resize()` and `suspend()` to simulate the host).

## Steps
1. State: `loadState()` (last saved or `null`), `saveState(obj)`.
2. Save in `onSuspend(fn)`; on OS Beroun the app is closed with about two seconds to save.
3. Screen: `screen()` gives size, density and `DeviceClass` (`console`, `phone`, `tablet`, `desktop`); follow with `onResize`.
4. `Display.trackCamera(cam)` keeps the field of view right (`fovFor`); `renderScale` trades sharpness for speed; `initialTier` picks the starting tier (the console is always `low`); `display.setTier(tier)` at run time.
5. Lay the HUD out in `em` from the UI scale.

## Check afterwards
Run headless with `HeadlessPlatform`: save, `suspend()`, reload, state is back; resize to a phone and a 4K screen, nothing is cut off.

## What usually goes wrong
- Relying on `beforeunload` to save instead of `onSuspend`.
- Pixel-sized HUD that is unreadable on the console or 4K.
- Requiring Pointer Lock or mouse look: not available on the console.
- Forgetting that physics tiers follow the same names as display tiers (see `ferret-physics-fx-tuning`).

## Files

- `reference/platform.md` — One interface over OS Beroun and the browser; screen, device class and quality tiers.
- `reference/api-platform.md` — every export of `@ferret/platform` with signature and doc comment
