7.2 KiB
studio
The RecFlare Studio host (https://studio.<domain>).
Device login stays on Auth, GET /account/me stays on Accounts, and the approval
page is WWW /device. This worker queues cloud builds, accepts completed bundles,
and serves build status and co-owner presence. Rooms exposes playable bundles in
CurrentSave.UnitySubAssets; their bytes are served by the CDN at /room/{filename}.
The Rooms GET /rooms/{roomId}/subrooms/{subRoomId}/unityasset route separately
returns the editable source manifest and available build metadata.
| Method | Path | Purpose |
|---|---|---|
GET |
/cloud-builds/for-room |
Cloud builds for that room and subroom, newest first (results, totalResults). Query: roomId, subRoomId, skip, take. A bad query is an empty page. |
GET |
/cloud-builds/get-build-count-for-user |
Authenticated user's Studio build totals for the current UTC-hour rate-limit window. |
POST |
/cloud-builds/from-editor |
Multipart Windows bundle (windows) and Android bundle (android), optional windowsStripped and androidStripped. Stores a finished build on the subroom's current published save and sets BecameRRStudioRoomAt the first time. Bearer required, and the token must include betastudio. Caller must be the creator or a co-owner. |
GET |
/collaboration/owners-in-room |
Account ids of the room's co-owners (creator, or a Creator/CoOwner role) whose live presence is in that roomId and subRoomId. Body: { success: true, error: null, value: number[] }. Bearer required. |
Development
Run in dev mode
pnpm dev
Run tests
pnpm test
Deploy
pnpm turbo deploy
Migrate
This worker owns studio_cloud_build on the shared recflare database (migrations/,
tracked in its own d1_migrations_studio table). The bundles themselves are rows of the
rooms worker's unity_asset (one per platform and kind: target 0 Windows / 2 Android,
studio/<roomId>/<name>.assetbundle as filename — the bytes sit at room/<filename> in
the bucket, the prefix the client adds — base64 SHA-256 as hash), so a stored build needs
the rooms migrations too. Deploying does not apply either.
just migrate -F studio # remote
just migrate -F studio -- --local # dev db
Launcher template distribution
Set STUDIO_DISTRIBUTION_MANIFEST to an R2 catalog key to enable the optional
PatchKit-compatible /1/apps/:secret/* routes. The catalog and ZIP parts are
generated by studio-patch-2026/build_distribution.py; upload all parts through
the existing CDN before publishing the catalog. No template bytes or operator
configuration belong in this repository.
The catalog names the template application's SHA-256 identifier, latest release,
HTTPS multipart content URL, file hashes, and download-chunk hashes. Optional
legacy summaries supply comparison hashes without making old templates
downloadable. The application identifier scopes requests; it is not an access
credential. Missing or disabled catalogs return 404. Invalid catalogs or catalogs
larger than 8 MiB return 503; responses use Cache-Control: no-store so a corrected
publication can be retried immediately.
Editor build limits
GET /cloud-builds/get-rate-limit-config returns the editor's
CloudBuildRateLimitConfigDTO directly: buildThrottleIntervalHours (1),
warnAfterBuildsPerInterval (90), and maxBuildsPerInterval (100). These names
matter: unknown keys leave the DTO's maximum at zero and block even a first build.
The authenticated get-build-count-for-user route provides the user's counts.
Queued Studio builds
POST /cloud-builds/create accepts the SDK's room, subroom, save, auto-publish,
and optional target fields. It requires Studio authorization and room management
rights, validates the uploaded source manifest, and returns a numeric string
build ID with a null completion time. Repeated requests for an in-progress save
reuse its job. GET /cloud-builds?cloudBuildId=... reads the status;
PUT /cloud-builds/cancel cancels a queued or running job.
Apply migration 0003_studio_cloud_build_job.sql. Configure a private
CLOUD_BUILD_KEY and run the outbound worker from recflare/cloud-building with
the matching credential. Without a key, creation returns an explicit unavailable
response. CLOUD_BUILD_TARGETS defaults to 0,2 (Windows and Android), and
CLOUD_BUILD_TEMPLATE_VERSION defaults to 169. Match installed editor modules to
the enabled targets.
The private /internal/cloud-builds/claim, /:id/heartbeat, and /:id/finish
routes lease jobs to that worker. Only validated UnityFS artifacts for the
allocated asset IDs and requested platforms are accepted. SDK bundle version 5
is retained. Completion links the submitted save; auto-publish does not replace
a newer draft. Failed, cancelled, or expired jobs never become successful builds.
Claims include a signed, short-lived SDK validation token with no account subject
or roles. Bulk component-text validation and job-scoped grant reads accept this
credential. It cannot authenticate as an account or publish a room.
Avatar Studio and consumable validation
Avatar authoring uses per-account Studio grants, source revisions, and the managed
cloud queue. Apply migrations/0004_avatar_studio.sql to the shared database before
enabling these routes. The API owns creator saves and explicit publication; the
Studio service queues prefab builds and returns per-platform main/stripped bundles
at version 5 and material bundles at version 6. Image badges publish directly.
Changed body/configuration inputs receive distinct output IDs, and automatic
publication cannot replace a newer revision. Deploy the paired cloud-building
worker for prefab support; restricted validation credentials grant no account role.
The SDK's access override reads the target account's entitlement. Build-validation credentials can inspect only the current owners of their active job's room; peers can inspect grants only while they currently manage the same room.