Skip to main content
Glama

Generate terrain

terrain_heightmap

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.

Input Schema

NameRequiredDescriptionDefault
iYesThe chunk column (east) to start from; chunks are 128 by 128 tiles.
jYesThe chunk row (south) to start from; chunks are 128 by 128 tiles.
glbNoTrue to also return the mesh as terrain.glb, at the mesh step.
rawNoTrue to also return heights.f32, every tile's exact height as little-endian float32.
areaNoA block of chunks, w by h (each 1 to 8) from (i, j), drawn as one picture on one grey scale.
bitsNoGrey depth of the PNG: 8 (the default) or 16.
meshNoTrue, or {step} of 1 to 16 tiles between vertices, to also return the ground as terrain.obj.
seedYesThe seed word that makes the country; the same word, chunk and knobs give the same ground.
rangeNoOptional [lo, hi] in world units that fixes the grey scale, so separate calls tile on one scale.
paramsNoCountry 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.
featuresNoTrue to also return features.json: where each tree, rock and scenery piece stands.

Output Schema

NameRequiredDescriptionDefault
msNoMilliseconds the run took.
jobYesThe job id; the job tool reads it.
verbNoThe tool that made it.
filesNoFiles made, each with a name, type, size and a signed URL.
unitsNoUnits this call cost.
resultNoThe engine's own answer, a JSON document.
statusNoqueued when the job runs in the background.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changed
    • addedInput schema / properties / area / description
      Added value: +"A block of chunks, w by h (each 1 to 8) from (i, j), drawn as one picture on one grey scale."
    • addedInput schema / properties / bits / description
      Added value: +"Grey depth of the PNG: 8 (the default) or 16."
    • addedInput schema / properties / features / description
      Added value: +"True to also return features.json: where each tree, rock and scenery piece stands."
    • addedInput schema / properties / glb / description
      Added value: +"True to also return the mesh as terrain.glb, at the mesh step."
    • addedInput schema / properties / i / description
      Added value: +"The chunk column (east) to start from; chunks are 128 by 128 tiles."
    • addedInput schema / properties / j / description
      Added value: +"The chunk row (south) to start from; chunks are 128 by 128 tiles."
    • addedInput schema / properties / mesh / description
      Added value: +"True, or {step} of 1 to 16 tiles between vertices, to also return the ground as terrain.obj."
    • addedInput schema / properties / params / description
      Added value: +"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."
    • addedInput schema / properties / range / description
      Added value: +"Optional [lo, hi] in world units that fixes the grey scale, so separate calls tile on one scale."
    • addedInput schema / properties / raw / description
      Added value: +"True to also return heights.f32, every tile's exact height as little-endian float32."
    • addedInput schema / properties / seed / description
      Added value: +"The seed word that makes the country; the same word, chunk and knobs give the same ground."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": true,
      +  "properties": {
      +    "files": {
      +      "description": "Files made, each with a name, type, size and a signed URL.",
      +      "items": {
      +        "additionalProperties": {},
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "job": {
      +      "description": "The job id; the job tool reads it.",
      +      "type": "string"
      +    },
      +    "ms": {
      +      "description": "Milliseconds the run took.",
      +      "type": "number"
      +    },
      +    "result": {
      +      "description": "The engine's own answer, a JSON document."
      +    },
      +    "status": {
      +      "description": "queued when the job runs in the background.",
      +      "type": "string"
      +    },
      +    "units": {
      +      "description": "Units this call cost.",
      +      "type": "number"
      +    },
      +    "verb": {
      +      "description": "The tool that made it.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "job"
      +  ],
      +  "type": "object"
      +}
  2. First observed

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnly/destructive/idempotent), and the description adds a great deal beyond them: the cost ('Costs 1 unit for any area'), the error contract ('an unknown or out-of-range knob is refused with the reason'), determinism of seed+chunk+knobs, and the exact modes in which files (PNG, heights.f32, terrain.obj, terrain.glb, features.json) are emitted. The non-determinism implied by idempotentHint=false is consistent with the per-call unit cost, so there is no annotation contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first clause, which is good, but the remainder is one enormous semicolon-and-parenthesis run-on sentence that is hard to parse and forces re-reading. Almost every clause carries information, so length is defensible for an 11-parameter tool, but the lack of sentence breaks or grouping hurts scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 11 parameters, nested objects, and an output schema, the description covers what an agent still needs: the coordinate conventions (row 0 north, x east/y up/z south), the output modes and their file names, cost, error behavior, and the grey-scale math (height = greyFrom + grey * unitsPerGrey). Return-value detail is partly carried by the output schema, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description materially enriches it: it supplies real working ranges that differ from the schema's generic ±65536 bounds (terrainAmp 0-40, terrainOctaves 1-5, ridgeHeight 0-400, step 1-16, area w/h 1-8) and explains ridgeX0/Z0/X1/Z1 as a hill along a line and range as the tiling scale. Many knobs (slopeLimit, clumping, palette, waterTable) are still only named, not explained, keeping it short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause gives a concrete verb and resource: 'Builds open country from a seed word and writes its ground as a greyscale PNG,' and it pins down the chunk/tile coordinate system. That is far more specific than a tautology, but it never names or contrasts a sibling such as world_heightmap or raster_render, so an agent still has to infer which generator is the right one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the text explains that 'a landscape is one call' via area and that range 'fixes the grey scale... so separate calls tile,' which tells the agent how to combine calls. There is no explicit when-to-use-this-vs-alternatives guidance, no exclusions, and no prerequisite statements, so it stays at the implied-usage level.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources