- Knownframe
- battlemap-mcp
- Docs
- Terrain, paths, water and caves tools
Terrain, paths, water and caves tools
Generated from the battlemap-mcp server at a020c64. Your assistant gets these same names, descriptions and parameters from the server when it connects; the server is named battlemap, so a client may show a tool as battlemap:ping or similar.
set_terrain_slot
Assign a Terrain asset to a terrain slot index so it can be filled/painted with that slot.
| Parameter | Type | Default |
|---|---|---|
asset required | string | |
slot | integer | 0 |
fill_terrain
Flood-fill the whole current level with a terrain slot.
If asset is given, it is assigned to the slot first.
The usual first ground call is fill_terrain(asset=<base material>) on the default slot 0: that replaces the base under everything and leaves slots 1-3 free for roads, yards and worn edges painted on top with fill_region.
| Parameter | Type | Default |
|---|---|---|
slot | integer | 0 |
asset | string | "" |
fill_region
Fill only a region with a terrain slot (e.g. floor a single room), in woxel coords.
Unlike fill_terrain (whole level), this paints inside a shape. Provide ONE of: rect: [x, y, w, h] axis-aligned rectangle, or points: [[x,y], ...] a polygon (>= 3 points).
asset: optional Terrain asset to assign to the slot first.
rate: paint strength 0..1 (1 = fully replace). Undoable via undo().
| Parameter | Type | Default |
|---|---|---|
rect | number[] | null | null |
points | number[][] | null | null |
slot | integer | 0 |
asset | string | "" |
rate | number | 1 |
paint_terrain
Paint a soft circular terrain brush of a slot at a woxel position.
radius: brush radius in woxels. rate: peak strength 0..1 at the center, with a smooth falloff to the rim so strokes blend. asset: optional Terrain asset to assign to the slot first (else set it with set_terrain_slot). Undoable. For a hard-edged region instead of a brush, use fill_region.
| Parameter | Type | Default |
|---|---|---|
slot | integer | 0 |
x | number | null | null |
y | number | null | null |
radius | number | 64 |
rate | number | 1 |
asset | string | "" |
paint_path
Paint a continuous terrain stroke (a road/trail) along a polyline in one call.
asset is a TERRAIN asset, not a Paths one — this paints ground, it does not lay a Paths element. Use draw_path for that.
points: a list of [x, y] woxel corners the path runs through (>= 2). The bridge rasterizes a uniform ribbon of constant width by measuring each pixel's distance to the nearest segment, so the route comes out smooth with clean edges — no gaps or double-painted overlaps. Prefer this over stamping many paint_terrain dabs for any line/road.
radius: half-width of the stroke in woxels. rate: peak strength 0..1 with a soft falloff to the edges so it blends. asset: optional Terrain asset to assign to the slot first (else set it with set_terrain_slot). Undoable.
| Parameter | Type | Default |
|---|---|---|
points required | number[][] | |
slot | integer | 0 |
radius | number | 96 |
rate | number | 1 |
asset | string | "" |
paint_material
Paint a MATERIAL patch along a brush stroke. Returns what it painted.
Materials are their own system — irregular patches of stone, earth, lava or moss with their own borders — and they are not terrain and not patterns. A Materials asset passed to place_pattern makes a PATTERN, not a material.
Choose between them deliberately: terrain ground that must BLEND into neighbouring ground pattern a tiled floor inside a building material a sculpted patch with its own edge, sitting on top of ground water actual water
points: the stroke, in woxels. One point is a single dab.
asset: a Materials path from list_assets(category='Materials').
size: brush radius in mesh CELLS, 1-20. A cell is typically one tile, so size 6 paints roughly twelve tiles across PER DAB. Start at 1-2 and look.
layer: which material layer to paint into. Materials on different layers stack rather than merge. Keep the default -400 unless you have checked an export: a stroke on -300 showed in the editor but not in an export.
smooth: smooth the patch's edge, versus following the material's own texture.
erase: remove this material along the stroke instead of adding it.
The response reports cell_size_woxels and covered_woxels so the brush size can be reasoned about on the ground. There is no "did it land" flag, because the engine offers no reliable one: verify a stroke by looking at it. Each call is one undo step.
| Parameter | Type | Default |
|---|---|---|
points required | number[][] | |
asset required | string | |
size | integer | 2 |
layer | integer | -400 |
smooth | boolean | true |
erase | boolean | false |
get_terrain
Read the terrain back: sample the painted terrain on a grid.
rect: [x, y, w, h] in woxels; omit for the whole map.
samples: grid resolution per side, 2-64 (16 = 256 points).
Returns a weights grid, row-major from the rect's top-left. Each point is [slot0, slot1, slot2, slot3], read directly from the splat image's RGBA channels and summing to ~1, and slots: the texture each of those four slots holds.
Slot 0 is the BASE: whatever slots 1-3 leave unclaimed shows slot 0's texture. So [1, 0, 0, 0] means "all slot 0" — and what that looks like depends entirely on slots[0]. On a new map every slot holds limestone, so it is ground nobody chose; after fill_terrain(asset=grass) it is grass. The weights cannot tell those apart, which is why slots is reported. paint_terrain(slot=0) is accepted by the engine but never raises slot 0's weight; fill_terrain(slot=0) replaces the base instead.
Slots 4-7 live in a second splat image, reported as weights2. All eight weights are one blend: painting any slot takes weight from the other seven. A slot 4-7 needs a texture (set_terrain_slot) before it is painted.
This is the only way to check terrain without a screenshot — use it to confirm a fill or paint landed where you meant, and to see what ground you inherited on a map you did not build.
render: also report how the GPU draws it (shader, bound textures, and at at = [x, y] the CPU and GPU weights), for ground that reads wrong.
| Parameter | Type | Default |
|---|---|---|
rect | number[] | null | null |
samples | integer | 16 |
render | boolean | false |
at | number[] | null | null |
set_terrain_blending
Choose how terrain slots blend into one another on this level.
enabled: True for smooth blending (slots fade into each other), False for textured (the blend follows the material's own texture, giving a grainier, more natural seam).
This is a per-level setting that affects every terrain edge already painted, not just the next one, so choose it before painting rather than after.
get_terrain reports the current value as smooth_blending.
| Parameter | Type | Default |
|---|---|---|
enabled required | boolean |
repair_terrain
Rebuild a level's terrain splat when the engine dropped it. Destructive.
Only needed on a map whose terrain has already been lost. Symptom: every terrain call answers "the terrain splat image is empty", and Dungeondraft's log carries Expected data size of N bytes in Image::create() at load.
That happens when a map was resized while its terrain was not. The splat keeps the pixel dimensions it was created with, the mismatch is silent until the map is next opened, and Godot then refuses the image and drops every painted stroke — while the save that produced it reported success. set_map_size now resizes the rasters with the map, so new maps do not reach this state; this repairs one that already did.
It does not recover anything. The painted terrain is gone before this runs; all it restores is a usable surface to paint on, so the terrain has to be laid down again afterwards. Nothing else on the map is touched.
force: blank a splat that is already usable. This throws away working terrain, so it is off by default.
| Parameter | Type | Default |
|---|---|---|
force | boolean | false |
draw_path
Draw a path/road/river through a list of [x, y] woxel points. Returns the new element id.
asset: a Paths asset path from list_assets(category='Paths').
smoothness: optional curve smoothing. width: optional width scale multiplier.
A wall-textured path looks like a wall but carries no line of sight into a VTT export. Where vision matters, run a real draw_wall along it too.
End treatments, which are what make a path read as part of the world rather than a strip laid on top of it:
fade_in / fade_out: the path's opacity fades at its start / end. Use where a trail should disappear into undergrowth or run off the map edge, instead of stopping at a hard rectangular cut. grow / shrink: the path's WIDTH tapers at its start / end. A stream that narrows upstream, a track that widens as it approaches a gate.
Set these per path, here: changing the PathTool's own options beforehand does not affect what this draws.
snap: 'none', 'grid' or 'auto'; see get_snap_settings.
| Parameter | Type | Default |
|---|---|---|
points required | number[][] | |
asset required | string | |
layer | integer | 0 |
sorting | integer | 0 |
smoothness | number | null | null |
width | number | null | null |
fade_in | boolean | false |
fade_out | boolean | false |
grow | boolean | false |
shrink | boolean | false |
snap | string | "" |
add_water
Add a body of water — a pond, pool, river bend, moat, or flooded room.
rect: [x, y, w, h] in woxels, or points: [[x,y], ...] for a shoreline.
invert: erase water inside the outline instead of adding it. Water is a layer, not an object — there is nothing to select and delete — so this is how you take a pond back or cut an island out of one.
Water is a polygon layer, not a brush stroke: you give it a closed outline and the whole enclosed area becomes water. Give exactly one of:
rect: [x, y, w, h] in woxels, for a rectangular pool.
points: [[x, y], ...] with at least 3 points, for an irregular shape — a pond, a river bend, a cave lake. The outline closes automatically.
Call it repeatedly to build up several separate bodies of water. When the level's existing water shares one style (set_water_style), new water takes it too and the response says matched_level_style.
| Parameter | Type | Default |
|---|---|---|
rect | number[] | null | null |
points | number[][] | null | null |
invert | boolean | false |
set_water_style
Style this level's water: what KIND of water it is. Returns the result.
Geometry first (add_water), then this. A muddy river, a clear shallow, a peat swamp and a deep cold pool are the same mesh with different colour.
Per LEVEL: every body of water on this level is restyled, and water drawn later on a level whose bodies share one style takes that style too. The response reads the style back off the water bodies, which are what the map saves; bodies is how many there are, and mixed_styles means they differ.
| Parameter | Type | Default |
|---|---|---|
deep_color | string | "" |
shallow_color | string | "" |
blend_distance | number | null | null |
border | boolean | null | null |
dig_cave
Carve a cave along a path with the Cave Brush (the dig/blast tool).
Dungeondraft caves are a separate layer: you dig open floor out of solid rock, and DD auto-generates the rocky wall border + debris around the opening.
points: a list of [x, y] woxel points the cave runs through (>= 1). A single point digs one circular chamber; multiple points dig a connected tunnel (rasterized as a constant-width ribbon, like paint_path). radius: half-width in woxels (default 256 = ~1 tile). dig: True carves open cave; False fills it back to rock. ground_color / wall_color: optional cave floor/wall tints ("#rrggbb" or [r,g,b]). texture: optional Caves floor asset (see list_assets(category="Caves")). The mesh rebuilds automatically.
| Parameter | Type | Default |
|---|---|---|
points required | number[][] | |
radius | number | 256 |
dig | boolean | true |
ground_color | string | "" |
wall_color | string | "" |
texture | string | "" |
get_cave
Read the selected level's cave floor/entrance cell counts and actual colours.
Entrances are a separate blast mask that removes rocky borders; they do not carve floor. Counts describe bitmap cells, not distinct rooms or openings.
No parameters.
set_cave_entrance
Open or restore a circular section of cave border, as one undoable edit.
Place the centre at an existing cave edge in woxels. radius is the half-width (0 < radius <= 2048), rounded to cave cells. open=False removes the blast mask, restoring the border; neither mode digs or fills cave floor. Dig the approach first with dig_cave, then inspect a screenshot of the mouth. The edit belongs to the selected level. Undo requires that same level and unchanged bitmap dimensions. Returns the actual number of changed cells.
| Parameter | Type | Default |
|---|---|---|
x required | number | |
y required | number | |
radius | number | 256 |
open | boolean | true |
clear_caves
Wipe the entire cave layer back to solid rock.
Removes all carved caves at once (the whole cave system), rebuilding the mesh. Undoable like dig_cave. Use this instead of filling regions back with dig_cave(dig=False) when you want to reset all caves.
No parameters.