tilemap
Manage TileSets and TileMaps in Godot: create tilesets, add texture sources, set tiles, paint, and list. Use help for full documentation.
Instructions
TileSet and TileMap management. Actions: create_tileset|add_source|set_tile|paint|list. Use help tool for full docs.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform | |
| project_path | No | Path to Godot project directory | |
| scene_path | No | Path to scene file (for list, paint) | |
| tileset_path | No | Path to TileSet .tres file (for create_tileset, add_source) | |
| texture_path | No | Texture source path (for add_source) | |
| tile_size | No | Tile size in pixels (default: 16, for create_tileset) |
Implementation Reference
- src/tools/composite/tilemap.ts:25-138 (handler)The handleTilemap function executes tilemap tool logic with actions: create_tileset, add_source, set_tile, paint, list. Creates TileSet .tres files, adds texture sources, lists TileMapLayer nodes in scenes, and provides guidance for tile painting/setup.
export async function handleTilemap(action: string, args: Record<string, unknown>, config: GodotConfig) { const projectPath = (args.project_path as string) || config.projectPath switch (action) { case 'create_tileset': { const tilesetPath = args.tileset_path as string if (!tilesetPath) throw new GodotMCPError( 'No tileset_path specified', 'INVALID_ARGS', 'Provide tileset_path (e.g., "tilesets/main.tres").', ) const tileSize = (args.tile_size as number) || 16 const fullPath = safeResolve(projectPath || process.cwd(), tilesetPath) // Performance optimization: using async pathExists instead of existsSync // to avoid blocking the Node.js event loop during I/O operations if (await pathExists(fullPath)) { throw new GodotMCPError(`TileSet already exists: ${tilesetPath}`, 'TILEMAP_ERROR', 'Use a different path.') } const content = [ `[gd_resource type="TileSet" format=3]`, '', `[resource]`, `tile_shape = 0`, `tile_size = Vector2i(${tileSize}, ${tileSize})`, '', ].join('\n') // Performance optimization: using async file writing instead of sync // to avoid blocking the Node.js event loop during I/O operations await mkdir(dirname(fullPath), { recursive: true }) await writeFile(fullPath, content, 'utf-8') return formatSuccess(`Created TileSet: ${tilesetPath} (tile size: ${tileSize}x${tileSize})`) } case 'add_source': { const tilesetPath = args.tileset_path as string const texturePath = args.texture_path as string if (!tilesetPath || !texturePath) { throw new GodotMCPError('tileset_path and texture_path required', 'INVALID_ARGS', 'Both are required.') } const fullPath = safeResolve(projectPath || process.cwd(), tilesetPath) // Performance optimization: using async pathExists instead of existsSync if (!(await pathExists(fullPath))) throw new GodotMCPError(`TileSet not found: ${tilesetPath}`, 'TILEMAP_ERROR', 'Create the tileset first.') // Performance optimization: using async file reading instead of sync let content = await readFile(fullPath, 'utf-8') // ⚡ Bolt: Using replaceAll('\\', '/') avoids RegExp allocation overhead const resPath = `res://${texturePath.replaceAll('\\', '/')}` // Count existing sources to get next ID const sourceCount = (content.match(/\[ext_resource/g) || []).length const sourceId = `source_${sourceCount}` // Add ext_resource reference const extRes = `[ext_resource type="Texture2D" path="${resPath}" id="${sourceId}"]` content = content.replace('[resource]', `${extRes}\n\n[resource]`) // Performance optimization: using async file writing instead of sync await writeFile(fullPath, content, 'utf-8') return formatSuccess(`Added texture source: ${texturePath} (id: ${sourceId})`) } case 'set_tile': { return formatSuccess( 'Tile configuration requires editing TileSet .tres resource data.\n' + 'For complex tile setup, use Godot editor.\n' + 'Basic format: sources/N/tiles/coords/terrain_set, animation_columns, etc.', ) } case 'paint': { const scenePath = args.scene_path as string if (!scenePath) throw new GodotMCPError('No scene_path specified', 'INVALID_ARGS', 'Provide scene_path with TileMapLayer node.') return formatSuccess( 'TileMap painting requires modifying tile_map_data which is binary-encoded.\n' + 'For procedural tile placement, create a GDScript that sets cells at runtime:\n' + '```gdscript\nvar tilemap = $TileMapLayer\ntilemap.set_cell(Vector2i(x, y), source_id, atlas_coords)\n```', ) } case 'list': { const scenePath = args.scene_path as string if (!scenePath) throw new GodotMCPError('No scene_path specified', 'INVALID_ARGS', 'Provide scene_path.') const fullPath = safeResolve(projectPath || process.cwd(), scenePath) // Performance optimization: using async pathExists instead of existsSync if (!(await pathExists(fullPath))) throw new GodotMCPError(`Scene not found: ${scenePath}`, 'SCENE_ERROR', 'Check the file path.') // Performance optimization: using async file reading instead of sync const content = await readFile(fullPath, 'utf-8') const tilemaps: string[] = [] const tmRegex = /\[node name="([^"]+)" type="TileMapLayer"/g for (const match of content.matchAll(tmRegex)) { tilemaps.push(match[1]) } return formatJSON({ scene: scenePath, tilemapLayers: tilemaps }) } default: throwUnknownAction(action, ['create_tileset', 'add_source', 'set_tile', 'paint', 'list']) } } - src/tools/registry.ts:323-344 (schema)Input schema definition for the 'tilemap' tool, defining actions (create_tileset, add_source, set_tile, paint, list), parameters (project_path, scene_path, tileset_path, texture_path, tile_size), and annotations.
{ name: 'tilemap', description: 'TileSet and TileMap management. Actions: create_tileset|add_source|set_tile|paint|list. Use help tool for full docs.', annotations: createAnnotations('TileMap'), inputSchema: { type: 'object' as const, properties: { action: { type: 'string', enum: ['create_tileset', 'add_source', 'set_tile', 'paint', 'list'], description: 'Action to perform', }, project_path: { type: 'string', description: 'Path to Godot project directory' }, scene_path: { type: 'string', description: 'Path to scene file (for list, paint)' }, tileset_path: { type: 'string', description: 'Path to TileSet .tres file (for create_tileset, add_source)' }, texture_path: { type: 'string', description: 'Texture source path (for add_source)' }, tile_size: { type: 'number', description: 'Tile size in pixels (default: 16, for create_tileset)' }, }, required: ['action'], }, }, - src/tools/registry.ts:28-28 (registration)Import of handleTilemap from './composite/tilemap.js' in the tool registry.
import { handleTilemap } from './composite/tilemap.js' - src/tools/registry.ts:500-500 (registration)Mapping of 'tilemap' tool name to its handler function handleTilemap in the TOOL_HANDLERS dispatch object.
tilemap: handleTilemap, - src/tools/composite/help.ts:23-23 (helper)Registration of 'tilemap' as a valid help topic, enabling users to get full documentation for the tilemap tool via the help tool.
'tilemap',