Platform and display
Games never talk to OS Beroun or to the page directly. They use FerretPlatform, which has three implementations and picks one with detectPlatform:
| Implementation | When | Notes |
|---|---|---|
BerounPlatform | /platform.js is present (OS Beroun) | state in the OS, log to the shell, exit() closes the app |
BrowserPlatform | any other page | state in localStorage under the game's storageKey, fullscreen, exit() goes back to the start page |
HeadlessPlatform | tests | everything in memory; resize() and suspend() to simulate the host |
What the interface gives#
- Saved state:
loadState()returns what the game saved last (ornull),saveState(obj)stores it. - Suspend:
onSuspend(fn)is called before the page goes away. On OS Beroun the app is closed and has about two seconds to save; in a browser the tab is hidden or closed. Save there. - Exit:
exit(). - Screen:
screen()returns size, pixel density and theDeviceClass(console,phone,tablet,desktop);onResize(fn)follows it. - Log:
log(msg).
Display and quality#
Display keeps the canvas, the hardware scaling factor, the quality settings and cameras in step with the screen. A phone held upright and a 4K monitor use the same game: trackCamera(cam) sets the field of view from the aspect (a fixed vertical angle that widens on wide screens, with a minimum horizontal angle so tall screens still see enough, see fovFor), and renderScale trades sharpness for speed.
initialTier chooses the starting quality tier from the device class; the console is always low. display.setTier(tier) changes it at run time. The physics budget has tiers of its own that follow the same names, see Physics overview.
Writing for all of them#
- Bind actions, never keys: the console has a cursor, A and B, no mouse look and no Pointer Lock (Input and UI).
- Lay the HUD out in
emfrom the UI scale, not in pixels. - Save on
onSuspend; do not rely onbeforeunload. - Keep the first frame small: assets are streamed and loaded after the loading screen is up (Levels).