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

Testing

Develop offline on the mock, then play your game inside uloggd, from your machine or from a release, before anyone reviews it.

On the mock, offline

A Vite project's npm run dev serves the game on localhost, where createArcadeSDK({ appId, mockWhenStandalone: true }) gives you the mock: no uloggd, no network, every command answered. Open a second tab with ?mock_player=2 in the address to be a second player. The SDK reference shows how to steer the mock in your own tests.

Your server accepts the mock's tokens only with allowMock: true. Keep that in your development configuration: a production verifier must refuse them.

In the verifiers for other languages, allowMock and allowTestMode (see Test mode) correspond to allow_mock and allow_test_mode in Python, which is verified and published on Verifying in other languages. The Go and C# verifiers, written but not yet verified, call them WithMockTokens() and WithoutTestMode() in Go, and AllowMock and AllowTestMode in C#.

To play the game inside uloggd while it still runs on your machine, use the development URL.

Test mode, inside uloggd

Test, on a release in the portal, opens it in the real player, on a page only you can open: /developers/applications/{id}/arcade/test/{releaseId}.

  • Any release of your app can be tested, draft, submitted, in review or approved, as long as its last URL check passed in the last 24 hours. Press Check URL again when it is older.
  • It needs a session signed in with two-factor. Test plays count toward the 60 games an account may open per hour, and the age rules apply as they do to any player.
  • Test plays are never counted as plays of your game.

Test mode is marked everywhere, so it cannot pass for the real thing:

  • a striped bar above the game says it is test mode, that the version was not reviewed, that only you see it, and not to type passwords;
  • the launch URL carries mode=test, and identity tokens "mode": "test";
  • the consent dialog adds that the version was not reviewed.

The SDK, consent and identity tokens work in test mode. verifyIdentityToken accepts test tokens unless you pass allowTestMode: false: pass it on any server where an unreviewed version must not sign anyone in. Data events reach your server once a release is approved (see Before approval).

Development URL: localhost and tunnels

The development URL opens the game in uloggd's real player while it runs on your machine or behind a tunnel, before any deploy, with no proof file and no URL check. In the portal, open the app and, in its Arcade section, go to Development URL: type the address in Game URL, pick a Base release, Save, then Open on uloggd.

  • What it accepts. http or https on your own machine, on any port: localhost, a name under .localhost (such as game.localhost), or 127.0.0.1. Or https on a public host, on any port, such as a tunnel. No user, query or fragment, and the path follows the release rules.
  • What it refuses, with url_denied:
    • [::1] and every other IPv6 address: the player page's policy cannot name an IPv6 origin. Write localhost or 127.0.0.1 instead.
    • Every other IP address, and a public host that resolves to a private address when you save it: uloggd frames your own machine, never another device on your network. To reach a dev server from a phone or another computer, use a tunnel.
    • http on a public host: plain HTTP only to your own machine.
    • uloggd's own hosts and their look-alikes, as for releases, and the hostname the uloggd site itself is served on. Cookies are not isolated by port, so a game on that hostname would share them with uloggd; on uloggd.com that is uloggd.com itself, not your localhost.
    • Hosts on the release denylist, except the ephemeral tunnels such as *.trycloudflare.com and *.ngrok-free.app, which the development URL accepts.
  • The base release. A draft, submitted, in review or approved release of the same app. What the game may do and ask for comes from it: capabilities, scopes, orientation and platforms. The development URL replaces only the address.
  • The store page. It must be saved before the game opens, because the player shows the game's name and controller from it. A draft is enough.
  • 24 hours. Saving again, with the same URL or another, starts another 24 hours. An app gets 20 saves a day; only a save that is kept counts, so a refused URL and Remove are free. Removing it, moving it to another origin or letting it expire closes a game open on it within 30 seconds. A new path or base release on the same origin does not: the game already open keeps the address and the base release it opened with until you open it again.
  • Only you. It opens only for the app's owner, on a session signed in with two-factor, at /developers/applications/{id}/arcade/override/play. Nobody else, reviewers and moderators included, can open it or read the URL. An origin held by another account's game is refused with origin_in_use. Plays count toward the 60 games an account may open per hour, the age rules apply, and they are never counted as plays of your game.

It is marked as test mode, like a tested release:

  • the striped bar says "Test mode: development URL, only you can see this. Do not type passwords." and shows the host with its port;
  • the launch URL carries mode=test, and identity tokens "mode": "test";
  • the consent dialog adds "Unreviewed version.".

Identity tokens from the development URL are ordinary test-mode tokens: the same iss and aud, and no claim of their own. A server that accepts test tokens accepts them too, so pass allowTestMode: false on every production server. Data events never go to the development URL: they go to the data events URL of a release (see Delivery).

On your own machine. Chrome and Edge may ask whether uloggd.com may access apps and services on this device (their Local Network Access prompt). Allow it, and the game loads from your machine; if you would rather not, use a tunnel. To take the permission back, open uloggd.com's site settings from the icon at the left of the address bar, and reset or block it there. Only the development URL's page can use that permission, and only for the loopback origin you saved (see Permissions). Loopback is meant for Chromium-based browsers such as Chrome and Edge; other browsers may not open a local address inside uloggd's HTTPS page. A tunnel works in all of them.

Tunnels

A tunnel gives your dev server a public HTTPS address. Any of these works:

  • cloudflared: cloudflared tunnel --url http://localhost:5173 prints an address under trycloudflare.com. Quick tunnels like this one are accepted for the development URL, even though a release refuses them.
  • Tailscale Funnel: tailscale funnel 5173 serves the dev server on your machine's ts.net name. Funnel publishes only ports 443, 8443 and 10000, and the development URL accepts any of them.
  • ngrok: ngrok http 5173. Its free plan may show a warning page before your site, and inside the frame that page keeps the game from loading.

Then:

  • Vite answers only the hosts it knows. Add the tunnel's to server.allowedHosts in vite.config.js, such as allowedHosts: [".trycloudflare.com"] (a leading dot admits every subdomain).
  • The dev server must let uloggd frame it: send Content-Security-Policy: frame-ancestors https://uloggd.com 'self', as the template's vite.config.js does, and no X-Frame-Options.
  • The game keeps hostOrigin at its default, https://uloggd.com.

If the game does not open

  • "No active development URL" or "The development URL expired": save it again in the portal, then open it from there.
  • "The development URL cannot be opened right now": the cover and the portal say why, such as a base release that was rejected or withdrawn, or no saved store page.
  • "The developer's site did not answer the way uloggd expects": the dev server is not running, or it does not allow https://uloggd.com in frame-ancestors. On localhost, the browser may also have refused the local address, or the Local Network Access permission is blocked: allow it in the site settings, or use a tunnel.
  • "Blocked request" from Vite: the tunnel's host is missing from server.allowedHosts.
  • "The game was restarted" after each edit: a full page reload is a navigation of the frame, which ends the play (see One document). An update Vite applies in place keeps it running; after a reload, play again from the cover.

Before you submit

  • Check URL passes: the proof file, no redirect, framing allowed.
  • The game played inside uloggd from the development URL with this release as its base, so the capabilities and scopes it declares are the ones the game needs.
  • The page creates the SDK first, and shows its own loading screen.
  • ready() resolves in test mode, with context.mode equal to test.
  • Nothing navigates the frame: no links, no reloads, no second page.
  • Fullscreen goes through requestFullscreen, from a click.
  • authorize follows a click of the player's, and a cancel leaves the game playable.
  • Your server verifies a test token and refuses a replayed one.
  • After approval, change your nickname for the game in Settings > Arcade, and check that a verified nickname_changed reaches your server.
  • Every third party the game loads is declared in the release.
  • On a phone, the layout follows LAYOUT_UPDATE and the safe area.

Data events

When a player revokes, forgets your game, changes the nickname or deletes the account, uloggd tells your server, and you repeat it.

Review policy

What a reviewer checks before a release or a store page reaches players, the reasons for a refusal, and what ends an account.

On this page

On the mock, offlineTest mode, inside uloggdDevelopment URL: localhost and tunnelsTunnelsIf the game does not openBefore you submit