# Terrain and backgrounds ## Use the editor Open **World** in the editor's asset panel. Set **Layout → Outdoor**, then choose **Meadow**, **Desert**, **Rocky** or **Flat**. Change the size, hill height, roughness or seed. **New seed** generates a different arrangement; **View terrain** frames the landscape. The central build area remains level. Place props and stations within X/Z ±half your selected **Build area** width (56–384 metres); the generated terrain extends around that area and is walkable. A player reaching the outer boundary returns to spawn. Changing the seed preserves your placed entities. Terrain settings support Undo and Redo. Choose **Sky** or **Lobby panorama** under **Background**, or select **Upload panorama**. Accepted uploads appear in the same selector and can be reused in your other worlds. Adjust **Background rotation °** to align the view with your layout. Terrain and background changes are part of the draft. **Save draft** stores them; **Publish** queues the world update after current bets finish. Set **Layout → Room** to restore the enclosed room. This removes terrain and background settings from the draft; uploaded images remain in your library. ## Prepare a panorama Use a still PNG, JPEG or WebP with these limits: | Property | Limit | | --- | --- | | Input file | 12,000,000 bytes | | Width | 512–8192 pixels | | Height | 256–4096 pixels | | Aspect ratio | 2:1 through 8:1, width divided by height | | Decoded pixels | 16,777,216 | | Converted WebP | 8,000,000 bytes | A seamless **2:1 equirectangular panorama**, such as 4096 × 2048, covers the full sphere. A wider panorama, such as 8192 × 2048, covers a band around the horizon and fades into the sky above and below. Keep the horizon near the middle, align the left and right edges and bake the image in landscape orientation. Panoramas with a rotated EXIF orientation are rejected; export the actual pixels in the intended orientation first. The renderer softens the join and poles, but matching the source edges gives the best result. The converter retains the source dimensions, strips metadata, flattens transparency and encodes a new WebP. Only the converted image is stored and displayed. SVG, GIF, animated WebP, archives and URLs are not accepted. Processing uses the isolated, networkless image worker. Models and converted backgrounds share your **100 MB library allowance**. A referenced panorama also counts toward the world's **100 MB download**, **32 megapixel texture** and **500 MB estimated memory** limits. A maximum-size panorama may leave too little memory for a complex world; the save response reports the combined budget. ## World document fields Keep `version: 1`, `floor`, `walls` and `entities`. Add either or both of these optional fields: ```json { "terrain": { "preset": "desert", "seed": 42, "size": 256, "height": 9, "roughness": 0.45 }, "background": { "mode": "lobby", "yaw": 0 } } ``` The example shows the environment fields to merge into your complete document. | Terrain field | Required value | | --- | --- | | `preset` | `meadow`, `desert` or `rocky` | | `seed` | Integer 0–2,147,483,647 | | `size` | Integer 128–512 and at least `buildSize + 64`; full square width in game units | | `height` | Finite number 0–28; maximum terrain amplitude | | `roughness` | Finite number 0–1; contribution of smaller hills | The same settings generate the same terrain. Geometry uses a fixed 192 × 192 grid: 37,249 vertices and 73,728 triangles. The center remains flat through ±`(buildSize / 2 + 6)` units (±34 at the default build size), then transitions into hills. Collision uses the generated mesh. The return boundary is three units inside each outer edge. Terrain geometry counts toward the geometry and estimated memory budgets; the world stores only its parameters. | Background field | Required value | | --- | --- | | `mode` | `sky`, `lobby` or `image` | | `yaw` | Finite radians, −2π through 2π | | `asset` | Required only for `image`: a 64-character lowercase hex hash from your background library | For an uploaded image: ```json {"mode":"image","asset":"","yaw":1.5707963267948966} ``` Omit `terrain` for flat outdoor ground. Omit both `terrain` and `background` for the enclosed room. A background alone creates a square of flat ground with width `max(128, buildSize + 64)` and the `floor` color. Change the root `buildSize` field to enlarge the placement area. The editor automatically increases terrain width if enlarging the build area requires it; API clients must send compatible values together. Game dimensions remain unchanged. There is no separate background URL, shader or expression field. ## Upload through HTTP With a world-scoped Bearer credential: ```bash curl --fail-with-body \ -X POST https://betworld.gg/api/worlds/ai/backgrounds/upload \ -H "Authorization: Bearer $BETWORLD_TOKEN" \ -H "Content-Type: image/webp" \ -H "X-Image-Name: Desert sunset" \ --data-binary @desert-panorama.webp ``` Send raw image bytes. Accepted content types are `image/png`, `image/jpeg`, `image/webp` and `application/octet-stream`. `X-Image-Name` is an optional trimmed name, 1–80 characters; it defaults to `Panorama`. Use ASCII for this HTTP header. The authenticated owner-session equivalent is `POST /api/worlds/backgrounds`. Successful response, HTTP 201: ```json { "hash": "<64-character-hash>", "name": "Desert sunset", "size": 1843200, "width": 4096, "height": 2048, "pixels": 8388608 } ``` Download the converted result from `GET /api/worlds/backgrounds/.webp`. This immutable public route returns `image/webp`. A creator can reference only hashes in their own library, even when another creator's public image URL is known. `GET /api/worlds/mine`, `GET /api/worlds/:id/draft`, `GET /api/worlds/ai/draft/document` and `GET /api/worlds/ai/export/world` include a `backgrounds` array with these metadata fields. The export also includes each background's `url`. `/mine` reports `usedBytes` for models and backgrounds together. The existing `assets` array continues to contain only GLB models. After upload, fetch the latest draft, set `document.background`, and save the complete document with its current `revision`. Uploading alone does not modify or publish the world. | Status | Meaning | | --- | --- | | 400 | Invalid fields, library quota, missing/foreign background, or world budget exceeded | | 401 | Sign-in or world credential required | | 404 | Background hash does not exist | | 413 | Request body exceeds the upload limit | | 422 | Image could not be converted within its format, dimension or processing limits | | 429 | Request rate or concurrent-write limit reached | | 503 | Converter is busy or unavailable; retry later | ## Upload through MCP Call `background_upload` with: ```json { "name": "Desert sunset", "imageBase64": "" } ``` The decoded image has the same 12 MB limit. The tool returns the metadata shown above. Use `world_download`, update `document.terrain` and/or `document.background`, then call `world_upload` with the returned revision and the complete document. Preserve entities, game skins and any other settings. Publish from your owner session in Betworld. The Blender bridge preserves terrain and background settings during download/upload round trips. Its scene preview still uses the base room shell; inspect the generated landscape and panorama in the in-game editor.