Skip to main content
Glama

Tiles (TileMapLayer / TileSet)

tiles

Build 2D tile maps in Godot: create TileSets from atlas images, add TileMapLayer nodes, and paint cells, terrain, or whole levels from ASCII art. Every edit is undoable.

Instructions

2D tile maps with TileMapLayer nodes (the deprecated TileMap node is never used). Build a TileSet from an atlas image in one call (tiles auto-detected from non-transparent cells, collision, terrains for autotiling, custom data), add layers, then paint: cells/rects/lines, terrain autotiling, or whole levels from ASCII art. All painting is undoable. Coordinates are map cells, tiles are atlas coords [x, y].

Actions:

  • create_tileset: {path: res://tiles/world.tres, texture: res://art/tiles.png, tile_size=[16,16], separation?=0|[x,y], margin?=0|[x,y], all_tiles?=false (else only non-transparent cells get tiles), overwrite? (layers of open scenes using the old TileSet are relinked), tile_shape?, physics_layers?: [{collision_layer: [1|'world'], collision_mask: [...]}], full_collision?: bool (full-square polygon on every tile) | collision_tiles?: [[x,y] | {tile:[x,y], points?:[[x,y]...] (tile-centered), one_way?}], terrains?: [{name, color?, mode?: match_corners_and_sides|match_sides|match_corners, block?: [x,y] (origin of a 3x3 autotile block: corners/edges/center; or {origin, size}), tiles?: [[x,y]...] (fully this terrain) | {"x,y": 'all' | ['top','right','bottom_right',...] | '010/111/010' 3x3 mask | {center:'grass', top:'dirt', ...}}}], custom_data?: [{name, type: int|float|bool|string|vector2|color..., values?: {"x,y": value}}]} create a TileSet from an atlas image. No art yet? assets.placeholder {kind: 'tileset'} makes one.

  • info: {path: res://x.tres | TileMapLayer node, tiles?=true} sources, atlas grid, tile coords (with collision/terrain/custom data per tile), physics layers, terrain sets, custom data; for a layer also used cells/rect.

  • create_layer: {tileset: res://x.tres, name?='TileMapLayer', parent?='.', position?, index?, props?: {z_index, y_sort_enabled, collision_enabled, ...}} add a TileMapLayer node. Use several layers for background/ground/decoration.

  • paint: {path: layer, cells: [[x,y],...] | rect: [x,y,w,h] | line: [[x1,y1],[x2,y2],...], tile: [ax,ay] (or [[ax,ay],[bx,by]] to pick randomly for variety), source?=first, alternative?=0} set cells to a tile.

  • fill_rect: {path, rect: [x,y,w,h], tile: [ax,ay], border?: [ax,ay] (different tile on the edge), hollow?: bool (only the edge; interior erased)} fill a rectangle, e.g. rooms with walls.

  • erase: {path, cells | rect | line} remove tiles.

  • terrain: {path, cells | rect | line, terrain: name|index, terrain_set?=0, mode?: connect|path, ignore_empty_terrains?=true} paint with terrain autotiling (the TileSet needs terrains, see create_tileset). Use -1 as terrain to erase terrain-aware.

  • from_ascii: {path, rows: ['##########', '#........#', '#..gggg..#', '##########'], legend: {'#': [3,0], '.': null (erase), 'g': {terrain: 'grass'} | 'grass', 'w': {tile: [1,0], source?, alternative?}}, origin?=[0,0], clear?=false} paint a whole level from ASCII art; spaces leave cells untouched. Best way to lay out levels.

  • read: {path, rect?: [x,y,w,h] (default: used rect), legend?: same legend as from_ascii ({char: [ax,ay] | null (empty char) | 'grass' | {terrain: 'grass'}}), cells?: bool} used cells plus an ASCII picture (terrain cells map to their terrain's char; other unknown tiles get auto characters, returned in auto_legend). Use it to check what's painted.

  • clear: {path} erase every cell of the layer (undoable).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cellNo[x, y] single cell.
lineNo[[x1, y1], [x2, y2], ...] polyline of cells.
modeNoterrain: connect (areas) or path (roads/rivers).
nameNoNode name.
pathNoTileMapLayer node path (scene-relative), or res:// TileSet path for create_tileset/info.
rectNo[x, y, width, height] in cells.
rowsNoASCII rows: list of strings (one per map row) or one string with line breaks.
tileNo
cellsNo[[x, y], ...] map cells.
clearNofrom_ascii: clear the layer first.
indexNoChild index.
propsNoProperty map. Values are coerced to the property type: numbers, [x,y], 'Vector2(1,2)', '#ff8800', 'res://file', {"type":"RectangleShape2D","size":[32,32]} for new resources, enum names as strings.
sceneNores:// scene to operate on; opened in the editor if needed. Defaults to the currently edited scene.
tilesNoinfo: include per-tile listing (default true).
actionYesWhat to do. See the tool description for each action's parameters.
borderNo[ax, ay] border tile for fill_rect.
hollowNofill_rect: only the outline.
legendNo{char: [ax, ay] | null | {tile, source?, alternative?} | {terrain}}.
marginNo
originNo[x, y] map cell of the first ASCII character.
parentNoParent node path (default '.').
sourceNoTileSet source id (default: first source).
terrainNo
textureNores:// atlas image for create_tileset.
tilesetNores:// TileSet for create_layer.
positionNo[x, y] layer position.
terrainsNoTerrain definitions (see create_tileset).
all_tilesNocreate_tileset: create tiles for every cell, even fully transparent ones.
overwriteNoReplace an existing TileSet file.
tile_sizeNo[w, h] tile size in pixels (default [16, 16]).
separationNo
tile_shapeNosquare | isometric | half_offset_square | hexagon.
alternativeNoAlternative tile id (default 0).
custom_dataNoCustom data layers [{name, type, values?}].
terrain_setNoTerrain set index (default 0).
full_collisionNoFull-square collision on every tile.
physics_layersNo[{collision_layer, collision_mask}] layer numbers or names.
collision_tilesNoTiles that get collision: [[x,y]] or {tile, points?, one_way?}.
ignore_empty_terrainsNoterrain: ignore empty terrain bits when matching.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.3/5.0
Behavior4/5

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

Annotations declare readOnlyHint=false and destructiveHint=false, and the description reinforces that mutations are safe by stating 'All painting is undoable' and calling out clear as undoable. It also discloses that overwrite relinks layers of open scenes using the old TileSet, which is genuinely useful behavioral context beyond the annotations.

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

Conciseness4/5

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

Front-loaded overview (what, coordinate conventions, undo guarantee) followed by a scannable per-action breakdown. It is long, but the 10-action, 39-parameter surface justifies the density and every action entry carries distinguishing detail rather than filler.

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

Completeness4/5

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

With no output schema, the description steps in to describe read's return (used cells plus an ASCII picture with auto_legend) and covers the parameter semantics for every action, including required TileSet prerequisites for terrain autotiling. Not every edge case (e.g., error behavior on a missing layer) is covered, keeping it at a strong 4.

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 description coverage is already 90%, so the baseline is 3. The description exceeds that by explaining non-obvious semantics: the '010/111/010' 3x3 terrain mask format, tile-centered collision points, tile-size/block origins for terrains, the alternative parameter for random variety, and how legends differ between from_ascii and read.

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

Purpose5/5

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

Names a concrete resource (2D tile maps, TileMapLayer/TileSet) and enumerates the specific verbs available (create_tileset, paint, terrain, from_ascii, read, clear). It explicitly distinguishes itself by stating the deprecated TileMap node is never used and by scoping to tilemap work that no sibling tool covers.

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

Usage Guidelines4/5

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

Provides per-action guidance ('Use several layers for background/ground/decoration', 'Best way to lay out levels' for from_ascii, 'Use it to check what's painted' for read, and the assets.placeholder pointer when no art exists). It does not state explicit when-not conditions or name a concrete alternative tool, so it stops short of a 5.

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