uloggdDevelopers
Developer portaluloggd
Get startedResourcesArcade
Developer portaluloggdArcadeHostingThe frameSDKIdentityVerifying in other languagesData eventsTestingReview policyPrivacy dutiesEngines

The frame

What a game can and cannot do inside uloggd's player, how it starts and stops, and the parameters it is launched with.

The game runs in an iframe, on a uloggd page built for that game alone. The page's policy lets the frame hold your origin and nothing else, and the frame stays covered until the SDK completes its handshake.

The sandbox

<iframe
  src="https://orbit.example.com/?frame_id=...&instance_id=...&platform=desktop&locale=en&mode=live&protocol=1"
  sandbox="allow-scripts allow-same-origin allow-forms"
  allow="autoplay; gamepad; ..."
  referrerpolicy="strict-origin"
></iframe>
TokenWhen
allow-scriptsAlways.
allow-same-originAlways. The game keeps its own origin, which gives it storage and gives uloggd an origin to verify. It is safe because that origin is never uloggd's.
allow-formsAlways, so submit events fire.
allow-pointer-lockOnly when the release declares the pointer-lock capability.

Never granted: popups, top navigation, modal dialogs, downloads, the Storage Access API, orientation lock and presentation. In practice:

  • window.open, links with target="_blank" and top.location fail. In v1 a game cannot open links at all; the store page carries your privacy policy, terms and support links.
  • alert, confirm and prompt do nothing. Draw your own dialogs.

Permissions

The allow attribute delegates autoplay and gamepad. Everything else is denied, by the attribute and by the player page's Permissions-Policy: camera, microphone, geolocation, payments, USB, serial, HID, Bluetooth, screen capture, WebAuthn and the other credential APIs, local fonts, window management, idle detection, picture-in-picture, the privacy sandbox APIs, and local network access. Firefox ignores the Permissions-Policy header.

Local network access is denied on every uloggd page but one: the page of your development URL, and only when that URL is on your own machine. There, the page's policy and the frame's allow let the frame reach that one loopback origin, and nothing else on your network. The browser may still ask you first.

Fullscreen belongs to uloggd's page, and the game asks for it through the SDK (below).

The first request for your entry URL carries Referer: https://uloggd.com/, never the page's path.

Storage and cookies

  • Storage is partitioned by the top-level site. localStorage, IndexedDB, the Cache API and service workers inside uloggd are separate from the same game opened on your own site, and a player who clears uloggd's site data clears them. Keep anything that matters on your server.
  • Cookies are not reliably partitioned. Safari blocks third-party cookies and Firefox keeps them apart per site, but Chrome still sends your unpartitioned cookies, and those of every third party the game embeds. Do not build sessions on cookies: once your server has verified an identity token, give the game a token of your own and send it in an Authorization header. If you must set a cookie, mark it SameSite=None; Secure; Partitioned.
  • A service worker you register lives in uloggd's partition and keeps serving what it cached to returning players, whatever your server serves today, and uloggd's checks cannot see it. If you use one, tie its cache to the build.

One document, start to finish

  • Any navigation of the frame removes the game: a second load event, a closed message channel, or a navigation the page's policy blocked. The player is told the game restarted, with a button to play again. Multi-page games and location.reload() are not supported.
  • The page's policy admits only your exact origin, so the browser blocks a redirect or a link to any other one.
  • Frames you nest inside the game inherit the sandbox, but they follow your own Content-Security-Policy, not uloggd's. Declare every third party you embed in the release.
  • Never call history.back(): from a sandboxed frame it can move the player's whole tab.

Starting, staying alive, closing

  • Handshake. createArcadeSDK sends uloggd a handshake, and uloggd answers with a private message channel. The frame stays covered until then; after 30 seconds the player is told the game did not load. Create the SDK as the first thing the page does, before downloading large assets, so the player sees your own loading screen.
  • Liveness. uloggd pings the game every second, and the SDK answers. After 2 seconds without an answer the frame is covered again and the player is told the game is not responding; the next answer uncovers it. Keep the main thread free: split long work, or move it to a worker.
  • Hidden tab. After 5 minutes hidden (15 with the background-audio capability), uloggd sends CLOSING and removes the frame.
  • Closing. When the player presses Close, the game gets CLOSING and up to 1 second to save before the frame is removed. Save as you go rather than counting on that second.
  • Suspension. If uloggd suspends the game, new launches are refused at once, and running frames are closed with code 4010 within 60 seconds.

Fullscreen and pointer lock

  • The frame cannot go fullscreen on its own. Call arcade.commands.requestFullscreen() from a click or a key press: uloggd puts its own container in fullscreen, with its bar still visible, or fills the screen on an iPhone. Without a recent gesture the call fails with requires_gesture.
  • Declare the pointer-lock capability to use requestPointerLock(). uloggd cannot see a lock your game holds, so for such a release its consent dialog never opens on its own: when authorize asks, the player's bar shows the request with an Answer button and says that Esc releases the pointer, and the dialog opens from that click. Without the capability, authorize opens the dialog directly.

Launch parameters

uloggd appends its own query to your entry URL:

?frame_id=Q1r9...&instance_id=0b7e...&platform=desktop&locale=en&mode=live&protocol=1
ParameterValue
frame_id22 base64url characters, used by the SDK in the handshake.
instance_idA uuid for this play.
platformdesktop or mobile.
localept-BR, en or es.
modelive, or test when you open your own release in test mode or your development URL. Reviewers play in live.
protocol1.

Nothing in it identifies the player, so your logs and analytics may keep it. The SDK reads it for you, and the same values arrive in context when ready() resolves.

Limits to know

  • Review certifies a moment, not a build. Daily checks, new reviews, player reports and suspension are how uloggd keeps following a game after approval.
  • Players' IP addresses reach your servers and every third party the game loads.
  • Where a browser does not give cross-site frames a process of their own (Safari, Firefox for Android and Chrome for Android), a game that blocks its main thread also freezes uloggd's page around it, until it yields.
  • No header can stop a clipboard write after a gesture. Asking players to paste or run something is against the rules (see Review policy).

Hosting

Where the game lives, the rules its URL must pass, and the checks uloggd runs against it.

SDK

@uloggd/arcade-sdk: the client, every command, event, error and close code, and the mock.

On this page

The sandboxPermissionsStorage and cookiesOne document, start to finishStarting, staying alive, closingFullscreen and pointer lockLaunch parametersLimits to know