# Creator runtime options and external backends Studio and MCP expose the same project options. A creator can activate supported cloud browser saves and Hackemist multiplayer rooms for an owned app. Extra browser capabilities and external destinations use administrator review. These settings change runtime permission; the uploaded app still needs save or networking integration in its JavaScript. ## Studio Open **Studio → Cloud saves** to inspect storage/save integration hints and enable automatic localStorage sync when separate runtime hosting is available. Under **Studio → App details → Browser compatibility**, **Multiplayer & connections** enables built-in rooms and shows the operator's service availability, guest policy, and room-size limit. Its copyable SDK starter demonstrates creating/joining a room and sending messages; implement your own UI and app rules using [the room SDK](/docs/multiplayer.md). The **External backend / API / WebSocket** form lists current approved origins separately from a pending request. Enter one exact origin per line, such as `https://api.example.com` and `wss://rooms.example.com`, and explain which data the service receives. Approval is required before the runtime CSP allows those connections. Submit the complete desired connection-origin list; include existing origins that the app still needs. Other approved permissions and pending managed-cache/frame requests are preserved. Deploy the backend through your own provider. Add its public endpoint URL and client networking logic to the browser build. Keep private API keys, database passwords, service-role credentials, and MCP credentials on the server or in the coding client's secret store. Hackemist serves the static frontend and does not execute uploaded Node/Python servers, install packages, proxy arbitrary requests, or inject private credentials into browser code. Use **Additional browser permissions** for managed service-worker caching, external assets, frames, and forms. The administrator can review the complete profile or configure permissions directly after password confirmation. Pointer capture, immersive WebXR VR/AR, native workers and shared-memory WASM instead follow global Admin switches, enabled by default, and require no project permission request. WebXR and workers automatically use dedicated origins when wildcard hosting is available. Shared memory requires workers and matching cross-origin isolation headers; disabling workers suspends shared memory. Spatial tracking does not grant raw camera or unrelated sensor access; player gestures/consent, supported hardware and a secure context remain necessary. Reopen the app after a permission change; old launches are revoked. ## MCP 1. Call `runtime_options_get` with `project_id`. It returns the current `policy`, opaque `policy_revision`, pending/approved/rejected request status, isolation availability, creator-option gate, and room-service configuration/limits. Use `save_integration_get` with `project_id` and optional `version_id` to inspect source hints and the save-format declaration. The read-only scan is bounded to 64 HTML/JS files, 512 KiB per file, and 2 MiB total. It does not execute code or access player saves. Hints cannot establish that memory-only progress or every gameplay field is persisted. 2. Call `runtime_options_update` with `project_id`, `base_policy_revision` from that response, and any of the boolean fields `auto_save`, `isolated`, or `multiplayer`. Only supplied options change. Enabling `auto_save` also enables `isolated` unless explicitly supplied; disabling saves retains the isolated origin and existing save data. Isolation cannot be disabled while an approved dependent capability is active. 3. To request a backend, call `connections_request` with `project_id`, current `base_policy_revision`, `connect_origins`, and a `reason` of 5–2,000 characters. It creates or amends a pending administrator review request. It preserves other approved/pending permissions and does not grant external network access. 4. For memory-only progress, connect `Hackemist.createProgressStore` with synchronous JSON `capture`, validated `restore`, `initial` and recovery UI callbacks. Await `ready` before player actions; preserve originals and pause for a choice when local/cloud data differ. Replace unconditional lifecycle cache writes with its gated `cacheLocal()`; local cache is not a cloud acknowledgement. The app defines which fields constitute progress. See [SAVE_SDK.md](/docs/save-sdk.md). Integrate external services separately, validate and preview, then publish explicitly. A standalone MCP preview is read-only and cannot open account saves or shared rooms. Test authenticated behavior in the Studio/player bridge; closing or offline operation cannot guarantee an unacknowledged final save. ```json { "name": "runtime_options_update", "arguments": { "project_id": "YOUR_PROJECT_ID", "base_policy_revision": "COPY_CURRENT_POLICY_REVISION_FROM_RUNTIME_OPTIONS_GET", "auto_save": true, "multiplayer": true } } ``` ```json { "name": "connections_request", "arguments": { "project_id": "YOUR_PROJECT_ID", "base_policy_revision": "COPY_NEW_POLICY_REVISION_FROM_PREVIOUS_RESPONSE", "connect_origins": ["https://api.example.com", "wss://rooms.example.com"], "reason": "Our separately hosted backend authenticates players and stores authoritative game state." } } ``` `runtime_options_get` needs `projects:read`; updates and requests need `projects:write`. Current account eligibility, token revocation, ownership, and project binding are checked again in the transaction. An administrator's MCP credential can modify only its own projects. A stale revision returns a conflict: reload current options and explicitly retry. The revision also covers pending request changes, so a stale form cannot silently overwrite a newer request. Safe option changes amend only those fields in the pending request and invalidate its previous review revision. `compatibility_get` includes these runtime options. `compatibility_request` continues to request a **complete** permission profile; start from the returned approved/pending profile and preserve existing permissions. Its policy schema lists all supported booleans and exact-origin arrays. `hosting_info` links this document through `hackemist://docs/connections`. ## Operator availability and backend integration The administrator's `creator_runtime_options_enabled` setting controls self-service runtime choices. Room activation also requires the global room service to be enabled and a valid stable signing key/service origin. Global disabling of rooms prevents connections even when an app's room option was previously enabled. Cloud browser saves require dedicated runtime origins, `RUNTIME_SUBDOMAINS=true`, a stable `SETTINGS_KEY`, and wildcard DNS/TLS. Production uses separate registrable domains by default or the explicitly configured sibling-domain protections (operator repository reference: `SINGLE_DOMAIN_DEPLOYMENT.md`). When hosting is unavailable, the operator must configure it; a project permission request cannot replace that setup. Apps can instead integrate explicit account saves with [the save SDK](/docs/save-sdk.md). Approved connection origins are network permissions, not backend authentication. Requests go directly from the player's browser. Your service must implement its own authentication, authorization, CORS, rate limits, and persistence. In the restricted sandbox the browser's Origin may be `null`; isolated origins differ per account/project/profile. Do not treat the Origin header as a user's identity or grant unauthenticated access simply to accept `null`. Browser third-party-cookie rules still apply; Hackemist account cookies/tokens are not passed to your service. Add the HTTPS origin used by API calls and the WSS origin used by sockets separately. URL paths belong in your app code, not in the origin allowlist. ```js // Public browser URLs: replace routes and add your backend's client auth. const response = await fetch('https://api.example.com/state'); if (!response.ok) throw new Error('Backend request failed'); const data = await response.json(); const socket = new WebSocket('wss://rooms.example.com/session'); socket.addEventListener('message', event => { const message = JSON.parse(event.data); // Validate your application's message schema before using it. }); ``` For threaded WASM or isolated app frames/assets, provider CORS/COEP/CORP headers must also support browser isolation. A permission grant cannot repair an incompatible provider. Exact HTTPS/WSS origins are required in production; wildcards, paths, embedded credentials, control/runtime origins, and literal private-network endpoints are rejected. Hackemist rooms offer temporary presence/messages and host-controlled shared state. They do not execute authoritative uploaded game rules. Use an external server for secret answers, authoritative competition rules, payments, persistent shared economies, or long-lived world state. Use account save checkpoints for lasting per-player progress. ## HTTP parity - `GET /api/projects/PROJECT_ID/runtime-options` reads the same owned-project status as MCP. - `PUT /api/projects/PROJECT_ID/runtime-options` accepts `{base_policy_revision, auto_save?, isolated?, multiplayer?}`. - `POST /api/projects/PROJECT_ID/runtime-connections/request` accepts `{base_policy_revision, connect_origins, reason}`. These browser routes use the existing signed-in account and CSRF protection. They do not accept bearer credentials or arbitrary profile fields. Extra capabilities continue through `POST /api/projects/PROJECT_ID/runtime-request` and the administrator review queue.