Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Scenes, assets and 3D models

This page describes the three parts that make up your game’s world: real-time scene (stage/room) registration, images uploaded from the panel and the server, and 3D models uploaded by an operator. Read it if you want to open city rooms from the server, manage icon and banner images, or serve models to the game.

What it does

  • Scene: The room where the real-time plugin gathers players. The game server registers the scenes it needs at startup; registration is idempotent.
  • Image (asset): PNG, JPEG or WebP. It is content-addressed: the address is the file’s sha256 digest, and the same file is stored once. Store banners, currency icons and content group image fields use this store.
  • 3D model: A glb (or a converted source file) uploaded by an operator in the panel. Once published it is bound to an item or a character and the game gets it from the catalog.

The scene and image write endpoints depend on the scenes module; if the module is disabled, 404 with {"code":"module_disabled","module":"scenes"} is returned. The image and model read endpoints are core and work even when the module is disabled. Enable the module on the Game settings › Modules page.

Where it lives in the panel

What you want to doPanel page
Upload, preview, publish and archive a 3D model, add a clip3D models, Model profile
Bind a model to an item or a characterContent (built-in item/character groups)
Upload store banners and product images, currency iconsStore, Currencies
Moderate city chat (scene plugin)City chat
See that the scene plugin is installed, and its permissionsPlugins

Note

Panel help pages are not translated yet; the panel links above point to the Turkish source.

Data model (in plain words)

Scene

  • The ID is derived from three parts: plugin_id (the plugin), module_id (the real-time module) and key (at most 96 characters). The same triple always resolves to the same scene.
  • capacity: The room’s player capacity; at most 10,000.
  • state: open, draining (emptying) or closed.
  • partition_id: The ID of the partition the scene runs on in the distributed setup (generated by the server).

Image

  • The type is derived from the first bytes of the file; the Content-Type header is only advisory. Accepted types are image/png, image/jpeg, image/webp.
  • At most 2 MiB; width and height are each at most 4096 pixels.
  • The response gives sha256, contentType, byteSize and created (whether it was written in this call).

3D model

  • An upload can be glb, or it is converted from source formats such as fbx, obj, usdz, stl, blend, 3mf, dxf. The conversion status is queued, converting, ready, failed; the reason for a failure appears in the panel as a sentence in Turkish (for example an external resource reference, a budget overrun, a 2D DXF).
  • Every model is versioned; the published version appears in the catalog. The lifecycle is active, archived, purged.
  • Default limits: uploaded file 50 MiB, environment quota 1 GiB, 200 models per environment, 20 versions per model, 10 uploads per operator per 10 minutes.
  • The converter runs only on the amd64 architecture; on other architectures only glb can be uploaded.

Calls your game makes

Method and pathCredentialWhat it does
PUT /v1/scenesserver keyProvisions a scene idempotently
PUT /v1/assetsserver keyUploads an image as a raw body
GET /v1/assetsserver keyLists the environment’s images (cursor, limit)
DELETE /v1/assets/{sha256}server keyDeletes an image row (204)
GET /v1/assets/{sha256}no credentialReads the image bytes
GET /v1/model-files/{sha256}no credentialReads a published model’s glb file

Management endpoints require Authorization: Bearer crx_live_<prefix>_<secret>; a client key gets 403.

Provisioning a scene

PUT /v1/scenes
Authorization: Bearer crx_live_<prefix>_<secret>
Content-Type: application/json

{ "plugin_id": "package-ride", "module_id": "package-ride.presence", "key": "istanbul-1", "capacity": 200 }
{ "scene_id": "…", "plugin_id": "package-ride", "module_id": "package-ride.presence", "key": "istanbul-1", "partition_id": "…", "capacity": 200, "state": "open", "created": true }
  • If the scene does not exist, it is written (201, created: true); if it exists, it is returned unchanged (200, created: false). Idempotency-Key is not needed.
  • 400: the ID, key or capacity is invalid (body errors are 400 too). 403: a client key. 409: a scene with a different ID on the same key. 422: the plugin is not enabled in this environment.

For a plugin’s real-time modules and the player-side flow, see Realtime: overview and Plugins.

Uploading an image

PUT /v1/assets
Authorization: Bearer crx_live_<prefix>_<secret>
Content-Type: image/png

<raw PNG bytes>
{ "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "contentType": "image/png", "byteSize": 18234, "created": true }

201 with created: true is the first write; if the same bytes already exist, 200 and created: false are returned and the row does not change, so the upload is idempotent. An empty body, an unrecognized type, a size over 2 MiB or a width/height over 4096 pixels is rejected with 400 (error codes asset_empty, asset_unsupported_type, asset_too_large, asset_dimensions_too_large).

To show the image in the game, use <img src="…/v1/assets/<sha256>?env=<environment uuid>">: the endpoint is unauthenticated, and it takes the environment from the x-crx-env header or (for <img>/texture loaders that cannot send headers) from the env query parameter. The response carries the sha256 as its ETag and can be cached indefinitely (immutable); if If-None-Match matches, 304 is returned. A new image means a new sha256, that is a new address.

Note

The image and model read endpoints send cross-origin readable response headers so that a browser’s texture loader can use them. The other public endpoints grant CORS only to origins in the environment’s domain list; see Architecture and hosting.

Warning

DELETE /v1/assets/{sha256} deletes only the row; the store does not know whether other records (a product, an icon, content) refer to this image. Make sure the image is unused before deleting it.

Bringing a 3D model into the game

Upload and publish the model in the panel and bind it to an item or a character. The game reads the model’s address and computed facts (triangle count, bones, clips, bounding box) from the catalog; model.glb.url has the form /v1/model-files/<sha256>?env=<environment uuid>. Details: Content groups › Catalog and Game catalog integration (docs/oyun-katalog-entegrasyonu.md) (Turkish).

GET /v1/model-files/{sha256} is unauthenticated and content-addressed:

  • The environment is given with the x-crx-env header or the env query; if both are given and differ, or neither is present, 400.
  • Only the glb file of a model that is ready, whose files are retained and which is not deleted is returned; 404 for a deleted model.
  • A matching If-None-Match gives 304 without opening the file. A 200 response carries Content-Length, the model/gltf-binary type and indefinite cache headers. Range is not supported.
  • The same sha256 is always the same bytes: cache the file by sha256 and do not download it again.

Note

Model upload and publishing are done only from the panel; there is no public write endpoint for models. The Unity SDK has no catalog and model read helpers; use raw REST.

Versioning and replay safety

  • PUT /v1/scenes and PUT /v1/assets are naturally idempotent (a derived ID, a content address); they do not ask for Idempotency-Key.
  • A model file and an image are content-addressed: the same address never gives different bytes.
  • Model versions are tracked in the panel; the game always sees the current published version from the catalog.

Events

These surfaces produce no webhook events. A model change is reflected in the catalog as a new sha256; poll with ETag.

Limits

  • An image is at most 2 MiB and 4096×4096 pixels; only PNG, JPEG, WebP.
  • Scene key is at most 96 characters, capacity at most 10,000.
  • The model default limits are above (50 MiB, 1 GiB quota, 200 models, 20 versions).
  • The GET /v1/assets page size is at most 200 (default 50).

Common errors

SymptomCauseFix
422 (scene)The plugin is not enabled in this environmentEnable the plugin (Plugins)
409 (scene)A scene with a different ID on the same keyChange the key
400 (image)The type was not recognized, or 2 MiB or 4096 pixels was exceededUpload PNG/JPEG/WebP under 2 MiB and 4096 pixels
<img> does not loadenv or x-crx-env is missingAdd ?env=<environment uuid> to the address
404 (model file)The model was deleted or is not ready yetCheck the model field in the catalog
The model is failed in the panelA conversion errorFix the file according to the reason the panel shows

Working example

Uploading and reading an image:

curl -X PUT "$API/v1/assets" \
  -H "Authorization: Bearer $SERVER_KEY" -H "Content-Type: image/png" \
  --data-binary @banner.png

curl "$API/v1/assets/<sha256>?env=$ENV" -o banner.png