---
title: "One chunk of open country as a greyscale heightmap."
method: POST
path: "/api/agents/run/terrain_heightmap"
tags: ["Production engines"]
---

# One chunk of open country as a greyscale heightmap.

`POST /api/agents/run/terrain_heightmap`

## Request

- Base URL: `https://tomorrowlives.com`
- URL: `https://tomorrowlives.com/api/agents/run/terrain_heightmap`
- Auth: HTTP bearer

Builds open country from a seed word and writes its ground as a greyscale PNG (row 0 is north; chunk (i, j) is 128 by 128 tiles). By default the picture is one chunk at 8 bits and black is its lowest tile, white its highest; bits 16 writes it at 16 bits (65535 greys, so a 40 unit relief steps by under a thousandth of a unit and a game's terrain built from it shows no stairs), and raw (true) also returns heights.f32, every tile's exact height as little-endian float32, width by height, row 0 north. area {w, h} (each 1 to 8) makes a w by h block of chunks from (i, j) one picture on one grey scale, so a landscape is one call; range [lo, hi] fixes the grey scale in world units so separate calls tile. params sets country knobs by name (terrainAmp 0 to 40, terrainOctaves 1 to 5, slopeLimit, treeDensity, rockDensity, clumping, portWidth, padRadius, padJitter, corridorWidth, meander, palette, waterTable, ridgeHeight 0 to 400 with ridgeX0, ridgeZ0, ridgeX1, ridgeZ1 for a long hill along that line); an unknown or out-of-range knob is refused with the reason. The answer carries the height range, the grey scale used (greyFrom, greyTo, unitsPerGrey, so height is greyFrom plus grey times unitsPerGrey), the bits, wall and scenery counts and the digest. mesh (true, or {step} of 1 to 16 tiles between vertices) also returns the ground as terrain.obj, a Wavefront OBJ in world units (x east, y up, z south) with normals and UVs that runs to the area's far edge so the next area's mesh starts where it ends; by default the step is the smallest that keeps a side to 256 cells. glb (true) returns the same mesh as terrain.glb, a glTF binary with normals and UVs, at mesh's step. features (true) also returns features.json: where each tree and rock stands (x, y, z and half extents) and the scenery (kind, position, turns, scale), each listed once, with the ground's height under it. Costs 1 unit for any area.

## Request body

- object
  - `seed` string, required: The seed word that makes the country; the same word, chunk and knobs give the same ground.
  - `i` integer, required: The chunk column (east) to start from; chunks are 128 by 128 tiles.
  - `j` integer, required: The chunk row (south) to start from; chunks are 128 by 128 tiles.
  - `area` object: A block of chunks, w by h (each 1 to 8) from (i, j), drawn as one picture on one grey scale.
    - `w` integer, required
    - `h` integer, required
  - `range` unknown[]: Optional [lo, hi] in world units that fixes the grey scale, so separate calls tile on one scale.
    - unknown
  - `params` object: Country knobs by name (terrainAmp, terrainOctaves, slopeLimit, treeDensity, rockDensity, clumping, portWidth, padRadius, padJitter, corridorWidth, meander, palette, waterTable, ridgeHeight, ridgeX0, ridgeZ0, ridgeX1, ridgeZ1). An unknown or out-of-range knob is refused with the reason.
    - `terrainAmp` number
    - `terrainOctaves` number
    - `slopeLimit` number
    - `treeDensity` number
    - `rockDensity` number
    - `clumping` number
    - `portWidth` number
    - `padRadius` number
    - `padJitter` number
    - `corridorWidth` number
    - `meander` number
    - `palette` number
    - `waterTable` number
    - `ridgeHeight` number
    - `ridgeX0` number
    - `ridgeZ0` number
    - `ridgeX1` number
    - `ridgeZ1` number
  - `mesh` union: True, or {step} of 1 to 16 tiles between vertices, to also return the ground as terrain.obj.
    - boolean
    - object
      - `step` integer, required
  - `features` boolean: True to also return features.json: where each tree, rock and scenery piece stands.
  - `bits` 8 | 16: Grey depth of the PNG: 8 (the default) or 16.
  - `raw` boolean: True to also return heights.f32, every tile's exact height as little-endian float32.
  - `glb` boolean: True to also return the mesh as terrain.glb, at the mesh step.

## Response `200`

The job's result and files

- Job
  - `job` string
  - `verb` string
  - `units` integer
  - `ms` integer
  - `result` unknown
  - `files` object[]
    - `name` string
    - `bytes` integer
    - `content_type` string
    - `url` string
    - `url_expires_at` string, date-time

## Other responses

- `400`: The input is not valid
- `401`: No valid API key
- `402`: A pass or a payment is needed: a queued render on the free plan, a unit pack on the free plan (pass_required), a card plan's past-due renewal, or, on the free plan, an owner who has not confirmed their email yet (owner_unconfirmed; a pass needs no confirmation); or a payment did not go through (payment_failed, payment_token_unusable), and nothing was charged
- `403`: The account is suspended, the paying card is not from the United States (region_not_supported), or the address named as its owner said it is not theirs and costed runs are paused until a new owner is named (owner_removed)
- `413`: The input or the output is over its cap; a job stopped by the output cap is not charged
- `422`: The engine refused the input, a limit of the service's refused it (error: video_limit or pull_limit) or stopped the job, or the content policy refused the input (error: content_policy)
- `429`: A limit was hit; reset_at says when it lifts (also in Retry-After)
- `503`: The engines are busy or not installed
- `504`: The job ran past its time and was stopped

---

[API](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines.md) · [All operations](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/llms.txt) · [OpenAPI document](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/revisions/afc3d67322ac?raw)
